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

问题描述

在这里看到了很多答案,我复制了一些示例并尝试将其应用,但是我不知道如何进行这项工作。我正在尝试使用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;
    }

}

https://keisan.casio.com/calculator