核心思路
无论使用哪种库,其基本原理都是相似的:

- 解析 HTML: 读取 HTML 字符串或文件,并将其解析成一个内存中的文档对象模型。
- 映射样式: 将 HTML 的标签(如
<p>,<h1>,<table>)和 CSS 样式(如font-size,color,text-align)映射到 Word 的对象模型(如段落、标题、表格、字体、颜色等)。 - 生成 Word: 遍历这个内存中的文档对象模型,使用 Java 的 Word 操作库来创建并填充一个
.docx文件。
使用 Apache POI + Flying Saucer (推荐)
这是目前功能最强大、效果最接近原生 Word 的方案,它结合了两个优秀的库:
- Apache POI: 用于创建和操作 Office 格式文件(如 .docx)的 Java API。
- Flying Saucer (xhtmlrenderer): 一个将 XHTML/CSS 渲染成图像或文档的库,它负责将 HTML 转换成 POI 可以理解的格式。
优点:
- 保真度高:能很好地支持 CSS 样式(如背景色、边距、字体等),生成的 Word 文档视觉效果好。
- 功能强大:支持复杂的 HTML 结构,如表格、列表、图片(需额外处理)等。
- 社区活跃:两个都是非常成熟和流行的项目,文档和解决方案丰富。
缺点:
- 依赖较多:需要引入多个库,项目体积会变大。
- 配置稍复杂:需要将两个库整合起来使用。
实现步骤
-
添加 Maven 依赖
(图片来源网络,侵删)<!-- Apache POI for .docx generation --> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>5.2.3</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>ooxml-schemas</artifactId> <version>1.4</version> </dependency> <!-- Flying Saucer for XHTML/CSS rendering --> <dependency> <groupId>org.xhtmlrenderer</groupId> <artifactId>flying-saucer-pdf</artifactId> <version>9.1.22</version> </dependency> <dependency> <groupId>org.xhtmlrenderer</groupId> <artifactId>flying-saucer-pdf-itext5</artifactId> <version>9.1.22</version> </dependency> <!-- 添加这个依赖以支持更完整的CSS --> <dependency> <groupId>org.xhtmlrenderer</groupId> <artifactId>flying-saucer-css</artifactId> <version>9.1.22</version> </dependency> -
编写 Java 代码
我们需要一个中间步骤:先将 HTML 转换成 XHTML(因为 Flying Saucer 对 XHTML 的支持更好),然后将其渲染成一个字节数组流,POI 读取这个流来创建 Word 文档。
import org.apache.poi.xwpf.usermodel.*; org.apache.poi.openxml4j.exceptions.InvalidFormatException; org.apache.poi.util.Units; org.xhtmlrenderer.swing.Java2DRenderer; org.xhtmlrenderer.util.FSImageWriter; import java.io.*; import java.nio.file.Files; import java.nio.file.Paths; public class HtmlToWordConverter { public static void convertHtmlToWord(String htmlContent, String outputPath) throws IOException, InvalidFormatException { // 1. 准备 XHTML 内容 (Flying Saucer 对 XHTML 更友好) String xhtmlContent = convertToXhtml(htmlContent); // 2. 使用 Flying Saucer 将 XHTML 渲染成图片 byte[] imageBytes = renderXhtmlToImage(xhtmlContent); // 3. 使用 Apache POI 创建 Word 文档并插入图片 try (XWPFDocument document = new XWPFDocument()) { XWPFParagraph paragraph = document.createParagraph(); XWPFRun run = paragraph.createRun(); // 将字节数组输入流添加到 Word 中 run.addPicture(new ByteArrayInputStream(imageBytes), XWPFDocument.PICTURE_TYPE_PNG, "rendered_content.png", Units.toEMU(600), Units.toEMU(800)); // 保存 Word 文档 try (FileOutputStream out = new FileOutputStream(outputPath)) { document.write(out); } System.out.println("Word 文档生成成功: " + outputPath); } } private static String convertToXhtml(String htmlContent) { // 一个简单的转换,实际项目中可能需要更复杂的处理,如使用 Jsoup 清理 HTML // 确保 HTML 有正确的 DOCTYPE 和 <html>, <head>, <body> 标签 if (!htmlContent.contains("<!DOCTYPE")) { htmlContent = "<!DOCTYPE html>\n" + "<html>\n" + "<head>\n" + " <meta charset=\"UTF-8\">\n" + " <style>\n" + " body { font-family: 'Microsoft YaHei', sans-serif; }\n" + " table { border-collapse: collapse; width: 100%; }\n" + " th, td { border: 1px solid #dddddd; text-align: left; padding: 8px; }\n" + " </style>\n" + "</head>\n" + "<body>\n" + htmlContent + "\n</body>\n</html>"; } return htmlContent; } private static byte[] renderXhtmlToImage(String xhtmlContent) throws IOException { // 创建一个临时文件来存储 XHTML File xhtmlFile = File.createTempFile("content", ".xhtml"); Files.write(xhtmlFile.toPath(), xhtmlContent.getBytes()); // 使用 Flying Saucer 渲染 Java2DRenderer renderer = new Java2DRenderer(xhtmlFile, 800); // 800 是渲染宽度 renderer.setDocument(xhtmlFile); // 渲染成 BufferedImage java.awt.image.BufferedImage image = (java.awt.image.BufferedImage) renderer.getImage(); // 将 BufferedImage 写入字节数组 ByteArrayOutputStream baos = new ByteArrayOutputStream(); FSImageWriter imageWriter = new FSImageWriter(); imageWriter.write(image, "png", baos); // 删除临时文件 Files.deleteIfExists(xhtmlFile.toPath()); return baos.toByteArray(); } public static void main(String[] args) { String html = "<h1 style='color: blue;'>这是一个标题</h1>" + "<p>这是一个段落,<strong>包含粗体文本</strong>和<em>斜体文本</em>。</p>" + "<table><tr><th>姓名</th><th>年龄</th></tr><tr><td>张三</td><td>30</td></tr></table>"; try { convertHtmlToWord(html, "D:/temp/output_from_flying_saucer.docx"); } catch (Exception e) { e.printStackTrace(); } } }
重要提示:此方案将整个 HTML 内容渲染成一张图片插入到 Word 中,这意味着 Word 中的内容是不可编辑的,如果需要生成可编辑的文本内容,则需要更复杂的解析和映射逻辑,或者考虑其他方案。
使用 iText 7 (功能强大,但商业版收费)
iText 7 是一个功能非常强大的文档操作库,它也支持 HTML 到 PDF 的转换,并且可以间接生成 Word。

优点:
- 专业级:处理文档的能力非常强。
- 支持 HTML 到 PDF:其
html2pdf模块可以直接转换 HTML 到 PDF,效果很好。
缺点:
- AGPL 许可证:如果你的项目是私有的,并且不遵循 AGPL 协议(即不公开你的源代码),则需要购买商业许可证,对于许多商业项目来说,这是一个重要考量。
实现步骤 (HTML to PDF)
-
添加 Maven 依赖
<dependency> <groupId>com.itextpdf</groupId> <artifactId>html2pdf</artifactId> <version>5.0.2</version> </dependency> <!-- 其他必要的 iText 7 依赖 --> <dependency> <groupId>com.itextpdf</groupId> <artifactId>kernel</artifactId> <version>8.0.2</version> </dependency> <dependency> <groupId>com.itextpdf</groupId> <artifactId>io</artifactId> <version>8.0.2</version> </dependency> -
编写 Java 代码
import com.itextpdf.html2pdf.HtmlConverter; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; public class HtmlToPdfWithIText { public static void main(String[] args) { String html = "<h1>iText 7 示例</h1>" + "<p>这是一个使用 iText 7 从 HTML 转换而来的 PDF。</p>"; String outputFile = "D:/temp/output_from_itext.pdf"; try { // 直接将 HTML 字符串转换为 PDF 文件 HtmlConverter.convertToPdf(new File(outputFile), html); System.out.println("PDF 文件生成成功: " + outputFile); } catch (IOException e) { e.printStackTrace(); } } }
如何从 PDF 到 Word?
iText 本身不直接支持 Word 生成,你可以先生成 PDF,然后使用其他库(如 Apache PDFBox + docx4j 或商业库 Aspose.Words)将 PDF 转换成 Word,但这会增加复杂性和潜在的精度损失。
使用商业库 (如 Aspose.Words)
商业库通常提供了最简单、最强大的解决方案,对格式的支持也最好。
优点:
- API 简单易用:通常一行代码就能完成转换。
- 保真度极高:生成的文档效果非常好,几乎与原生 Word 无异。
- 功能全面:支持所有复杂的 Word 功能和 HTML/CSS 特性。
缺点:
- 需要付费:需要购买许可证,对于个人项目或预算有限的项目不适用。
实现步骤 (使用 Aspose.Words)
-
下载 JAR 包:从 Aspose 官网下载 Aspose.Words for Java 的 JAR 包。
-
编写 Java 代码
import com.aspose.words.*; public class HtmlToWordWithAspose { public static void main(String[] args) throws Exception { String html = "<h1 style='color: green;'>Aspose.Words 示例</h1>" + "<p>这是一个使用 Aspose.Words 从 HTML 转换而来的 Word 文档。</p>" + "<ul><li>列表项 1</li><li>列表项 2</li></ul>"; // 创建一个 Document 对象 Document doc = new Document(); DocumentBuilder builder = new DocumentBuilder(doc); // 使用 InsertHtml 方法直接插入 HTML // 这是 Aspose.Words 最方便的地方 builder.insertHtml(html); // 保存为 .docx 文件 doc.save("D:/temp/output_from_aspose.docx"); System.out.println("Word 文档生成成功: D:/temp/output_from_aspose.docx"); } }
使用 Docx4j (纯 Java,功能尚可)
Docx4j 是一个专门用于处理 Office Open XML 格式(.docx, .xlsx, .pptx)的纯 Java 库。
优点:
- 纯 Java:不依赖本地库。
- 专门针对 .docx:API 设计围绕 Word 文档结构。
缺点:
- HTML 支持:其 HTML 到 Word 的转换能力相对较弱,对 CSS 的支持有限,可能需要大量的手动调整才能达到理想效果。
实现步骤
-
添加 Maven 依赖
<dependency> <groupId>org.docx4j</groupId> <artifactId>docx4j-core</artifactId> <version>11.4.4</version> </dependency> <dependency> <groupId>org.docx4j</groupId> <artifactId>docx4j-export-fo</artifactId> <version>11.4.4</version> </dependency> -
编写 Java 代码 Docx4j 通常的流程是 HTML -> FO (Formatting Objects) -> Word,这个过程比较复杂,且容易出错,不推荐作为首选方案。
总结与建议
| 方案 | 优点 | 缺点 | 推荐场景 |
|---|---|---|---|
| Apache POI + Flying Saucer | 保真度高,功能强大,开源免费 | 依赖多,内容转为图片不可编辑,配置复杂 | 对文档视觉效果要求高,且接受内容为图片的场景(如报告、票据) |
| iText 7 | 专业级,HTML转PDF效果好 | AGPL许可证(商业项目需付费) | 主要需求是生成高质量PDF,且能接受许可证要求的项目 |
| Aspose.Words | API最简单,效果最好,功能最全 | 需要付费 | 预算充足,追求开发效率和最佳效果的商业项目 |
| Docx4j | 纯Java,专门针对.docx | HTML支持弱,配置复杂 | 已在使用其生态,或对纯Java有强需求且不介意复杂性的项目 |
给你的建议:
- 如果你是个人项目、学习或开源项目:首选 Apache POI + Flying Saucer会变成图片,但它是免费且功能最强大的开源组合。
- 如果你的项目是商业性质,且预算充足:强烈推荐 Aspose.Words,它能为你节省大量的开发时间,并提供最完美的转换效果。
- 如果你的主要目标是生成 PDF,而不是 Word:可以考虑 iText 7,但要务必先了解其许可证条款。
- 尽量避免直接使用 Docx4j 进行 HTML 转换,除非你有非常特殊的需求和足够的时间去研究它。
