问题描述
我在这里看到了很多答案,我复制了一些示例并尝试将其应用,但是我不知道如何进行这项工作。我正在尝试使用PDFBox创建文件并发送带有响应的文件,以便用户下载。到目前为止,我已经可以下载文件了,但是它是空白的。我已经尝试过仅使用PDFBox从计算机中加载示例文件并下载它,但是它以相同的方式出现,为空白。我现在使用的代码是:
@GET
@Path("/dataPDF")
@Produces("application/pdf")
public Response retrievePDF(){
try {
ByteArrayOutputStream output = new ByteArrayOutputStream();
output = createPDF();
ResponseBuilder response = Response.ok(output.toByteArray(),"application/pdf");
response.header("Content-disposition","attachment; filename=file.pdf");
return response.build();
}
catch (Exception ex) {
ex.printstacktrace();
return Response.status(Response.Status.NOT_FOUND).build();
}
public ByteArrayOutputStream createPDF() throws IOException {
PDFont font = PDType1Font.HELVETICA;
PDPageContentStream contentStream;
ByteArrayOutputStream output =new ByteArrayOutputStream();
PDDocument document =new PDDocument();
PDPage page = new PDPage();
document.addPage(page);
contentStream = new PDPageContentStream(document,page);
contentStream.beginText();
contentStream.setFont(font,20);
contentStream.newLineatoffset(10,770);
contentStream.showtext("Amount: $1.00");
contentStream.endText();
contentStream.beginText();
contentStream.setFont(font,20);
contentStream.newLineatoffset(200,880);
contentStream.showtext("Sequence Number: 123456789");
contentStream.endText();
contentStream.close();
document.save(output);
document.close();
return output;
}
更新1:这样就可以创建文件了,现在我很难将其发送到Web,正在使用ReactJS。我尝试调整了用于下载csv文件的结构,这里是:
const handleExportPDF= fileName => {
FileController.retrievePDF().then((response) => {
const url = window.URL.createObjectURL(new Blob([response.data]));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download',fileName);
document.body.appendChild(link);
link.click();
});
};
static retrievePDF() {
const { method,url } = endpoints.retrievePDF();
return api[method](url,{
responseType: "application/pdf"
});
}
export const fileEndpoints = {
retrievePDF: () => ({
method: "get",url: `/export/dataPDF`
})
};
更新2:如果有人在这里跌跌撞撞,我可以通过以下答案来解决问题:PDF Blob - Pop up window not showing content。重点正在改变
responseType: "application/pdf"
至responseType: 'arraybuffer'
即使只是更改它就已经可以了,我也改变了
window.URL.createObjectURL(new Blob([response.data]));
至window.URL.createObjectURL(new Blob([response.data]),{type: 'application/pdf'});
解决方法
使用下面的测试代码,您可以验证生成PDF的源代码是否可以正常工作。
但是第二个Textelement的位置不在视口中。
看起来您的问题与Webframework有关。您可能会对此提供更多详细信息,以寻求更多建议。
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>2.0.19</version>
</dependency>
</dependencies>
App.java
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.apache.pdfbox.pdmodel.font.PDType1Font;
import java.io.*;
public class App {
public static void main(String[] args) throws IOException {
File resultFile = File.createTempFile("Test",".pdf");
ByteArrayOutputStream byteArrayOutputStream = createPDF();
try(OutputStream outputStream = new FileOutputStream(resultFile)) {
byteArrayOutputStream.writeTo(outputStream);
}
System.out.println("Please find your PDF File here: " + resultFile.getAbsolutePath());
}
public static ByteArrayOutputStream createPDF() throws IOException {
PDFont font = PDType1Font.HELVETICA;
PDPageContentStream contentStream;
ByteArrayOutputStream output =new ByteArrayOutputStream();
PDDocument document =new PDDocument();
PDPage page = new PDPage();
document.addPage(page);
contentStream = new PDPageContentStream(document,page);
contentStream.beginText();
contentStream.setFont(font,20);
contentStream.newLineAtOffset(10,770);
contentStream.showText("Amount: $1.00");
contentStream.endText();
contentStream.beginText();
contentStream.setFont(font,20);
// 200 is way too much right and 800 too much on top... so this want be visible on normal A4 Format
contentStream.newLineAtOffset(200,880);
contentStream.showText("Sequence Number: 123456789");
contentStream.endText();
contentStream.close();
document.save(output);
document.close();
return output;
}
}