将自定义字体与飞碟一起使用会导致 PDF 损坏
Using custom font with flying saucer gives corrupt 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", BaseFont.IDENTITY_H, true);
renderer.getFontResolver().addFont("/fonts/Montserrat-Bold.ttf", BaseFont.IDENTITY_H, true);
renderer.getFontResolver().addFont("/fonts/Montserrat-BoldItalic.ttf", BaseFont.IDENTITY_H, true);
并在CSS中指定字体:
html {
font-family: 'Montserrat', sans-serif;
font-size: 14px;
}
问题是由于在将 PDF 生成到响应的输出流后设置了响应 header。
我的控制器是这样的:
@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();
}
解决方法是将内容类型的设置和 header 移动到方法的顶部:
@GetMapping("/{id}/download-pdf")
@Secured(Roles.ADMIN)
public void downloadPDFResource(@PathVariable("id") EntityId entityId,
HttpServletRequest request, HttpServletResponse response,
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();
}
我有一个使用 Flying Saucer 生成的工作 PDF。但是,当我现在想要添加自定义字体时,生成的 PDF 会损坏。浏览器没有下载文件,而是显示各种奇怪的符号。
通过在类路径中添加 ttf 字体文件并调用 addFont
:
renderer.getFontResolver().addFont("/fonts/Montserrat-Regular.ttf", BaseFont.IDENTITY_H, true);
renderer.getFontResolver().addFont("/fonts/Montserrat-Italic.ttf", BaseFont.IDENTITY_H, true);
renderer.getFontResolver().addFont("/fonts/Montserrat-Bold.ttf", BaseFont.IDENTITY_H, true);
renderer.getFontResolver().addFont("/fonts/Montserrat-BoldItalic.ttf", BaseFont.IDENTITY_H, true);
并在CSS中指定字体:
html {
font-family: 'Montserrat', sans-serif;
font-size: 14px;
}
问题是由于在将 PDF 生成到响应的输出流后设置了响应 header。
我的控制器是这样的:
@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();
}
解决方法是将内容类型的设置和 header 移动到方法的顶部:
@GetMapping("/{id}/download-pdf")
@Secured(Roles.ADMIN)
public void downloadPDFResource(@PathVariable("id") EntityId entityId,
HttpServletRequest request, HttpServletResponse response,
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();
}