使用带有飞碟的自定义字体会导致 PDF 损坏

问题描述

我有一个用 Flying Saucer 生成的工作 PDF。然而,当我现在想要添加自定义字体时,生成的 PDF 会损坏。浏览器没有下载文件,而是显示了各种奇怪的符号。

自定义字体是通过在类路径上添加 ttf 字体文件调用 addFont添加的:

            renderer.getFontResolver().addFont("/fonts/Montserrat-Regular.ttf",BaseFont.IDENTITY_H,true);
            renderer.getFontResolver().addFont("/fonts/Montserrat-Italic.ttf",true);
            renderer.getFontResolver().addFont("/fonts/Montserrat-Bold.ttf",true);
            renderer.getFontResolver().addFont("/fonts/Montserrat-BoldItalic.ttf",true);

并在 CSS 中指定字体:

html {
  font-family: 'Montserrat',sans-serif;
  font-size: 14px;
}

解决方法

问题是由于在将 PDF 生成到响应的输出流中之后设置了响应标头。

我的控制器是这样的:

    @GetMapping("/{id}/download-pdf")
    @Secured(Roles.ADMIN)
    public void downloadPDFResource(@PathVariable("id") EntityId entityId,HttpServletRequest request,HttpServletResponse response,Locale locale) throws IOException {
        byte[] pdf = pdfService.generatePdf("details-pdf",context);
        response.getOutputStream().write(pdf);
        response.setContentType("application/pdf");
        response.addHeader("Content-Disposition","attachment; filename=" + "document.pdf");

        response.getOutputStream().flush();
    }

修复方法是将内容类型和标题的设置移动到方法的顶部:

    @GetMapping("/{id}/download-pdf")
    @Secured(Roles.ADMIN)
    public void downloadPDFResource(@PathVariable("id") EntityId entityId,Locale locale) throws IOException {
        response.setContentType("application/pdf");
        response.addHeader("Content-Disposition","attachment; filename=" + "document.pdf");

        byte[] pdf = pdfService.generatePdf("details-pdf",context);
        response.getOutputStream().write(pdf);

        response.getOutputStream().flush();
    }

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...