最近遇到在 Java 项目中生成 PDF 文件的需求,使用 iText7 通过 html 模板生成的 PDF 文件,中文都消失了,只剩下英文。
先说结论
iText7 本身就支持中文字体显示,不需要自己添加字体文件。
相关依赖:
1 | implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' |
生成 PDF:
1 | private void convertHtmlToPdf(String htmlContent) { |
推荐资料
一些很有用的资料:
主流工具
可以选择的方案很多,都支持 HTML 转 PDF,但实现原理、渲染效果和支持的 HTML/CSS 标准有很大的区别,有的像是“浏览器”能完美还原网页,有的像是“文档生成器”,只支持基础排版。
iText
iText 是行业标准的 PDF 库,功能极其强大,生态好,分为 iText 5(旧版稳定)和 iText 7(新版重构)。支持极其复杂的 PDF 操作,包括表单处理(AcroForm/XFA)、数字签名、PDF/A 归档标准、加密解密、HTML 转 PDF(html2pdf)等。在处理大型文件或高并发场景下,性能表现较好。
不过 开源协议限制,需要慎重使用。
iText 本身是一个底层 PDF 库,它通过官方的 pdfHTML 插件(itext7-pdfhtml)来实现 HTML 转换。不支持 JavaScript,无法渲染动态生成的内容,只能处理静态 HTML。支持 CSS 2.1 的大部分特性,但对 Flexbox、Grid 等现代布局支持不如浏览器内核完善。
OpenPDF
OpenPDF 本身不直接支持 HTML 转换,通常需要配合 Flying Saucer 或 openhtmltopdf 使用。
原理:Flying Saucer 负责解析 HTML/CSS,然后调用 OpenPDF 的 API 绘制内容。
特点:
- 基础支持:主要支持 XHTML 和 CSS 2.1 标准。
- 轻量级:适合生成简单的列表、表格类报表。
- 局限性:同样不支持 JavaScript 和复杂的 HTML5 布局。
wkhtmltopdf
一个命令行工具(不是纯 Java 库,Java 需调用进程),基于 WebKit 内核(Qt)。
特点:
- 还原度极高:支持 HTML5、CSS3、@media print,甚至支持 SVG 和 Web 字体。
- 有限支持 JS:相比纯 Java 库,它对 JS 的支持更好,但有时仍需等待页面加载完成。
- 部署麻烦:需要在服务器上安装二进制文件,且处理中文字体时需要手动挂载字体文件,否则乱码。
Flying Saucer
一个 HTML/CSS 渲染引擎,通常作为“桥梁”连接 HTML 和 PDF 库(如 iText 或 OpenPDF)。
特点:
- 稳定:非常成熟,但标准较老(主要支持 CSS 2.1)。
- 不支持 JS:完全不支持 JavaScript,无法处理动态 DOM。
适合对样式要求不复杂、纯静态内容的报表生成。
x-easypdf
一个 Java 封装库,它内部集成了 Playwright 来实现 HTML 转 PDF。Playwright 是由微软开发的自动化工具,它会启动一个真实的浏览器(Chromium)来渲染页面,然后截图或打印为 PDF。
特点:
- 最现代:因为基于真实浏览器,所以支持所有的现代 CSS(Grid/Flex)、JavaScript 动画、ECharts 图表等。
- 所见即所得:网页长什么样,PDF 就是什么样。
- 资源占用:因为要启动浏览器内核,内存和 CPU 占用较高,速度相对较慢。