【问题标题】:Download pdf directly to browser when generated with itext使用itext生成pdf时直接下载到浏览器
【发布时间】:2016-03-24 22:35:09
【问题描述】:

我正在使用 itext 从 html 字符串生成 pdf 文件。我在控制台中收到此错误:

Uncaught Error: Syntax error, unrecognized expression: %PDF-1.4

这是我控制器中的代码。

@RequestMapping(value = "/print",method = RequestMethod.POST)
public void  print(String html,HttpServletResponse response,HttpServletRequest request) throws IOException,DocumentException {
    try{
        Document document = new Document();
        // step 2
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        PdfWriter.getInstance(document, baos);
        // step 3
        document.open();
        document.add(new Paragraph(html));
        // step 5
        document.close();

        // setting some response headers
        response.setHeader("Expires", "0");
        response.setHeader("Cache-Control",
                "must-revalidate, post-check=0, pre-check=0");
        response.setHeader("Pragma", "public");
        // setting the content type
        response.setContentType("application/pdf");
        // the contentlength
        response.setContentLength(baos.size());
        // write ByteArrayOutputStream to the ServletOutputStream
        OutputStream os = response.getOutputStream();
        baos.writeTo(os);
        os.flush();
    }
    catch(DocumentException e) {
        throw new IOException(e.getMessage());
    } 

【问题讨论】:

  • %PDF-1.4 是 PDF 文件的标题。每个 PDF必须%PDF-1. 开头,后跟从 07 的数字。代码中的哪一行导致了未捕获的错误?乍一看,我看不出你的代码有什么问题,但我可能忽略了一些东西。错误消息应提供行号。请告诉我们哪一行与该行号对应。
  • 注意:如果html 是HTML,那么new Paragraph(html) 将显示HTML。换句话说:如果您有 <b>bold</b> and <i>italic</i>,那么 PDF 上的文本将是“bold 和 `italic”而不是“bold 和 斜体”。 (但这太明显了,你可能已经知道了。)
  • 错误不在服务器中,它出现在我浏览器的控制台中。我现在已经在临时目录中生成了文件,并且生成得很好。问题是当我读回它以在浏览器中下载它时。那是我收到错误消息的时候。
  • 您是否在不同的浏览器/不同的计算机上尝试过您的应用程序?也许您的浏览器未配置为显示 PDF。浏览器需要 HTML。如果它获取另一种格式的文件,它需要一个插件。例如。 Adobe Reader 插件。某些浏览器使用不同的 PDF 查看器。例如。 Firefox 使用 pdf、js,Chrome 使用 Chrome PDF 查看器,Safari 使用 Preview,...
  • 尝试添加response.setHeader("Content-Disposition", "attachment; filename=sample.pdf"); 如果这样做会怎样?

标签: java spring pdf-generation itext


【解决方案1】:

您需要做的是将 PDF 文件的字节直接流式传输到输出流并刷新响应。在 Spring 中,您可以这样做:

@RequestMapping(value="/displayProcessFile/{processInstanceId}", method=RequestMethod.GET)
public ResponseEntity<byte[]> displayProcessFile(@PathVariable String processInstanceId) throws UnauthorizedUserAccessException{
    Document processFile=null;
    try {
        processFile = documentService.retrieveProcessFile(Long.parseLong(processInstanceId));
    } catch (ProcessFileNotFoundExpection e) {
        e.printStackTrace();
    }
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.parseMediaType("application/pdf"));
    headers.add("content-disposition", "attachment;filename=" + processFile.getDocName());
    ResponseEntity<byte[]> response = new ResponseEntity<byte[]>(processFile.getContent(), headers, HttpStatus.OK);
    return response;
}

【讨论】:

  • 由于 PDF 的二进制特性,在某些浏览器中直接将 PDF 字节流式传输到浏览器会失败。某些浏览器需要 PDF 的确切文件大小。为了实现这一点,许多开发人员首先在内存中创建 PDF(使用ByteArrayOutputStream),然后在 HTTP 标头中传递 PDF 的长度:response.setContentLength(baos.size());。我认为您的回答没有解决问题。尽管将 content-disposition 设置为 attachment (而不是您的答案中所做的 inline),但可能会奏效。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-05-14
  • 1970-01-01
  • 2018-12-11
  • 1970-01-01
  • 2014-08-03
  • 2021-07-13
  • 1970-01-01
相关资源
最近更新 更多