上一篇
Java如何把HTML转成PDF?
- 前端开发
- 2025-06-02
- 2104
Java可通过第三方库如iText、Flying Saucer或OpenPDF实现HTML转PDF,先将HTML内容解析为DOM树,再结合CSS样式渲染布局,最终生成PDF文件,常用工具包包括iText的XML Worker或基于wkhtmltopdf的封装库。
在Java中将HTML转换为PDF是常见的开发需求,尤其适用于生成报表、电子合同、数据存档等场景,以下是几种主流实现方案,结合代码示例和关键注意事项:
主流技术方案及实现步骤
iText + Flying Saucer (XML Worker)
原理:解析HTML/CSS并渲染为PDF
优点:开源免费、支持CSS 2.1
局限:对CSS 3和复杂布局支持有限
Maven依赖:
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.13.3</version>
</dependency>
<dependency>
<groupId>org.xhtmlrenderer</groupId>
<artifactId>flying-saucer-pdf</artifactId>
<version>9.1.22</version>
</dependency>
示例代码:

import com.itextpdf.text.Document;
import com.itextpdf.text.pdf.PdfWriter;
import org.xhtmlrenderer.pdf.ITextRenderer;
public class HtmlToPdf {
public static void convert(String htmlPath, String pdfPath) throws Exception {
Document document = new Document();
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(pdfPath));
document.open();
ITextRenderer renderer = new ITextRenderer();
renderer.setDocument(new File(htmlPath));
renderer.layout();
renderer.createPDF(writer.getOs());
document.close();
}
}
Apache PDFBox + PDFBox-PDL
原理:直接操作PDF文档结构
适用场景:需要精细控制PDF元素的场景
Maven依赖:
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>3.0.0</version>
</dependency>
基础转换流程:

PDDocument document = new PDDocument();
PDPage page = new PDPage();
document.addPage(page);
try (PDPageContentStream contentStream = new PDPageContentStream(document, page)) {
// 手动添加文本/图像(需自行解析HTML)
contentStream.beginText();
contentStream.setFont(PDType1Font.HELVETICA_BOLD, 12);
contentStream.newLineAtOffset(100, 700);
contentStream.showText("Hello PDFBox!");
contentStream.endText();
}
document.save("output.pdf");
document.close();
OpenHTML to PDF (开源方案)
优势:支持CSS 3和现代布局
Maven依赖:
<dependency>
<groupId>com.openhtmltopdf</groupId>
<artifactId>openhtmltopdf-pdfbox</artifactId>
<version>1.0.10</version>
</dependency>
示例代码:

import com.openhtmltopdf.pdfboxout.PdfRendererBuilder;
public void convertHtmlToPdf(String htmlFile, String pdfFile) throws Exception {
try (OutputStream os = new FileOutputStream(pdfFile)) {
PdfRendererBuilder builder = new PdfRendererBuilder();
builder.useFastMode();
builder.withFile(new File(htmlFile));
builder.toStream(os);
builder.run();
}
}
商业库Aspose.HTML
优势:高保真转换、企业级支持
代码示例:
import com.aspose.html.HTMLDocument;
import com.aspose.html.saving.PdfSaveOptions;
public class AsposeConverter {
public static void convert(String inputPath, String outputPath) {
HTMLDocument document = new HTMLDocument(inputPath);
PdfSaveOptions options = new PdfSaveOptions();
document.save(outputPath, options);
}
}
关键问题与解决方案
| 问题类型 | 解决方案 |
|---|---|
| 中文乱码 | 使用嵌入中文字体:renderer.getFontResolver().addFont("font.ttf", true); |
| CSS样式丢失 | 避免使用CSS 3特性,或用OpenHTML替代 |
| 图片不显示 | 检查图片路径是否为绝对路径,或使用Base64编码 |
| 分页控制 | 在HTML中添加CSS打印样式:@media print { .page-break { page-break-after: always; } } |
| 性能优化 | 启用缓存:builder.useCache(true); |
方案选型建议
- 开源项目 → OpenHTML to PDF(平衡性能与兼容性)
- 企业级需求 → Aspose.HTML(付费但省心)
- 简单文本转换 → iText/Flying Saucer
- 自定义PDF结构 → PDFBox直接操作API
最佳实践注意事项
- 字体嵌入:始终嵌入字体避免客户端显示异常
- 资源路径:将图片/CSS转为绝对路径或内联资源
- 内存管理:使用
try-with-resources确保流关闭 - 错误处理:捕获
IOException和DocumentException
// 健壮性处理示例
try (PDDocument doc = new PDDocument()) {
// 操作逻辑
} catch (IOException e) {
logger.error("PDF生成失败", e);
throw new ConversionException("文件创建异常");
}
引用说明
- iText官方文档:https://itextpdf.com/en
- PDFBox指南:https://pdfbox.apache.org
- OpenHTML项目:https://github.com/danfickle/openhtmltopdf
- Aspose.HTML API:https://products.aspose.com/html/java
版权声明:本文中代码示例基于MIT许可证的开源库编写,商业使用请遵循对应库的许可协议。
