将Java与HTML结合生成PDF文件是现代开发中常见的需求,尤其在报告生成、电子文档转换等场景中应用广泛,本文将详细介绍通过Java实现HTML转PDF的多种方法,涵盖主流技术选型、核心代码实现及注意事项,帮助开发者高效完成转换任务。

技术选型:主流HTML转PDF方案对比
在Java生态中,实现HTML转PDF主要有以下几种技术路径,各有优劣:
Flying Saucer(xhtmlrenderer)
基于Java的XML渲染引擎,支持CSS 2.1及部分CSS 3样式,适合需要严格样式还原的场景,其核心原理是将HTML解析为Java的Document对象,再通过渲染引擎绘制为PDF,优点是开源免费、样式兼容性好;缺点是对复杂CSS(如Flexbox、Grid)支持有限,且依赖Java AWT环境。
iText
老牌PDF处理库,提供了HTML到PDF的直接转换功能(iText 7+),通过集成XML Worker或自定义HTML解析器,支持HTML/CSS渲染,优点是功能强大,可灵活操作PDF元素;缺点是商业版本需付费,开源版本功能受限。
Apache FOP
专注于XSL-FO(格式化对象)的转换工具,可通过将HTML转换为XSL-FO再生成PDF,优点是对打印样式支持完善;缺点是流程较复杂,需要额外处理HTML到XSL-FO的转换逻辑。
无头浏览器方案(如Selenium+Headless Chrome)
通过程序控制无头浏览器加载HTML页面,再截取或打印为PDF,优点是能完美还原现代Web页面样式(包括JavaScript渲染效果);缺点是性能较低,需安装浏览器依赖,适合需要高保真还原的场景。
开发者可根据需求选择:若追求样式兼容性和开源,推荐Flying Saucer;若需复杂PDF操作,可考虑iText;若要求高保真渲染,无头浏览器更合适。

核心实现:以Flying Saucer为例详解
Flying Saucer是开源HTML转PDF的热门选择,以下为具体实现步骤:
环境准备
添加Maven依赖(Flying Saucer核心依赖):
<dependency>
<groupId>org.xhtmlrenderer</groupId>
<artifactId>flying-saucer-pdf-itext5</artifactId>
<version>9.1.22</version>
</dependency>
基础转换代码
import org.xhtmlrenderer.pdf.ITextRenderer;
import java.io.FileOutputStream;
import java.io.OutputStream;
public class HtmlToPdf {
public static void main(String[] args) {
String htmlContent = "<html><body><h1>Hello PDF</h1><p>Generated by Flying Saucer</p></body></html>";
String outputPath = "output.pdf";
try (OutputStream os = new FileOutputStream(outputPath)) {
ITextRenderer renderer = new ITextRenderer();
renderer.setDocumentFromString(htmlContent);
renderer.layout();
renderer.createPDF(os);
System.out.println("PDF生成成功:" + outputPath);
} catch (Exception e) {
e.printStackTrace();
}
}
}
处理外部资源(CSS/图片)
Flying Saucer默认无法直接加载外部资源,需手动配置:
- CSS文件:通过
renderer.getSharedContext().setBaseURL()设置基础路径,确保CSS中的url()路径正确。 - 图片:使用
renderer.getSharedContext().getReplacedElementFactory()自定义图片加载逻辑,或使用data:内嵌图片。
示例代码(加载外部CSS):
renderer.setDocumentFromString(htmlContent);
renderer.getSharedContext().setBaseURL("file:/path/to/your/resources/");
renderer.layout();
中文支持
需添加中文字体配置,避免PDF中出现乱码:
ITextRenderer renderer = new ITextRenderer();
// 注册中文字体(如SimSun)
renderer.getFontResolver().addFont("path/to/SimSun.ttf", "UniGB-UCS2-H", true);
进阶技巧:优化PDF输出效果
页面设置
通过CSS控制PDF页面样式,

@page {
size: A4;
margin: 2cm;
}
body {
font-family: "SimSun", serif;
font-size: 12pt;
}
分页处理
Flying Saucer支持通过CSS属性控制分页:
.page-break {
page-break-before: always;
}
水印与页眉页脚
可通过在HTML中添加固定定位元素实现,或使用iText的HeaderFooter功能(需结合iText API)。
无头浏览器方案:Selenium+Headless Chrome
若需渲染JavaScript动态内容,可采用无头浏览器方案:
环境准备
- 安装Chrome浏览器及ChromeDriver
- 添加Selenium依赖:
<dependency> <groupId>org.seleniumhq.selenium</groupId> <artifactId>selenium-java</artifactId> <version>4.1.0</version> </dependency>
核心代码
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import java.io.File;
import java.io.IOException;
public class HtmlToPdfWithSelenium {
public static void main(String[] args) {
System.setProperty("webdriver.chrome.driver", "path/to/chromedriver");
ChromeOptions options = new ChromeOptions();
options.addArguments("--headless");
options.addArguments("--disable-gpu");
options.addArguments("--print-to-pdf=/path/to/output.pdf");
WebDriver driver = new ChromeDriver(options);
driver.get("file:///path/to/your.html");
try {
Thread.sleep(5000); // 等待页面加载完成
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
driver.quit();
}
}
}
注意事项
- 需确保ChromeDriver版本与Chrome浏览器版本匹配
- 复杂页面可能需调整等待时间,避免PDF生成不完整
常见问题与解决方案
样式错乱
- 检查CSS兼容性,避免使用Flying Saucer不支持的属性(如
position: fixed) - 确保外部资源路径正确,可通过浏览器开发者工具验证网络请求
中文乱码
- 确保HTML声明为UTF-8编码:
<meta charset="UTF-8"> - 注册本地中文字体,并设置CSS的
font-family为对应字体名
内存溢出
- 处理大HTML文件时,可启用Flying Saucer的
buffer模式:renderer.getSharedContext().setBufferModel(true);
- 或分块处理HTML内容,避免一次性加载过大数据
Java实现HTML转PDF可根据需求选择不同方案:Flying Saucer适合开源、样式要求一般的场景;iText适合复杂PDF操作;无头浏览器则能完美还原动态页面,开发者需结合项目需求权衡性能、兼容性与开发成本,同时注意资源路径、字体支持等细节问题,才能高效生成符合预期的PDF文档。


















