关于Java实现word(docx、doc)转html的完美解决方案

 更新时间:2025年01月26日 10:32:25   作者:WAZYY0619  
文章介绍了多种将Word文档转换为HTML的方法,包括使用Microsoft Word自带的导出功能、第三方工具和编程实现,展示了如何实现将.docx文件转换为HTML文件,并自动生成目录、处理分页符和增强表格样式等功能,感兴趣的朋友一起看看吧

最近在研究一些关于文档转换格式的方法,因为需要用在开发的一个项目上,所以投入了一些时间,给大家聊下这块逻辑及解决方案。

一、关于word转换html大致都有哪些方法?

(1)使用 Microsoft Word 导出

        其实该方法就是使用word本身导出方案

操作步骤

  • 在 Microsoft Word 中打开文档。
  • 点击 文件 > 另存为 或 导出。
  • 选择保存类型为 网页(.html, .htm)。
  • 保存文件后,会生成一个 HTML 文件(有时会附带一个文件夹用于存放图片等资源)。

优点

  • 保留了文档的大部分格式。
  • 操作简单,无需其他工具。

缺点

  • 导出的 HTML 文件代码较冗余,包含许多与 Word 相关的样式和标签。

(2)使用第三方工具或在线转换工具

        一般常见的有SmallPDF、Zamzar、Convertio、LibreOffice等在线工具或软件进行转换

优点

  • 方便快捷,适合大多数人使用。
  • 有些工具可以清理冗余代码,生成更简洁的 HTML。

缺点

  • 在线工具可能存在隐私和安全风险。
  • 某些工具可能无法完全保留复杂文档的格式。

(3)使用编程实现自动化转换

常见的编程实现有:

  • Python
    • 使用 python-docx 库读取 .docx 文件,再用自定义逻辑生成 HTML。
    • 使用 mammoth 库,专门将 .docx 转为干净的 HTML(推荐)。
    • 使用 pywin32 调用 Windows COM 接口操作 Microsoft Word。
  • Java
    • 使用 Apache POI 的 XWPF 模块解析 .docx 文件并输出 HTML。
  • Node.js
    • 使用 officegenmammoth.js 转换 .docx 文件。
  • C#
    • 使用 OpenXML SDK 或 Interop.Word 来操作 Word 文件并转换为 HTML。

        本此讲解的就是通过java的poi内的模块进行解析输出html

二、docx转换html

        示例代码如下:

public static void docxtoHtml(String fileName, String outPutFile) throws TransformerException, IOException, ParserConfigurationException {
    long startTime = System.currentTimeMillis();
    XWPFDocument document = new XWPFDocument(new FileInputStream(fileName));
    // 用于存储目录内容
    StringBuilder toc = new StringBuilder();
    toc.append("<div id='toc'>\n<ul>\n");  // 直接从 <ul> 开始,表示目录
    // 遍历文档中的段落,查找目录项
    List<XWPFParagraph> paragraphs = document.getParagraphs();
    int tocLevel = 0; // 目录的当前级别,1代表一级目录,2代表二级目录,3代表三级目录
    boolean tocStarted = false; // 标记目录是否开始
    for (XWPFParagraph paragraph : paragraphs) {
        String style = paragraph.getStyle();  // 获取段落样式
        String text = paragraph.getText();  // 获取段落文本
        // 根据段落的样式级别来识别目录项,假设标题样式为 Heading 1, Heading 2, Heading 3
        if (style != null) {
            if (style.equals("Heading 1")) {  // 一级标题
                if (tocStarted) {
                    toc.append("</ul>\n"); // 关闭上一级目录
                }
                toc.append("<ul>\n");  // 开始一个新的无序列表
                toc.append("<li><a href='#" + text.hashCode() + "'>" + text + "</a></li>\n");
                tocLevel = 1;
                tocStarted = true;
            } else if (style.equals("Heading 2")) {  // 二级标题
                if (tocLevel == 1) {
                    toc.append("<ul>\n");  // 开始二级目录
                }
                toc.append("<li><a href='#" + text.hashCode() + "'>" + text + "</a></li>\n");
                tocLevel = 2;
            } else if (style.equals("Heading 3")) {  // 三级标题
                if (tocLevel == 2) {
                    toc.append("<ul>\n");  // 开始三级目录
                }
                toc.append("<li><a href='#" + text.hashCode() + "'>" + text + "</a></li>\n");
                tocLevel = 3;
            }
        }
        // 在目录项前插入锚点
        if (style != null && (style.equals("Heading 1") || style.equals("Heading 2") || style.equals("Heading 3"))) {
            String anchor = "<a name='" + text.hashCode() + "'></a>";
            String modifiedText = anchor + text;  // 在目录项文本前添加锚点
            // 更新段落中的文本
            for (XWPFRun run : paragraph.getRuns()) {
                run.setText(modifiedText, 0); // 更新段落内容
            }
        }
    }
    // 如果目录结束后,确保关闭所有的<ul>标签
    if (tocLevel > 0) {
        toc.append("</ul>\n");
    }
    toc.append("</ul>\n</div>\n");  // 关闭最外层的 <ul> 和 <div>
    // 设置XHTMLOptions
    XHTMLOptions options = XHTMLOptions.create().indent(4);
    File imageFolder = new File(tempPath);  // 图片临时文件夹路径
    options.setExtractor(new FileImageExtractor(imageFolder));
    options.URIResolver(new FileURIResolver(imageFolder));
    // 使用 `XHTMLConverter` 进行 DOCX 到 HTML 的转换
    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
    XHTMLConverter.getInstance().convert(document, byteArrayOutputStream, options);
    System.out.println("Generate " + outPutFile + " with " + (System.currentTimeMillis() - startTime) + " ms.");
    // 获取转换后的HTML内容
    String htmlContent = new String(byteArrayOutputStream.toByteArray(), "UTF-8");
    // 将TOC插入到HTML的开头
    htmlContent = toc + htmlContent;
    // 处理分页符:将分页符添加到HTML中
    htmlContent = htmlContent.replaceAll("<!-- PAGE_BREAK -->", "<div class='page-break'></div>");
    // 添加表格样式(边框)
    htmlContent = htmlContent.replaceAll("<table>", "<table style='border: 1px solid black !important; border-collapse: collapse; width: 100%;'>");
    htmlContent = htmlContent.replaceAll("<td>", "<td style='border: 1px solid black !important; padding: 5px; text-align: left;'>");
    htmlContent = htmlContent.replaceAll("<th>", "<th style='border: 1px solid black !important; padding: 5px; text-align: left;'>");
    htmlContent = htmlContent.replaceAll("<tr>", "<tr style='border: 1px solid black !important;'>");
    htmlContent = htmlContent.replaceAll("<thead>", "<thead style='border: 1px solid black !important;'>");
    htmlContent = htmlContent.replaceAll("<tbody>", "<tbody style='border: 1px solid black !important;'>");
    htmlContent = htmlContent.replaceAll("<tfoot>", "<tfoot style='border: 1px solid black !important;'>");
    // 增加全局CSS样式(确保表格和目录样式正确)
    String style = "<style>\n" +
                   "table { border: 1px solid black !important; border-collapse: collapse; width: 100%; }\n" +
                   "td, th { border: 1px solid black !important; padding: 5px; text-align: left; }\n" +
                   "tr { border: 1px solid black !important; }\n" +
                   "ul { list-style-type: none; padding: 0; }\n" + // 去掉默认的列表样式
                   "li { margin: 5px 0; }\n" + // 设置目录项的间距
                   "</style>\n";
    htmlContent = style + htmlContent;
    // 将最终的HTML内容写入文件
    writeFile(htmlContent, outPutFile);
}

        该方法功能实现:

  • .docx 文件转换为 HTML 文件。
  • 自动生成基于文档标题的目录 (TOC)。
  • 为标题添加锚点链接,支持 HTML 页面内跳转。
  • 处理分页符,将其转换为 HTML 的 <div> 元素。
  • 增强表格样式,添加边框和对齐(有时原表格css样式转换后会被覆盖掉)。
  • 为 HTML 页面添加全局 CSS 样式,保证视觉效果统一。

三、doc转换html

        示例代码如下:

public static void doctoHtml(String fileName, String outPutFile) throws TransformerException, IOException, ParserConfigurationException {
    // 开始计时
    long startTime = System.currentTimeMillis();
    // 读取 Word 文档
    HWPFDocument wordDocument = new HWPFDocument(new FileInputStream(fileName));
    // 创建 Word 转 HTML 转换器
    WordToHtmlConverter wordToHtmlConverter = new WordToHtmlConverter(DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument());
    // 图片保存路径设置
    String imageFolderPath = tempPath + "images" + File.separator;  // 存储图片的绝对路径
    // 设置图片管理器,处理图片保存逻辑
    wordToHtmlConverter.setPicturesManager(new PicturesManager() {
        public String savePicture(byte[] content, PictureType pictureType, String suggestedName, float widthInches, float heightInches) {
            String picturePath = imageFolderPath + suggestedName;  // 图片保存路径
            File imageFolder = new File(imageFolderPath);
            if (!imageFolder.exists()) {
                boolean created = imageFolder.mkdirs(); // 创建图片文件夹
                if (created) {
                    System.out.println("在以下位置创建图片文件夹:" + imageFolder.getAbsolutePath());
                } else {
                    System.out.println("创建图片文件夹失败");
                }
            }
            try {
                File pictureFile = new File(picturePath);
                try (FileOutputStream fos = new FileOutputStream(pictureFile)) {
                    fos.write(content);  // 写入图片数据
                    System.out.println("图片保存路径" + pictureFile.getAbsolutePath());
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            return picturePath;  // 返回图片路径
        }
    });
    // 处理文档内容,转换为 HTML
    wordToHtmlConverter.processDocument(wordDocument);
    // 获取生成的 HTML 文档
    Document htmlDocument = wordToHtmlConverter.getDocument();
    // 自定义分页符处理:查找文档中的分页符并插入到 HTML 中
    NodeList bodyNodes = htmlDocument.getElementsByTagName("body");
    if (bodyNodes.getLength() > 0) {
        Node bodyNode = bodyNodes.item(0);  // 获取 HTML 中的 <body> 节点
        NodeList paragraphs = bodyNode.getChildNodes();
        for (int i = 0; i < paragraphs.getLength(); i++) {
            Node paragraph = paragraphs.item(i);
            if (paragraph.getNodeType() == Node.ELEMENT_NODE && paragraph.getNodeName().equals("p")) {
                String innerText = paragraph.getTextContent();
                if (innerText.contains("\f")) {  // 检查是否包含分页符(\f)
                    // 创建自定义分页符 HTML 元素
                    Element pageBreak = htmlDocument.createElement("div");
                    pageBreak.setAttribute("class", "page-break");  // 设置 class 属性,方便样式控制
                    pageBreak.appendChild(htmlDocument.createTextNode(" "));
                    // 在分页符前插入自定义分页符标记
                    bodyNode.insertBefore(pageBreak, paragraph);
                }
            }
        }
    }
    // 将 HTML 文档输出为字节流
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    DOMSource domSource = new DOMSource(htmlDocument);
    StreamResult streamResult = new StreamResult(out);
    // 使用 Transformer 进行 HTML 格式化输出
    TransformerFactory tf = TransformerFactory.newInstance();
    Transformer serializer = tf.newTransformer();
    serializer.setOutputProperty(OutputKeys.ENCODING, "utf-8");  // 设置编码为 UTF-8
    serializer.setOutputProperty(OutputKeys.INDENT, "yes");  // 格式化输出
    serializer.setOutputProperty(OutputKeys.METHOD, "html");  // 输出格式为 HTML
    serializer.transform(domSource, streamResult);
    out.close();
    // 将字节流转换为字符串
    String htmlContent = new String(out.toByteArray());
    // 处理特殊标记符,例如去掉目录标记(根据需要调整)
    htmlContent = htmlContent.replaceAll("TOC \\\\o \"1-3\" \\\\h \\\\z \\\\u", "");
    // 将生成的 HTML 内容写入文件
    writeFile(htmlContent, outPutFile);
    // 输出生成文件的信息及用时
    System.out.println("Generate " + outPutFile + " with " + (System.currentTimeMillis() - startTime) + " ms.");
}

        该方法功能实现:

  • .doc 格式的 Word 文档转换为 HTML 文件。
  • 提取并保存文档中的图片到指定路径,并在 HTML 中插入图片引用。
  • 处理分页符,将分页符(\f)替换为自定义的 HTML 标记。
  • 格式化生成的 HTML 文件,便于阅读和使用。

到此这篇关于关于java实现word(docx、doc)转html的解决方案的文章就介绍到这了,更多相关java word转html内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • SpringBoot使用Swagger生成多模块的API文档

    SpringBoot使用Swagger生成多模块的API文档

    这篇文章将以 Spring Boot 多模块项目为例,为大家详细介绍一下如何使用 Swagger 生成多模块的 API 文档,感兴趣的小伙伴可以了解一下
    2025-02-02
  • Mybatisplus主键生成策略算法解析

    Mybatisplus主键生成策略算法解析

    这篇文章主要介绍了Mybatisplus主键生成策略算法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-11-11
  • Java excel数据导入mysql的实现示例详解

    Java excel数据导入mysql的实现示例详解

    今天教大家如何使用Java将excel数据导入MySQL,文中有非常详细的代码示例,对正在学习java的小伙伴呢很有帮助,需要的朋友可以参考下
    2022-08-08
  • SpringBoot项目中忽略某属性返回数据给前端

    SpringBoot项目中忽略某属性返回数据给前端

    在Spring Boot中,保护敏感信息和减少数据传输是很重要的,我们可以使用多种方法来忽略返回数据中的字段,无论是使用@JsonIgnore注解、Projection投影、@JsonIgnoreProperties注解还是自定义序列化器,都能达到我们的目的,在实际应用中,根据具体场景和需求选择合适的方法
    2024-05-05
  • Java动态规划方式解决不同的二叉搜索树

    Java动态规划方式解决不同的二叉搜索树

    二叉搜索树作为一个经典的数据结构,具有链表的快速插入与删除的特点,同时查询效率也很优秀,所以应用十分广泛。本文将详细讲讲二叉搜索树的原理与实现,需要的可以参考一下
    2022-10-10
  • 一篇文章彻底弄懂Java中二叉树

    一篇文章彻底弄懂Java中二叉树

    二叉树是有限个节点的集合,这个集合可以是空集,也可以是一个根节点和两颗不相交的子二叉树组成的集合,其中一颗树叫根的左子树,另一颗树叫右子树,这篇文章主要给大家介绍了一篇文章如何彻底弄懂Java中二叉树的相关资料,需要的朋友可以参考下
    2022-01-01
  • Java自动添加重写的toString方法详解

    Java自动添加重写的toString方法详解

    在本篇文章里小编给大家整理了关于Java自动添加重写的toString方法总结,需要的朋友们学习下。
    2019-07-07
  • MyBatis-Plus主键生成策略的实现方法

    MyBatis-Plus主键生成策略的实现方法

    MyBatis-Plus提供了多种主键生成策略,包括自增、UUID、Redis和雪花算法,本文就来介绍一下,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-12-12
  • Java框架MyBatis接口编程过程解析

    Java框架MyBatis接口编程过程解析

    这篇文章主要介绍了Java框架MyBatis接口编程过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-02-02
  • java使用CompletableFuture分批处理任务实现

    java使用CompletableFuture分批处理任务实现

    本文主要介绍了java使用CompletableFuture分批处理任务实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-07-07

最新评论