使用 PDFBox 创建文件并下载 [已解决]

Creating file with PDFBox and downloading it [SOLVED]

我在这里看到了很多答案,我复制了一些示例并尝试应用它,但我不知道如何使它起作用。我正在尝试使用 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: .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:所以正在创建文件,现在我只是无法将其发送到网络,我正在使用 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 的定位在 Viewport 之外。

看来您的问题与 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: .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;
    }

}