Java处理doc类型的Word文档转换成html(按顺序保留格式+图片)

最新有个新需求,就是doc文档转换html内容倒不是很难,给大家分享一下,总体思路就是按doc转html的思路来走,唯一缺点是不会自动转换图片,图片是要手动转成base64,默认是有html、body、head、meta等等标签,我这里都用正则处理掉了。

需要注意的是:

.docx 格式的 Word 文档是一种基于 XML 和 ZIP 压缩技术的文件格式,其文件结构相对固定并且较为简单,可以通过一些开源的 JavaScript 库进行解析和转换(推荐使用mammoth.js在前端即可完成Word转换html的操作,但是目前的mammoth版本只支持docx,后续可能会支持解析doc的功能)。
·
.doc 格式的 Word 文档是一种相对来说版本比较老一点并且是二进制格式的文件,文件结构比较复杂,具有较高的私有性和细节,需要专用微软 Office 应用程序才能完整读取,所以一般如果要对doc文档进行转换内容时,最好是使用java处理,比较容易一些。

具体引用jar包如下,一共6个:
1、poi-4.1.2.jar
2、poi-ooxml-4.1.2.jar
3、poi-scratchpad-4.1.2.jar

poi的版本必须一致,不然会有问题,一般情况下如果用到poi互相依赖,最好是要做到poi版本一致,不仅针对这个转换html中,其他地方也是一样。

4、fr.opensagres.poi.xwpf.converter.xhtml-2.0.2.jar
5、commons-math3-3.6.1.jar
6、commons-collections4-4.4.jar

jar包下载如果本地没有可以去中央仓库下载,直接搜索就行,比较方便,有pom也有jar

在这里插入图片描述

总体流程和思路:

1、创建 File 对象,将要转换的 Word 文档的路径传入文件对象中。

2、使用 FileInputStream 对象读取 Word 文档文件。

3、构建 HWPFDocument 对象,该对象是 Apache POI 库中的类,用于读取 .doc 格式的 Word 文档。

4、构建 WordToHtmlConverter 对象,并将 DocumentBuilderFactory、DocumentBuilder 和 Document 对象传递给构造函数。

5、解析 Word 文档并将解析结果存储到 Document 对象中。

6、创建 Transformer 对象,用于将 Document 对象转换为 HTML 格式,并设置输出格式、字符编码等。

7、使用 DOMSource 对象将 Document 对象中的内容提供给 Transformer 对象。

8、创建 ByteArrayOutputStream 对象,并将结果存储到该流中。

9、使用 StreamResult 指定输出流,将转换后的结果写入到 ByteArrayOutputStream 中。

10、将 ByteArrayOutputStream 对象转换为字符串并输出。

需要注意的是,此示例中使用的是 HWPFDocument 类,而不是 XWPFDocument 类
这意味着该示例只能处理 .doc 格式的 Word 文档。如果需要处理 .docx 格式的 Word 文档,则需要使用 XWPFDocument 类。

java代码如下:

import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.usermodel.Picture;
import org.apache.poi.hwpf.converter.WordToHtmlConverter;
import org.w3c.dom.Document;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

public class DocToHtml {

    /**
     * 传递文件路径
     * @param filePath 文件路径
     * @return 返回html标签
     */
    public static String inputDocPath(String filePath) {
        File file = new File(filePath);
        try {
            FileInputStream inputStream = new FileInputStream(file);
            HWPFDocument hwpfDocument = new HWPFDocument(inputStream);

            // 提取图像数据并转换为 BASE64 编码字符串
            List<Picture> pictures = hwpfDocument.getPicturesTable().getAllPictures();
            List<String> base64ImageStrings = new ArrayList<>();
            for (Picture picture : pictures) {
                byte[] imageData = picture.getContent();
                String base64ImageString = "data:image/png;base64," + Base64.getEncoder().encodeToString(imageData);
                base64ImageStrings.add(base64ImageString);
            }

            // 转换为 HTML 文本
            WordToHtmlConverter wordToHtmlConverter = new WordToHtmlConverter(DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument());
            wordToHtmlConverter.processDocument(hwpfDocument);
            Document document = wordToHtmlConverter.getDocument();
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            Transformer transformer = TransformerFactory.newInstance().newTransformer();
            transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
            transformer.setOutputProperty(OutputKeys.INDENT, "yes");
            transformer.setOutputProperty(OutputKeys.METHOD, "html");
            transformer.transform(new DOMSource(document), new StreamResult(outputStream));
            String html = outputStream.toString("UTF-8");

            //查找所有图片
            List<String> matches = findMatchesToPic(html);

            //查找无用标签并替换成空,用自己写入的标签
            html = findMatchesToLable(html);
            // 在 HTML 中插入图像
            // 替换图片链接为 base64 编码
            for (int i = 0; i < base64ImageStrings.size(); i++) {
                html = html.replace(matches.get(i), "<img src=\"" + base64ImageStrings.get(i) + "\">");
            }

            return html;

        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    //查找所有图片集合
    private static List<String> findMatchesToPic(String input) {
        List<String> matches = new ArrayList<>();
        Pattern pattern = Pattern.compile("<!--.*?-->");
        Matcher matcher = pattern.matcher(input);
        while (matcher.find()) {
            String match = matcher.group();
            matches.add(match);
        }
        return matches;
    }

    //查找没用的标签,并替换
    private static String findMatchesToLable(String html) {
        Pattern pattern = Pattern.compile("<META.*?>", Pattern.DOTALL);
        Matcher matcher = pattern.matcher(html);
        if (matcher.find()) {
            html = html.replace(matcher.group(), "");
        }

        Pattern patternMeta = Pattern.compile("<meta.*?>", Pattern.DOTALL);
        Matcher matcherMeta = patternMeta.matcher(html);
        if (matcherMeta.find()) {
            html = html.replace(matcherMeta.group(), "");
        }

        Pattern patternBody = Pattern.compile("<body.*?>", Pattern.DOTALL);
        Matcher matcherBody = patternBody.matcher(html);
        if (matcherBody.find()) {
            html = html.replace(matcherBody.group(), "");
        }

        Pattern patternStyle = Pattern.compile("<style.*?</style>", Pattern.DOTALL);
        Matcher matcherStyle = patternStyle.matcher(html);
        if (matcherStyle.find()) {
            html = html.replace(matcherStyle.group(), "");
        }

        html = html.replace("<html>", "");
        html = html.replace("<head>", "");
        html = html.replace("</head>", "");
        html = html.replace("</body>", "");
        html = html.replace("</html>", "");

        return html;
    }


}

将Word文档转换为HTML有许多方法,其中基于Apache POI和HSSF的方式就是其中一种。

优点:

1、准确度高:使用java的Apache POI和HSSF,可以更准确地提取一份 Microsoft Word
·
2、文档的内容。这种方式的特点是能够完美保留 Word 文档的大部分格式,包括样式、标题、字体、表格、图像等等。
·
3、可定制性强:将 Word 文档转换为 HTML 可以实现高度的可定制化,特别是针对文字内容的处理。使用此方法,开发人员可以从文档中提取仅所需的部分,并将其转换为 HTML。
·
4、应用场景广泛:可以将 Word 文档转换为 HTML 以便于在线发布、在线查看或轻松共享。

缺点:

1、格式兼容性问题:某些 Word 版本中的内容无法精确保留,因为 Apache POIC 的一些功能可能在某些版本的 Word 中不支持。
·
2、转换时间长:对于大型文件来说,这种转换可能需要花费更长的时间以完成其处理。较大的文档可能会导致性能问题,并且需要更多的计算资源来完成其转换。

总之,将 Word 文档转换为 HTML 有其一些优点和缺点。 这种转换方法是一种可行的方式,但在处理一些格式或较大的文档方面可能存在局限性或成本问题。如果对文档的格式和内容要求较高,建议考虑使用高级的第三方工具或者云服务来处理。