核心原理
Java 本身并不能直接理解 HTML 并将其渲染成 PDF,我们需要借助第三方库,这些库的核心思想通常是:

- 嵌入一个浏览器内核:最强大的方法,它们会集成一个真正的浏览器内核(如 Google Chrome 的 Blink 或 Firefox 的 Gecko),它们通过启动一个无头(Headless)浏览器实例,加载你的 HTML 文件,然后像浏览器一样渲染出页面,最后将渲染好的页面截图或直接打印成 PDF。
- 使用 HTML/CSS 渲染引擎:这种方法不依赖外部浏览器,而是自己实现一个 HTML/CSS 解析和渲染引擎,它们速度更快,资源消耗更少,但可能在处理现代 CSS(如 Flexbox, Grid、某些动画和字体)方面存在兼容性问题。
使用 Flying Saucer (xhtmlrenderer) - 纯 Java 解决方案
Flying Saucer 是一个开源的、纯 Java 实现的 XHTML/CSS 渲染器,它非常适合将静态的、样式简单的 HTML 转换为 PDF。
优点
- 纯 Java:无需安装任何外部依赖(如浏览器),部署简单。
- 轻量级:启动速度快,资源占用少。
- 开源免费:基于 Apache 2.0 许可证。
缺点
- CSS 支持有限:对现代 CSS3 的支持不完整,特别是复杂的布局(Flexbox, Grid)、部分 CSS3 选择器和伪类可能无法正确渲染。
- JavaScript 支持:不支持 JavaScript。
- 性能:对于非常复杂的 HTML 文档,性能可能不如基于浏览器的方案。
实现步骤
-
添加依赖 (Maven)
<dependency> <groupId>org.xhtmlrenderer</groupId> <artifactId>flying-saucer-pdf</artifactId> <version>9.1.22</version> <!-- 请使用最新版本 --> </dependency> -
Java 代码示例
import org.xhtmlrenderer.pdf.ITextRenderer; import java.io.File; import java.io.FileOutputStream; import java.io.OutputStream; public class FlyingSaucerExample { public static void main(String[] args) { // 1. 准备 HTML 内容 // 注意:Flying Saucer 期望的是 XHTML 格式,所以标签最好闭合 String htmlContent = "<h1>Hello, Flying Saucer!</h1>" + "<p>This is a PDF generated from HTML using Flying Saucer.</p>" + "<table border='1'>" + "<tr><th>Name</th><th>Age</th></tr>" + "<tr><td>John Doe</td><td>30</td></tr>" + "</table>"; // 2. 创建 ITextRenderer 实例 ITextRenderer renderer = new ITextRenderer(); // 3. 设置 HTML 内容 renderer.setDocumentFromString(htmlContent); // 4. (可选)设置基础 URL,用于解析相对路径的 CSS 和图片 renderer.getSharedContext().setBaseURL("file:/C:/path/to/your/resources/"); // 5. 渲染 PDF try (OutputStream os = new FileOutputStream("output_flying_saucer.pdf")) { renderer.layout(); renderer.createPDF(os); System.out.println("PDF generated successfully!"); } catch (Exception e) { e.printStackTrace(); } } }
使用 iText - 功能强大的商业/开源方案
iText 是一个非常著名的 PDF 操作库,它有一个名为 iText HTMLWorker 的组件可以解析 HTML,但官方已不推荐使用,因为它对 CSS 的支持非常糟糕。

取而代之的是 iText 7 的 html2pdf 模块,它基于 Flying Saucer,所以优缺点和 Flying Saucer 类似,但提供了更现代化的 API 和商业支持。
优点
- 功能强大:除了 HTML 转 PDF,iText 本身在 PDF 创建、修改、加密等方面是业界标杆。
- 商业支持:提供商业版本,可获得官方技术支持。
缺点
- 开源版限制:iText 7 的 AGPL 开源许可证有商业限制,如果你的项目是商业闭源的,需要购买商业许可证。
- CSS 支持同样有限:和 Flying Saucer 一样,对现代 CSS 的支持不是其强项。
实现步骤 (基于 iText 7)
-
添加依赖 (Maven)
<dependency> <groupId>com.itextpdf</groupId> <artifactId>html2pdf</artifactId> <version>5.0.5</version> <!-- 请使用最新版本 --> </dependency> -
Java 代码示例
import com.itextpdf.html2pdf.HtmlConverter; import java.io.File; import java.io.FileOutputStream; import java.io.OutputStream; public class ITextHtml2PdfExample { public static void main(String[] args) { String htmlContent = "<h1>Hello, iText 7 html2pdf!</h1>" + "<p>This PDF was created with the iText 7 html2pdf add-on.</p>"; try (OutputStream os = new FileOutputStream("output_itext_html2pdf.pdf")) { // 直接调用 HtmlConverter 的静态方法进行转换 HtmlConverter.convertToPdf(htmlContent, os); System.out.println("PDF generated successfully with iText 7!"); } catch (Exception e) { e.printStackTrace(); } } }注意:这个例子和 Flying Saucer 的核心代码非常相似,因为
html2pdf模块内部就封装了 Flying Saucer。
(图片来源网络,侵删)
使用 Selenium / Playwright - 功能最强大的方案
这种方法通过驱动一个真实的无头浏览器来渲染页面,因此能完美支持现代 HTML5、CSS3 和 JavaScript。
优点
- 完美的兼容性:可以渲染任何现代网页,包括复杂的 CSS 布局、JavaScript 动态内容、SVG、Canvas 等。
- 真实环境:模拟真实用户操作,适合生成需要交互或复杂 JS 计算后的页面截图/PDF。
缺点
- 依赖外部环境:需要预先安装 Chrome、Firefox 或 Edge 浏览器。
- 资源消耗大:启动浏览器进程需要较多内存和 CPU。
- 速度慢:相比纯 Java 方案,启动和渲染过程要慢得多。
实现步骤 (以 Selenium + Chrome 为例)
-
安装 Chrome 浏览器 确保你的服务器或开发环境上已经安装了 Google Chrome。
-
添加依赖 (Maven)
<!-- Selenium WebDriver for Chrome --> <dependency> <groupId>org.seleniumhq.selenium</groupId> <artifactId>selenium-chrome-driver</artifactId> <version>4.10.0</version> <!-- 请使用与你的 Chrome 版本匹配的版本 --> </dependency> <!-- 一个更轻量的库,也可以选择 --> <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>31.1-jre</version> </dependency> -
Java 代码示例
import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.chrome.ChromeOptions; import org.openqa.selenium.OutputType; import org.openqa.selenium.Pdf; // 需要较新版本的 Selenium import java.io.File; import java.io.IOException; import org.apache.commons.io.FileUtils; public class SeleniumPdfExample { public static void main(String[] args) { // 1. 设置 ChromeDriver 路径 // 如果你把 chromedriver.exe 放在系统 PATH 中,可以省略这步 // System.setProperty("webdriver.chrome.driver", "path/to/your/chromedriver.exe"); // 2. 配置 Chrome 选项为无头模式 ChromeOptions options = new ChromeOptions(); options.addArguments("--headless"); options.addArguments("--no-sandbox"); options.addArguments("--disable-dev-shm-usage"); // 指定打印的背景颜色 options.addArguments("--print-to-pdf-no-header"); options.addArguments("--hide-scrollbars"); // 3. 创建 WebDriver 实例 WebDriver driver = null; try { driver = new ChromeDriver(options); // 4. 加载 HTML 文件 // 你可以是一个本地文件,也可以是一个 URL // File htmlFile = new File("path/to/your/report.html"); // driver.get("file:///" + htmlFile.getAbsolutePath()); driver.get("https://www.google.com"); // 5. 使用 Chrome 的打印 API 生成 PDF // 这是 Selenium 4+ 的新特性,比截图更精确 Pdf pdf = driver.print(OutputType.FILE); File pdfFile = pdf.getAsFile(); FileUtils.copyFile(pdfFile, new File("output_selenium.pdf")); System.out.println("PDF generated successfully with Selenium!"); } catch (Exception e) { e.printStackTrace(); } finally { // 6. 关闭浏览器 if (driver != null) { driver.quit(); } } } }注意:Selenium 4 开始原生支持
print到 PDF,这是最佳方式,如果使用旧版本,你需要通过driver.getScreenshotAs()截图,但这无法生成完整的页面长 PDF,只能截取视口部分。
使用商业 API 服务 (如 PrinceXML, SelectPDF)
对于有高要求、高预算的企业,可以考虑商业 API 服务。
PrinceXML
- 优点:业界公认的对 CSS 支持最好的渲染引擎,能将几乎所有符合标准的 XHTML 和 CSS 转换成精美的 PDF,质量极高。
- 缺点:价格昂贵,是商业产品。
SelectPDF
- 优点:提供 .NET 和 Java 库,对 CSS3 和 HTML5 有很好的支持,性价比比 PrinceXML 高。
- 缺点:需要付费购买许可证,有免费版本但有页面数限制。
总结与选择建议
| 方法 | 核心原理 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|---|
| Flying Saucer / iText html2pdf | 纯 Java 渲染引擎 | 轻量、快速、无外部依赖 | CSS 支持有限,无 JS 支持 | 简单的、静态的报告、发票、标签等 |
| Selenium / Playwright | 驱动无头浏览器 | 完美支持现代 CSS/JS,功能最全 | 依赖浏览器、资源消耗大、速度慢 | 复杂的网页、需要执行 JS 的页面、高保真网页截图/PDF |
| 商业 API (PrinceXML, SelectPDF) | 专业商业引擎 | CSS 支持顶尖,质量高 | 价格昂贵 | 对 PDF 质量、样式保真度有极高要求的企业级应用 |
如何选择?
- 如果只是简单的 HTML 转 PDF,样式不复杂:首选 Flying Saucer 或 iText 7 html2pdf,它们简单、快速、免费,足以满足大多数内部报表的需求。
- 如果需要生成高保真的网页,包含复杂布局、字体、甚至 JavaScript 动态内容:必须选择 Selenium 或 Playwright,虽然慢一些,但效果是最好的。
- 如果项目预算充足,且 PDF 的视觉质量是第一要求:可以考虑 PrinceXML 等商业解决方案。
对于大多数 Java Flying Saucer 和 Selenium 是最常用和最需要了解的两种方案。
