杰瑞科技汇

Java用POI如何将Word转为HTML?

下面我将为你详细介绍几种方法,从最简单、最推荐到更复杂、更灵活的方案。

Java用POI如何将Word转为HTML?-图1
(图片来源网络,侵删)

核心思路

  1. 解析 Word 文档:使用 Apache POI 读取 .docx 文件(.doc 文件支持有限且复杂,强烈建议使用 .docx)。
  2. :遍历文档中的元素,如段落、表格、图片、列表等。
  3. 转换为 HTML 标签:将提取的 POI 对象映射到对应的 HTML 标签。
    • XWPFParagraph -> <p>
    • XWPFRun -> <span> 或直接包含在 <p>
    • XWPFTable -> <table>
    • XWPFTableRow -> <tr>
    • XWPFTableCell -> <td>
    • 图片 -> <img>
  4. 处理样式:这是最复杂的部分,POI 的样式(如字体、颜色、对齐方式)需要转换为 CSS 样式。
  5. 保存为文件:将生成的 HTML 字符串写入 .html 文件。

使用 docx4j (强烈推荐)

docx4j 是一个专门处理 Office Open XML 格式(如 .docx)的 Java 库,它内置了强大的 Word 到 HTML 的转换功能,使用起来非常简单,效果也最好。

添加依赖

在你的 pom.xml 文件中添加 docx4j 的依赖:

<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>
<!-- 如果需要转换 .doc 文件,需要额外添加 -->
<dependency>
    <groupId>org.docx4j</groupId>
    <artifactId>docx4j-converter-microsoft</artifactId>
    <version>11.4.4</version>
</dependency>

Java 代码实现

转换 .docx 文件:

import org.docx4j.Docx4J;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import java.io.File;
import java.io.FileOutputStream;
public class DocxToHtmlConverter {
    public static void main(String[] args) {
        try {
            // 1. 加载 Word 文档
            String inputPath = "path/to/your/document.docx";
            String outputPath = "path/to/your/output.html";
            WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.load(new File(inputPath));
            // 2. 转换为 HTML
            // options 可以用来控制转换行为,例如是否包含页眉页脚
            org.docx4j.convert.in.xhtml.XHTMLImporterImpl XHTMLImporter = new org.docx4j.convert.in.xhtml.XHTMLImporterImpl(wordMLPackage);
            // Docx4J 提供了便捷的转换方法
            String html = Docx4J.toHTML(wordMLPackage, null, Docx4J.FLAG_EXPORT_PREFER_XSL);
            // 3. 保存 HTML 文件
            try (FileOutputStream out = new FileOutputStream(outputPath)) {
                out.write(html.getBytes("UTF-8"));
            }
            System.out.println("转换成功!HTML 文件已保存至: " + outputPath);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

优点:

Java用POI如何将Word转为HTML?-图2
(图片来源网络,侵删)
  • 简单易用:几行代码即可完成转换。
  • 功能强大:能很好地处理样式、图片、表格、页眉页脚等复杂内容。
  • 高质量输出:生成的 HTML 和 CSS 结构清晰,可读性好。

缺点:

  • 依赖库相对较大。
  • 主要支持 .docx 格式,对 .doc 的支持需要额外依赖且效果可能不佳。

使用 Apache POI 手动实现 (更灵活,但更复杂)

如果你不想引入 docx4j,或者需要完全控制转换过程的每一个细节,可以使用 Apache POI 手动实现。

添加依赖

在你的 pom.xml 文件中添加 Apache POI 的依赖:

<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>5.2.3</version> <!-- 建议使用最新版本 -->
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>5.2.3</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-scratchpad</artifactId>
    <version>5.2.3</version>
</dependency>

Java 代码实现

这个例子会遍历段落和表格,并尝试处理一些基本样式。

import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
import java.io.*;
import java.util.List;
public class PoiDocxToHtmlConverter {
    public static void main(String[] args) {
        try {
            String inputPath = "path/to/your/document.docx";
            String outputPath = "path/to/your/output_poi.html";
            XWPFDocument document = new XWPFDocument(new FileInputStream(inputPath));
            StringBuilder htmlBuilder = new StringBuilder();
            // 添加 HTML 头部
            htmlBuilder.append("<!DOCTYPE html>\n<html>\n<head>\n")
                      .append("<meta charset=\"UTF-8\">\n")
                      .append("<title>Word to HTML</title>\n")
                      .append("<style>\n") // 内联 CSS 样式
                      .append("  body { font-family: Arial, sans-serif; }\n")
                      .append("  p { margin: 8px 0; }\n")
                      .append("  table { border-collapse: collapse; width: 100%; }\n")
                      .append("  td, th { border: 1px solid #ddd; padding: 8px; text-align: left; }\n")
                      .append("</style>\n")
                      .append("</head>\n<body>\n");
            // 处理段落
            for (XWPFParagraph p : document.getParagraphs()) {
                if (!p.getParagraphText().isEmpty()) {
                    htmlBuilder.append("<p>");
                    processRuns(p.getRuns(), htmlBuilder);
                    htmlBuilder.append("</p>\n");
                }
            }
            // 处理表格
            for (XWPFTable table : document.getTables()) {
                htmlBuilder.append("<table>\n");
                for (XWPFTableRow row : table.getRows()) {
                    htmlBuilder.append("<tr>\n");
                    for (XWPFTableCell cell : row.getTableCells()) {
                        htmlBuilder.append("<td>");
                        for (XWPFParagraph p : cell.getParagraphs()) {
                            if (!p.getParagraphText().isEmpty()) {
                                processRuns(p.getRuns(), htmlBuilder);
                            }
                        }
                        htmlBuilder.append("</td>");
                    }
                    htmlBuilder.append("\n</tr>\n");
                }
                htmlBuilder.append("</table>\n");
            }
            // 添加 HTML 尾部
            htmlBuilder.append("</body>\n</html>");
            // 写入文件
            try (FileOutputStream out = new FileOutputStream(outputPath)) {
                out.write(htmlBuilder.toString().getBytes("UTF-8"));
            }
            System.out.println("POI 转换成功!HTML 文件已保存至: " + outputPath);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 处理段落内的文本块,应用样式
     */
    private static void processRuns(List<XWPFRun> runs, StringBuilder htmlBuilder) {
        for (XWPFRun run : runs) {
            String text = run.getText(0);
            if (text == null || text.isEmpty()) {
                continue;
            }
            // 开始标签
            htmlBuilder.append("<span style=\"");
            // 字体
            if (run.isBold()) htmlBuilder.append("font-weight: bold; ");
            if (run.isItalic()) htmlBuilder.append("font-style: italic; ");
            if (run.getUnderline() != UnderlinePatterns.none) htmlBuilder.append("text-decoration: underline; ");
            if (run.getColor() != null) htmlBuilder.append("color: #" + run.getColor() + "; ");
            if (run.getFontFamily() != null) htmlBuilder.append("font-family: " + run.getFontFamily() + "; ");
            if (run.getFontSize() != -1) htmlBuilder.append("font-size: " + run.getFontSize() + "pt; ");
            htmlBuilder.append("\">");
            // 文本内容 (需要转义 HTML 特殊字符)
            htmlBuilder.append(escapeHtml(text));
            // 结束标签
            htmlBuilder.append("</span>");
        }
    }
    /**
     * 转义 HTML 特殊字符
     */
    private static String escapeHtml(String input) {
        if (input == null) {
            return "";
        }
        return input.replace("&", "&amp;")
                   .replace("<", "&lt;")
                   .replace(">", "&gt;")
                   .replace("\"", "&quot;")
                   .replace("'", "&#39;");
    }
}

优点:

  • 完全控制:你可以精确决定如何处理每一个元素和样式。
  • 依赖较小:只需要 POI 相关库。
  • 轻量级:对于转换需求非常简单的场景,可能更合适。

缺点:

  • 非常复杂:需要手动处理所有 Word 元素和样式的映射。
  • 功能有限:很难完美处理页眉页脚、页脚、页码、复杂的浮动图片、文本框等。
  • 样式处理繁琐:将 POI 的样式对象转换为 CSS 是一项艰巨的任务。

使用 aspose-words (商业库,功能最强)

Aspose.Words 是一个商业的 Java 文档处理库,以其卓越的转换质量和稳定性而闻名,如果你有预算,这是最佳选择。

添加依赖

<!-- Aspose.Words 是商业库,需要付费许可证 -->
<dependency>
    <groupId>com.aspose</groupId>
    <artifactId>aspose-words</artifactId>
    <version>23.8</version> <!-- 建议使用最新版本 -->
</dependency>

Java 代码实现

import com.aspose.words.*;
import java.io.*;
public class AsposeDocxToHtmlConverter {
    public static void main(String[] args) throws Exception {
        // 如果有许可证,在此加载
        // License license = new License();
        // license.setLicense("Aspose.Words.Java.lic");
        String inputPath = "path/to/your/document.docx";
        String outputPath = "path/to/your/output_aspose.html";
        // 加载文档
        Document doc = new Document(inputPath);
        // 保存为 HTML
        // HtmlSaveOptions 提供了丰富的选项来控制输出
        HtmlSaveOptions saveOptions = new HtmlSaveOptions();
        saveOptions.setPrettyFormat(true); // 格式化输出
        saveOptions.setExportHeadersFootersMode(ExportHeadersFootersMode.FirstPage); // 导出页眉页脚模式
        doc.save(outputPath, saveOptions);
        System.out.println("Aspose 转换成功!HTML 文件已保存至: " + outputPath);
    }
}

优点:

  • 无与伦比的转换质量:生成的 HTML 几乎与原始 Word 文档一模一样。
  • 功能最全面:支持所有 Word 特性,包括复杂的布局、样式、域、OLE 对象等。
  • 性能优秀:处理大文档速度快,稳定性高。
  • API 友好:简单易用,配置选项丰富。

缺点:

  • 需要付费:这是一个商业产品,价格不菲。

总结与选择建议

特性 docx4j (开源) Apache POI (手动实现) aspose-words (商业)
易用性 ⭐⭐⭐⭐⭐ ⭐⭐ ⭐⭐⭐⭐⭐
转换质量 ⭐⭐⭐⭐ ⭐⭐ ⭐⭐⭐⭐⭐
功能完整性 ⭐⭐⭐⭐ ⭐⭐ ⭐⭐⭐⭐⭐
灵活性 ⭐⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐
成本 免费 免费 付费
主要格式 .docx .docx .doc, .docx, 等

如何选择?

  1. 首选 docx4j:对于绝大多数开源项目和个人开发者,docx4j 是最佳选择,它在易用性、功能和免费之间取得了最好的平衡。
  2. 选择手动 POI 实现:只有当你对转换过程有完全的、精细的控制需求,并且不介意投入大量时间去开发和维护转换逻辑时,才考虑此方案。
  3. 选择 aspose-words:如果你的项目有预算,并且对文档转换的保真度、稳定性和性能有极高的要求(企业级应用、生成正式报告),aspose-words 是最值得投资的选择。
分享:
扫描分享到社交APP
上一篇
下一篇