核心思路
无论使用哪种库,其基本流程都大同小异:

- 引入依赖:在你的 Java 项目中添加处理 Word 和 HTML 的库。
- 加载 Word 文档:使用库提供的 API 读取
.docx文件。 - :遍历 Word 文档的元素(段落、表格、图片、列表等)。
- 转换为 HTML:将提取的元素及其样式(如字体、颜色、对齐方式)映射到对应的 HTML 标签和 CSS 样式。
- 生成并输出 HTML 文件:将转换后的 HTML 字符串写入到一个
.html文件中。
使用 Apache POI (推荐,功能最强大)
Apache POI 是 Java 操作 Office 文档的“瑞士军刀”,功能非常全面,虽然它本身不是一个专门的“转 HTML”工具,但通过组合其 XWPF(.docx)组件,我们可以实现高质量的转换。
优点
- 功能最全面:可以精确控制 Word 文档中的每一个元素(文本、表格、图片、页眉页脚、页码、超链接等)。
- 社区活跃:遇到问题容易找到解决方案和第三方扩展。
- 免费开源:基于 Apache License 2.0。
缺点
- 样式处理复杂:将复杂的 Word 样式(如自定义样式、段落间距)完美转换为 CSS 需要编写较多的代码。
- 需要自己实现转换逻辑:POI 只提供读取 Word 的能力,你需要自己编写代码来构建 HTML。
实现步骤
-
添加 Maven 依赖 你需要
poi和poi-ooxml两个核心包,为了更好地处理 XML,推荐也添加xmlbeans。<dependencies> <!-- Apache POI Core --> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>5.2.4</version> </dependency> <!-- Apache POI for OOXML formats (like .docx) --> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>5.2.4</version> </dependency> <!-- For better XML handling --> <dependency> <groupId>org.apache.xmlbeans</groupId> <artifactId>xmlbeans</artifactId> <version>5.1.1</version> </dependency> </dependencies> -
编写转换代码 下面是一个完整的示例,它处理段落、表格、图片和基本样式。
import org.apache.poi.xwpf.usermodel.*; org.apache.xmlbeans.XmlException; org.apache.poi.openxml4j.exceptions.InvalidFormatException; org.apache.poi.util.Units; import java.io.*; import java.util.List; public class WordToHtmlConverter { public static void main(String[] args) { String inputWordPath = "input.docx"; String outputHtmlPath = "output.html"; try { convertDocxToHtml(inputWordPath, outputHtmlPath); System.out.println("转换成功!HTML 文件已生成: " + outputHtmlPath); } catch (IOException | InvalidFormatException | XmlException e) { e.printStackTrace(); } } public static void convertDocxToHtml(String docxPath, String htmlPath) throws IOException, InvalidFormatException, XmlException { // 1. 加载 Word 文档 XWPFDocument document = new XWPFDocument(new FileInputStream(docxPath)); // 2. 创建 HTML 构建器 StringBuilder htmlBuilder = new StringBuilder(); htmlBuilder.append("<html><head><meta charset=\"UTF-8\"><title>转换自 Word</title></head><body>"); // 3. 遍历文档中的所有元素 for (IBodyElement element : document.getBodyElements()) { if (element instanceof XWPFParagraph) { // 处理段落 XWPFParagraph paragraph = (XWPFParagraph) element; htmlBuilder.append(convertParagraph(paragraph)); } else if (element instanceof XWPFTable) { // 处理表格 XWPFTable table = (XWPFTable) element; htmlBuilder.append(convertTable(table)); } } // 4. 处理图片 (需要单独遍历,因为图片是独立的 run) List<XWPFPictureData> pictures = document.getAllPictures(); for (XWPFPictureData picture : pictures) { // 注意:这里只是将图片数据内联到HTML,实际应用中可能需要将图片保存为单独文件 String pictureHtml = String.format("<img src=\"data:image/%s;base64,%s\" alt=\"Word Image\">", picture.suggestFileExtension(), new String(picture.getData())); // 将图片插入到文档的某个位置比较复杂,这里简化处理,可以放在body末尾 // 更好的做法是记录图片位置并插入到对应段落中 htmlBuilder.append(pictureHtml); } htmlBuilder.append("</body></html>"); // 5. 写入 HTML 文件 try (BufferedWriter writer = new BufferedWriter(new FileWriter(htmlPath))) { writer.write(htmlBuilder.toString()); } document.close(); } private static String convertParagraph(XWPFParagraph paragraph) { StringBuilder html = new StringBuilder("<p>"); for (XWPFRun run : paragraph.getRuns()) { String text = run.getText(0); if (text == null || text.isEmpty()) { continue; } html.append("<span style=\""); // 处理样式 if (run.isBold()) html.append("font-weight: bold;"); if (run.isItalic()) html.append("font-style: italic;"); if (run.getUnderline() != UnderlinePatterns.NONE) { html.append("text-decoration: underline;"); } String fontFamily = run.getFontFamily(); if (fontFamily != null) { html.append("font-family: ").append(fontFamily).append(";"); } int fontSize = run.getFontSize(); if (fontSize > 0) { html.append("font-size: ").append(fontSize).append("pt;"); } String color = run.getColor(); if (color != null) { html.append("color: #").append(color).append(";"); } html.append("\">"); html.append(text); html.append("</span>"); } // 处理段落对齐 String alignment = getAlignment(paragraph.getAlignment()); if (!alignment.isEmpty()) { html.insert(0, "<p style=\"text-align: " + alignment + "\">"); } else { html.insert(0, "<p>"); } html.append("</p>"); return html.toString(); } private static String convertTable(XWPFTable table) { StringBuilder html = new StringBuilder("<table border=\"1\">"); for (XWPFTableRow row : table.getRows()) { html.append("<tr>"); for (XWPFTableCell cell : row.getTableCells()) { html.append("<td>"); for (XWPFParagraph p : cell.getParagraphs()) { html.append(convertParagraph(p)); } html.append("</td>"); } html.append("</tr>"); } html.append("</table>"); return html.toString(); } private static String getAlignment(ParagraphAlignment alignment) { if (alignment == null) return ""; switch (alignment) { case CENTER: return "center"; case LEFT: return "left"; case RIGHT: return "right"; case BOTH: return "justify"; default: return ""; } } }
使用 docx4j (功能强大,专为 OOXML 设计)
docx4j 是另一个专门处理 Office Open XML 格式(.docx, .xlsx, .pptx)的库,它在某些方面比 POI 更 OOXML 原生,转换功能也很出色。
优点
- 转换功能内置:docx4j 提供了
HtmlSettings和WordprocessingMLPackage,可以方便地进行转换。 - 样式保留较好:内置的转换器能较好地处理 Word 样式到 CSS 的映射。
- API 设计友好:基于 JAXB,对于处理 XML 结构非常直观。
缺点
- 依赖较多:依赖 JAXB 和其他一些较大的库,项目体积会变大。
- 转换结果可能包含冗余:内置转换器生成的 HTML 可能包含大量
div和内联样式,需要后期清理。
实现步骤
-
添加 Maven 依赖
<dependencies> <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> <!-- JAXB is required by docx4j for older Java versions --> <dependency> <groupId>org.glassfish.jaxb</groupId> <artifactId>jaxb-runtime</artifactId> <version>2.3.3</version> </dependency> </dependencies> -
编写转换代码 使用 docx4j 的内置转换器非常简单。
import org.docx4j.Docx4J; import org.docx4j.openpackaging.packages.WordprocessingMLPackage; import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart; import java.io.File; import java.io.OutputStream; public class Docx4jConverter { public static void main(String[] args) { String inputWordPath = "input.docx"; String outputHtmlPath = "output_docx4j.html"; try { convertDocxToHtml(inputWordPath, outputHtmlPath); System.out.println("转换成功!HTML 文件已生成: " + outputHtmlPath); } catch (Exception e) { e.printStackTrace(); } } public static void convertDocxToHtml(String docxPath, String htmlPath) throws Exception { // 1. 加载 Word 文档 WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.load(new File(docxPath)); // 2. 设置 HTML 转换选项 org.docx4j.convert.in.xhtml.XHTMLConversionOptions options = org.docx4j.convert.in.xhtml.XHTMLConversionOptions.create(); // 你可以在这里配置一些选项,比如是否保留样式等 // 3. 执行转换 // Docx4J 会将整个文档内容转换为一个 XHTML 字符串 String html = Docx4J.convert(wordMLPackage, options); // 4. 写入 HTML 文件 // 注意:转换后的HTML可能不包含<html>和<body>标签,需要手动包装 String fullHtml = "<!DOCTYPE html><html><head><meta charset=\"UTF-8\"><title>转换自 Word (docx4j)</title></head><body>" + html + "</body></html>"; try (OutputStream out = new FileOutputStream(htmlPath)) { out.write(fullHtml.getBytes("UTF-8")); } } }
使用 iText (商业库,功能强大)
iText 是一个非常著名的 PDF 和文档操作库,它有一个商业版本的 iText 7,提供了将 Word (DocX) 转换为 HTML 的功能。
优点
- 高质量转换:iText 的转换引擎非常成熟,能生成非常干净、格式良好的 HTML 和 CSS。
- 商业支持:购买商业版可以获得专业的技术支持。
缺点
- 收费:核心转换功能在 AGPL 许可下是免费的,但如果你在闭源的商业应用中使用,则需要购买商业许可证,这通常是最大的限制。
实现步骤 (需要 iText 7 Core 和 Layout 模块)
-
添加 Maven 依赖
<dependencies> <!-- iText 7 Core --> <dependency> <groupId>com.itextpdf</groupId> <artifactId>itext7-core</artifactId> <version>7.2.5</version> <type>pom</type> </dependency> <!-- iText 7 Layout for HTML conversion --> <dependency> <groupId>com.itextpdf</groupId> <artifactId>html2pdf</artifactId> <version>4.0.3</version> </dependency> </dependencies> -
编写转换代码 iText 的转换过程相对高级,它将 Word 视为一种布局格式进行解析。
import com.itextpdf.html2pdf.HtmlConverter; import com.itextpdf.html2pdf.resolver.font.DefaultFontProvider; import com.itextpdf.io.font.PdfFont; import com.itextpdf.io.font.PdfFontFactory; import com.itextpdf.kernel.pdf.PdfDocument; import com.itextpdf.kernel.pdf.PdfWriter; import com.itextpdf.layout.font.FontProvider;
import java.io.*;
public class ITextConverter {
public static void main(String[] args) {
String inputWordPath = "input.docx";
String outputHtmlPath = "output_itext.html";
try {
convertDocxToHtml(inputWordPath, outputHtmlPath);
System.out.println("转换成功!HTML 文件已生成: " + outputHtmlPath);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void convertDocxToHtml(String docxPath, String htmlPath) throws Exception {
// iText 7 的 DocX to HTML 转换通常分两步:
// 1. 将 DocX 转换为临时 PDF
// 2. 将 PDF 转换为 HTML
// 或者直接使用其布局解析器转换 DocX
// 这里展示一种更直接的方法:使用其布局解析器
// 注意:iText 的 HTML 生成器主要是为了从 HTML 生成 PDF,反向转换支持有限。
// 对于 DocX 到 HTML,iText 官方推荐使用其商业的 DocX 解析器。
// 以下代码仅作概念演示,可能无法完美工作。
// 更实际的商业方案是使用 iText 7 的商业模块,它提供了直接的 DocX 解析和转换功能。
//
// PdfReader reader = new PdfReader(new File("input.pdf"));
// PdfWriter writer = new PdfWriter(new File("output.pdf"));
// PdfDocument pdf = new PdfDocument(reader, writer);
// ConverterProperties props = new ConverterProperties();
// HtmlConverter.convertToHtml(pdf, new File("output.html"), props);
// 由于 iText 的 DocX 转 HTML 在开源版本中支持不完善,此处不提供完整示例。
// 请参考 iText 官方文档获取商业版的使用方法。
System.out.println("iText 的 DocX 转 HTML 功能主要在商业版本中提供。");
}
---
### 总结与对比
| 特性 | Apache POI | docx4j | iText (商业) |
| :--- | :--- | :--- | :--- |
| **易用性** | 中等,需要自己编写转换逻辑 | **高**,内置转换器 | 高,但商业版需要授权 |
| **功能完整性** | **极高**,可访问所有细节 | 高,支持大部分元素 | **极高**,商业版功能最完善 |
| **样式保留** | 一般,需要手动映射 CSS | **好**,内置样式转换 | **优秀**,生成干净CSS |
| **依赖/成本** | 免费,依赖少 | 免费,依赖较多 | **商业软件**,闭源需付费 |
| **推荐场景** | 需要完全控制转换过程,或处理非常特殊的Word元素 | 快速实现,对样式要求不是极端苛刻的项目 | 对转换质量和样式保真度要求极高的商业项目 |
### 如何选择?
* **如果你是初学者,或者项目时间紧张**:选择 **docx4j**,它的内置转换器能让你用最少的代码完成大部分任务,效果也还不错。
* **如果你需要精细控制转换的每一个细节**,比如自定义HTML标签、处理特殊的Word元素、或者对生成的CSS有特定要求:选择 **Apache POI**,虽然代码量会多一些,但灵活性和可控性是最好的。
* **如果你的项目是商业性质,并且预算充足,对输出质量有极致要求**:考虑 **iText 商业版**,它能提供最稳定、最专业的转换效果。
对于大多数 Java **Apache POI** 和 **docx4j** 是最常用且最实用的选择,你可以先从 **docx4j** 开始尝试,如果发现无法满足你的特定需求,再转向使用 **Apache POI** 进行深度定制。 