【问题标题】:How to export PDFBox (pdf file) by response?如何通过响应导出 PDFBox(pdf 文件)?
【发布时间】:2018-09-18 15:02:30
【问题描述】:

我需要通过控制器将 PDF 文件导出给用户。我的 REST 看起来像这样,但是它返回空文件。

@RequestMapping(value="/pdfReport", method=RequestMethod.PUT, produces = MediaType.APPLICATION_JSON_VALUE)
public void downloadPDFReport(HttpServletResponse response, @RequestBody PDFReport pdfReport) throws IOException{

    StringBuilder sB = storageManager.getPDF(pdfReport);
    System.out.println(sB.toString());

    PDDocument document = new PDDocument();
    PDPage page = new PDPage();
    document.addPage(page);
    PDPageContentStream contentStream = new PDPageContentStream(document, page);
    contentStream.setFont(PDType1Font.TIMES_ROMAN, 12);
    contentStream.beginText();
    contentStream.showText(sB.toString());
    contentStream.endText();
    contentStream.close();

    document.save("pdfBoxHelloWorld.pdf");

    PDStream pdfStream = new PDStream(document);
    InputStream inputStream = pdfStream.createInputStream();
    FileCopyUtils.copy(inputStream, response.getOutputStream());
}

我打印出 StringBuilder,所以我 100% 确定 StringBuilder 的内容是正确的。

【问题讨论】:

    标签: java pdf pdfbox


    【解决方案1】:

    你的代码

    PDStream pdfStream = new PDStream(document);
    InputStream inputStream = pdfStream.createInputStream();
    FileCopyUtils.copy(inputStream, response.getOutputStream());
    

    没有任何意义,根据 PDStream 构造函数的 JavaDocs

    /**
     * Creates a new empty PDStream object.
     * 
     * @param document The document that the stream will be part of.
     */
    public PDStream(PDDocument document)
    

    pdfStream 是一个新的空PDStream 对象,它是document 的一部分。 因此,它返回一点也不奇怪空文件。

    考虑简单地使用

    document.save(response.getOutputStream());
    

    改为。

    或者,如果在流式传输上下文中需要在实际流式传输内容之前设置内容长度属性,请执行以下操作:

    try (   ByteArrayOutputStream baos = new ByteArrayOutputStream()   )
    {
        [...]
        doc.save(baos);
        byte[] bytes = baos.toByteArray();
    
        [... set response content length property to bytes.length ...]
    
        response.getOutputStream().write(bytes);
    }
    

    【讨论】:

    • 我想专注于第一部分。它可以帮助我返回 .pdf,但它仍然是空的。我更改了我的 contentStream contentStream.showText("Hello world");
    • “它可以帮助我返回 .pdf,但它仍然是空的。” - 这是否意味着返回了一个非空(长度 > 0)文件但仅包含空白页?或者这是否意味着您仍然收到一个空文件(长度 == 0)?在前一种情况下,请保存检索到的文件并共享以供分析。在后一种情况下,请尝试在流式传输数据之前设置响应内容长度属性。
    • 是的,它包含空白页。看起来内容为空。在这里你可以找到返回给我的pdf文件ufile.io/3gdao
    • 文本在左下角,页面坐标系的原点。尝试在contentStream.beginText();contentStream.showText("Hello world"); 之间添加contentStream.newLineAtOffset(100, 600);
    • 噢,我的错。我期待页面顶部的内容。无论如何,当我更改contentStream.showText(sB.toString()); 时,我遇到了另一个问题U+000A ('controlLF') is not available in this font Times-Roman encoding: WinAnsiEncoding。我认为它是 '\n' 的原因,我现在不知道如何修复它。
    猜你喜欢
    • 1970-01-01
    • 2019-06-16
    • 1970-01-01
    • 2019-08-27
    • 2023-03-04
    • 2013-05-12
    • 1970-01-01
    • 2020-10-14
    • 2016-03-21
    相关资源
    最近更新 更多