杰瑞科技汇

word 转html java

核心思路

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

word 转html java-图1
(图片来源网络,侵删)
  1. 引入依赖:在你的 Java 项目中添加处理 Word 和 HTML 的库。
  2. 加载 Word 文档:使用库提供的 API 读取 .docx 文件。
  3. :遍历 Word 文档的元素(段落、表格、图片、列表等)。
  4. 转换为 HTML:将提取的元素及其样式(如字体、颜色、对齐方式)映射到对应的 HTML 标签和 CSS 样式。
  5. 生成并输出 HTML 文件:将转换后的 HTML 字符串写入到一个 .html 文件中。

使用 Apache POI (推荐,功能最强大)

Apache POI 是 Java 操作 Office 文档的“瑞士军刀”,功能非常全面,虽然它本身不是一个专门的“转 HTML”工具,但通过组合其 XWPF(.docx)组件,我们可以实现高质量的转换。

优点

  • 功能最全面:可以精确控制 Word 文档中的每一个元素(文本、表格、图片、页眉页脚、页码、超链接等)。
  • 社区活跃:遇到问题容易找到解决方案和第三方扩展。
  • 免费开源:基于 Apache License 2.0。

缺点

  • 样式处理复杂:将复杂的 Word 样式(如自定义样式、段落间距)完美转换为 CSS 需要编写较多的代码。
  • 需要自己实现转换逻辑:POI 只提供读取 Word 的能力,你需要自己编写代码来构建 HTML。

实现步骤

  1. 添加 Maven 依赖 你需要 poipoi-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>
  2. 编写转换代码 下面是一个完整的示例,它处理段落、表格、图片和基本样式。

    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 提供了 HtmlSettingsWordprocessingMLPackage,可以方便地进行转换。
  • 样式保留较好:内置的转换器能较好地处理 Word 样式到 CSS 的映射。
  • API 设计友好:基于 JAXB,对于处理 XML 结构非常直观。

缺点

  • 依赖较多:依赖 JAXB 和其他一些较大的库,项目体积会变大。
  • 转换结果可能包含冗余:内置转换器生成的 HTML 可能包含大量 div 和内联样式,需要后期清理。

实现步骤

  1. 添加 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>
  2. 编写转换代码 使用 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 模块)

  1. 添加 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>
  2. 编写转换代码 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** 进行深度定制。
分享:
扫描分享到社交APP
上一篇
下一篇