核心思路
无论使用哪种库,转换的核心思路通常分为两步:

- 解析 HTML:将 HTML 字符串或文件解析成一个 Java 可以操作的对象模型。
- 生成 Word 文档:根据解析后的内容,使用 Word 操作库(如 Apache POI)来创建
.docx文件,并填充内容。
使用 Apache POI (纯 Java,功能强大)
这是最底层、最灵活的方式,但也是代码量最多、最复杂的方式,你需要手动处理 HTML 标签到 Word 元素的映射。
原理:
- 使用一个 HTML 解析器(如 Jsoup)来解析 HTML,提取文本、图片、表格等元素。
- 使用 Apache POI 库来创建 Word 文档的各个部分(段落、表格、图片等)。
优点:
- 完全控制:你可以精确控制 Word 文档的每一个细节,如字体、颜色、段落样式、页眉页脚等。
- 不依赖外部服务:所有逻辑都在本地运行,数据安全性高。
- 功能最全:可以实现 Word 支持的所有复杂功能。
缺点:

- 代码复杂:需要编写大量的样板代码来构建 Word 文档结构。
- 需要手动处理:HTML 标签(如
<div>,<span>)与 Word 元素(如XWPFParagraph,XWPFRun)之间没有直接对应,需要你自行实现转换逻辑。
示例代码 (简化版)
这个示例只处理了文本和粗体/斜体,实际项目中需要处理更多标签。
添加 Maven 依赖
<dependencies>
<!-- Apache POI for .docx -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.2.3</version>
</dependency>
<!-- Jsoup for HTML parsing -->
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.15.3</version>
</dependency>
</dependencies>
Java 代码
import org.apache.poi.xwpf.usermodel.*;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.io.FileOutputStream;
import java.io.IOException;
public class HtmlToWordPoi {
public static void main(String[] args) {
String htmlContent = "<h1>这是一个标题</h1>" +
"<p>这是一个段落,包含<b>粗体</b>和<i>斜体</i>文本。</p>" +
"<p>这是一个包含链接的段落:<a href=\"https://www.example.com\">示例链接</a></p>" +
"<table border=\"1\">" +
"<tr><th>Header 1</th><th>Header 2</th></tr>" +
"<tr><td>Cell 1</td><td>Cell 2</td></tr>" +
"</table>";
String outputPath = "C:\\temp\\output_from_poi.docx";
try {
convertHtmlToWord(htmlContent, outputPath);
System.out.println("Word 文档生成成功: " + outputPath);
} catch (IOException e) {
e.printStackTrace();
}
}
public static void convertHtmlToWord(String html, String outputPath) throws IOException {
// 1. 使用 Jsoup 解析 HTML
Document doc = Jsoup.parse(html);
// 2. 创建一个新的 Word 文档
XWPFDocument document = new XWPFDocument();
// 3. 遍历 HTML 元素并添加到 Word 文档
for (Element element : doc.body().children()) {
if (element.tagName().equals("h1")) {
XWPFParagraph p = document.createParagraph();
p.setBold(true);
p.setFontSize(16);
XWPFRun r = p.createRun();
r.setText(element.text());
} else if (element.tagName().equals("p")) {
XWPFParagraph p = document.createParagraph();
// 处理段落内的内联元素
for (Node node : element.childNodes()) {
if (node instanceof org.jsoup.nodes.TextNode) {
XWPFRun r = p.createRun();
r.setText(((TextNode) node).text());
} else if (node instanceof Element) {
Element inlineElement = (Element) node;
XWPFRun r = p.createRun();
if (inlineElement.tagName().equals("b") || inlineElement.tagName().equals("strong")) {
r.setBold(true);
}
if (inlineElement.tagName().equals("i") || inlineElement.tagName().equals("em")) {
r.setItalic(true);
}
r.setText(inlineElement.text());
}
}
} else if (element.tagName().equals("table")) {
XWPFTable table = document.createTable();
// ... 处理表格行和单元格的逻辑,这里省略 ...
}
// ... 可以继续添加对 ul, ol, img 等标签的处理 ...
}
// 4. 将文档写入输出文件
try (FileOutputStream out = new FileOutputStream(outputPath)) {
document.write(out);
}
}
}
使用 docx4j + Flying Saucer (推荐,功能与易用性平衡)
这是目前最推荐的方案之一,它结合了 Flying Saucer 的 HTML 渲染能力和 docx4j 的 Word 生成能力。

原理:
- HTML 转 XHTML:Flying Saucer (xhtmlrenderer) 是一个 XHTML 渲染引擎,它能将 XHTML (一个更严格的 HTML) 渲染成一个可打印的格式,比如图片或 PDF。
- 使用 docx4j:docx4j 提供了一个
XHTMLImporter,它可以解析 Flying Saucer 生成的 XHTML DOM,并将其转换为 Apache POI 的XWPFDocument对象。
优点:
- 保留样式:能很好地保留 HTML 中的 CSS 样式(如颜色、字体、边距等),这是 POI 原生方式难以做到的。
- 代码相对简洁:相比纯 POI,代码量大大减少,你主要关注 HTML 的编写。
- 功能强大:支持复杂的布局、列表、表格等。
缺点:
- 依赖多:需要引入 docx4j 和 Flying Saucer 两个较大的库。
- 性能开销:HTML 到 XHTML 的渲染过程会带来一定的性能开销。
- 不完全兼容:不是所有的 CSS 属性都能完美映射到 Word 格式。
示例代码
添加 Maven 依赖
<dependencies>
<!-- docx4j core -->
<dependency>
<groupId>org.docx4j</groupId>
<artifactId>docx4j-core</artifactId>
<version>11.4.4</version>
</dependency>
<!-- docx4j for importing XHTML -->
<dependency>
<groupId>org.docx4j</groupId>
<artifactId>docx4j-importxhtml</artifactId>
<version>11.4.4</version>
</dependency>
<!-- Flying Saucer for XHTML rendering -->
<dependency>
<groupId>org.xhtmlrenderer</groupId>
<artifactId>flying-saucer-pdf</artifactId>
<version>9.1.22</version>
</dependency>
<!-- For logging, docx4j uses slf4j -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.36</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.36</version>
</dependency>
</dependencies>
Java 代码
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart;
import org.docx4j.wml.P;
import org.jsoup.Jsoup;
import org.xhtmlrenderer.css.style.CascadingStyle;
import org.xhtmlrenderer.css.style.Style;
import org.xhtmlrenderer.layout.Box;
import org.xhtmlrenderer.layout.Context;
import org.xhtmlrenderer.swing.Java2DRenderer;
import org.xhtmlrenderer.util.FSImageWriter;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.net.URI;
import java.net.URISyntaxException;
public class HtmlToWordDocx4j {
public static void main(String[] args) {
String htmlContent = "<html><head><style>body { font-family: Arial; } h1 { color: blue; }</style></head>" +
"<body><h1>Docx4j 示例标题</h1>" +
"<p>这是一个使用 <b>docx4j</b> 和 <i>Flying Saucer</i> 生成的 Word 文档。</p>" +
"<p style=\"color: red; font-size: 12px;\">这段文字是红色的。</p></body></html>";
String outputPath = "C:\\temp\\output_from_docx4j.docx";
try {
convertHtmlToWordWithDocx4j(htmlContent, outputPath);
System.out.println("Word 文档生成成功: " + outputPath);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void convertHtmlToWordWithDocx4j(String html, String outputPath) throws Exception {
// 1. 使用 Jsoup 清理和格式化 HTML,确保它是有效的 XHTML
// 注意:Flying Saucer 需要有效的 XHTML,<br /> 而不是 <br>
org.jsoup.nodes.Document jsoupDoc = Jsoup.parse(html);
String xhtml = jsoupDoc.html(); // Jsoup 的 .html() 方法会输出格式化的 XHTML
// 2. 创建一个 WordprocessingMLPackage
WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.createPackage();
// 3. 使用 XHTMLImporter 将 XHTML 导入到 Word 文档的主部分
MainDocumentPart documentPart = wordMLPackage.getMainDocumentPart();
// docx4j 会自动处理大部分标签和样式
documentPart.getContent().addAll(XHTMLImporter.convert(xhtml, null));
// 4. 保存 Word 文档
wordMLPackage.save(new File(outputPath));
}
}
注意:上面的 XHTMLImporter.convert 是 docx4j 的核心,它已经封装了大部分复杂逻辑,你只需要提供格式良好的 XHTML 即可。
使用 iText (商业库,有免费版)
iText 是一个非常著名的 PDF 和 Word 操作库,它也提供了 HTML 转 Word 的功能。
原理:
iText 有一个专门的 HtmlConverter 类,它可以直接将 HTML 字符串或文件转换为 com.itextpdf.html2pdf.HtmlConverter 对象,然后保存为 .docx 格式。
优点:
- API 简单:一行代码就能完成转换,非常方便。
- 性能较好:底层实现经过优化。
缺点:
- 商业许可:iText 5 及之前的版本在 AGPL 许可下是免费的,但如果用于闭源的商业项目,需要购买商业许可证,iText 7 引入了更严格的许可条款。
- 样式控制有限:虽然支持 CSS,但与 docx4j 相比,在 Word 特有样式的精细控制上可能稍弱。
示例代码
添加 Maven 依赖
<dependencies>
<!-- iText 7 Core -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext7-core</artifactId>
<version>7.2.5</version>
<type>pom</type>
</dependency>
<!-- HTML to PDF/Word add-on -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>html2pdf</artifactId>
<version>4.0.3</version>
</dependency>
</dependencies>
Java 代码
import com.itextpdf.html2pdf.HtmlConverter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
public class HtmlToWordIText {
public static void main(String[] args) {
String htmlContent = "<h1>iText 示例标题</h1>" +
"<p>这是一个使用 <b>iText</b> 生成的 Word 文档。</p>";
String outputPath = "C:\\temp\\output_from_itext.docx";
try {
convertHtmlToWordWithIText(htmlContent, outputPath);
System.out.println("Word 文档生成成功: " + outputPath);
} catch (IOException e) {
e.printStackTrace();
}
}
public static void convertHtmlToWordWithIText(String html, String outputPath) throws IOException {
// iText 的 HtmlConverter 可以直接将 HTML 写入 .docx 文件
// 它会自动处理基本的 HTML 标签和样式
try (FileOutputStream fos = new FileOutputStream(new File(outputPath))) {
HtmlConverter.convertToDocument(html, fos);
}
}
}
总结与对比
| 特性 | Apache POI + Jsoup | docx4j + Flying Saucer (推荐) | iText |
|---|---|---|---|
| 易用性 | 低,代码复杂 | 中,代码相对简洁 | 高,API 极简 |
| 样式保留 | 差,需手动实现 | 好,支持大部分 CSS | 中,支持基本 CSS |
| 功能丰富度 | 极高,可实现所有 Word 功能 | 高,能满足大部分需求 | 高,功能强大 |
| 性能 | 快 (纯 Java) | 中,有渲染开销 | 较快 |
| 依赖 | POI, Jsoup | docx4j, Flying Saucer | iText 核心库 |
| 成本 | 免费 (开源) | 免费 (开源) | 有商业许可限制 |
| 适用场景 | 需要极致控制、不介意写大量代码的场景 | 需要较好保留 HTML 样式、追求开发效率的场景 | 快速实现、对样式要求不高、且能接受其许可的商业项目 |
如何选择?
- 新手或追求快速开发:选择 iText,如果项目是开源的或者符合其免费许可条款,这是最快的方式。
- 需要保留 HTML 样式(如颜色、字体、边距):强烈推荐 docx4j + Flying Saucer,它在功能和易用性之间取得了最佳平衡,是目前社区的主流选择。
- 需要精细控制 Word 文档的每一个细节(如复杂页眉页脚、图表、VBA宏等):选择 Apache POI,虽然痛苦,但它是唯一能让你完全掌控一切的方式,通常可以先尝试 docx4j,如果发现某些样式无法转换,再考虑用 POI 进行微调。
