最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

關(guān)于Java實(shí)現(xiàn)word(docx、doc)轉(zhuǎn)html的完美解決方案

 更新時(shí)間:2025年01月26日 10:32:25   作者:WAZYY0619  
文章介紹了多種將Word文檔轉(zhuǎn)換為HTML的方法,包括使用Microsoft Word自帶的導(dǎo)出功能、第三方工具和編程實(shí)現(xiàn),展示了如何實(shí)現(xiàn)將.docx文件轉(zhuǎn)換為HTML文件,并自動(dòng)生成目錄、處理分頁符和增強(qiáng)表格樣式等功能,感興趣的朋友一起看看吧

最近在研究一些關(guān)于文檔轉(zhuǎn)換格式的方法,因?yàn)樾枰迷陂_發(fā)的一個(gè)項(xiàng)目上,所以投入了一些時(shí)間,給大家聊下這塊邏輯及解決方案。

一、關(guān)于word轉(zhuǎn)換html大致都有哪些方法?

(1)使用 Microsoft Word 導(dǎo)出

        其實(shí)該方法就是使用word本身導(dǎo)出方案

操作步驟

  • 在 Microsoft Word 中打開文檔。
  • 點(diǎn)擊 文件 > 另存為 或 導(dǎo)出。
  • 選擇保存類型為 網(wǎng)頁(.html, .htm)。
  • 保存文件后,會(huì)生成一個(gè) HTML 文件(有時(shí)會(huì)附帶一個(gè)文件夾用于存放圖片等資源)。

優(yōu)點(diǎn)

  • 保留了文檔的大部分格式。
  • 操作簡單,無需其他工具。

缺點(diǎn)

  • 導(dǎo)出的 HTML 文件代碼較冗余,包含許多與 Word 相關(guān)的樣式和標(biāo)簽。

(2)使用第三方工具或在線轉(zhuǎn)換工具

        一般常見的有SmallPDF、Zamzar、Convertio、LibreOffice等在線工具或軟件進(jìn)行轉(zhuǎn)換

優(yōu)點(diǎn)

  • 方便快捷,適合大多數(shù)人使用。
  • 有些工具可以清理冗余代碼,生成更簡潔的 HTML。

缺點(diǎn)

  • 在線工具可能存在隱私和安全風(fēng)險(xiǎn)。
  • 某些工具可能無法完全保留復(fù)雜文檔的格式。

(3)使用編程實(shí)現(xiàn)自動(dòng)化轉(zhuǎn)換

常見的編程實(shí)現(xiàn)有:

  • Python
    • 使用 python-docx 庫讀取 .docx 文件,再用自定義邏輯生成 HTML。
    • 使用 mammoth 庫,專門將 .docx 轉(zhuǎn)為干凈的 HTML(推薦)。
    • 使用 pywin32 調(diào)用 Windows COM 接口操作 Microsoft Word。
  • Java
    • 使用 Apache POI 的 XWPF 模塊解析 .docx 文件并輸出 HTML。
  • Node.js
    • 使用 officegenmammoth.js 轉(zhuǎn)換 .docx 文件。
  • C#
    • 使用 OpenXML SDK 或 Interop.Word 來操作 Word 文件并轉(zhuǎn)換為 HTML。

        本此講解的就是通過java的poi內(nèi)的模塊進(jìn)行解析輸出html

二、docx轉(zhuǎn)換html

        示例代碼如下:

public static void docxtoHtml(String fileName, String outPutFile) throws TransformerException, IOException, ParserConfigurationException {
    long startTime = System.currentTimeMillis();
    XWPFDocument document = new XWPFDocument(new FileInputStream(fileName));
    // 用于存儲(chǔ)目錄內(nèi)容
    StringBuilder toc = new StringBuilder();
    toc.append("<div id='toc'>\n<ul>\n");  // 直接從 <ul> 開始,表示目錄
    // 遍歷文檔中的段落,查找目錄項(xiàng)
    List<XWPFParagraph> paragraphs = document.getParagraphs();
    int tocLevel = 0; // 目錄的當(dāng)前級(jí)別,1代表一級(jí)目錄,2代表二級(jí)目錄,3代表三級(jí)目錄
    boolean tocStarted = false; // 標(biāo)記目錄是否開始
    for (XWPFParagraph paragraph : paragraphs) {
        String style = paragraph.getStyle();  // 獲取段落樣式
        String text = paragraph.getText();  // 獲取段落文本
        // 根據(jù)段落的樣式級(jí)別來識(shí)別目錄項(xiàng),假設(shè)標(biāo)題樣式為 Heading 1, Heading 2, Heading 3
        if (style != null) {
            if (style.equals("Heading 1")) {  // 一級(jí)標(biāo)題
                if (tocStarted) {
                    toc.append("</ul>\n"); // 關(guān)閉上一級(jí)目錄
                }
                toc.append("<ul>\n");  // 開始一個(gè)新的無序列表
                toc.append("<li><a href='#" + text.hashCode() + "'>" + text + "</a></li>\n");
                tocLevel = 1;
                tocStarted = true;
            } else if (style.equals("Heading 2")) {  // 二級(jí)標(biāo)題
                if (tocLevel == 1) {
                    toc.append("<ul>\n");  // 開始二級(jí)目錄
                }
                toc.append("<li><a href='#" + text.hashCode() + "'>" + text + "</a></li>\n");
                tocLevel = 2;
            } else if (style.equals("Heading 3")) {  // 三級(jí)標(biāo)題
                if (tocLevel == 2) {
                    toc.append("<ul>\n");  // 開始三級(jí)目錄
                }
                toc.append("<li><a href='#" + text.hashCode() + "'>" + text + "</a></li>\n");
                tocLevel = 3;
            }
        }
        // 在目錄項(xiàng)前插入錨點(diǎn)
        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;  // 在目錄項(xiàng)文本前添加錨點(diǎn)
            // 更新段落中的文本
            for (XWPFRun run : paragraph.getRuns()) {
                run.setText(modifiedText, 0); // 更新段落內(nèi)容
            }
        }
    }
    // 如果目錄結(jié)束后,確保關(guān)閉所有的<ul>標(biāo)簽
    if (tocLevel > 0) {
        toc.append("</ul>\n");
    }
    toc.append("</ul>\n</div>\n");  // 關(guān)閉最外層的 <ul> 和 <div>
    // 設(shè)置XHTMLOptions
    XHTMLOptions options = XHTMLOptions.create().indent(4);
    File imageFolder = new File(tempPath);  // 圖片臨時(shí)文件夾路徑
    options.setExtractor(new FileImageExtractor(imageFolder));
    options.URIResolver(new FileURIResolver(imageFolder));
    // 使用 `XHTMLConverter` 進(jìn)行 DOCX 到 HTML 的轉(zhuǎn)換
    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
    XHTMLConverter.getInstance().convert(document, byteArrayOutputStream, options);
    System.out.println("Generate " + outPutFile + " with " + (System.currentTimeMillis() - startTime) + " ms.");
    // 獲取轉(zhuǎn)換后的HTML內(nèi)容
    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" + // 去掉默認(rèn)的列表樣式
                   "li { margin: 5px 0; }\n" + // 設(shè)置目錄項(xiàng)的間距
                   "</style>\n";
    htmlContent = style + htmlContent;
    // 將最終的HTML內(nèi)容寫入文件
    writeFile(htmlContent, outPutFile);
}

        該方法功能實(shí)現(xiàn):

  • .docx 文件轉(zhuǎn)換為 HTML 文件。
  • 自動(dòng)生成基于文檔標(biāo)題的目錄 (TOC)。
  • 為標(biāo)題添加錨點(diǎn)鏈接,支持 HTML 頁面內(nèi)跳轉(zhuǎn)。
  • 處理分頁符,將其轉(zhuǎn)換為 HTML 的 <div> 元素。
  • 增強(qiáng)表格樣式,添加邊框和對(duì)齊(有時(shí)原表格css樣式轉(zhuǎn)換后會(huì)被覆蓋掉)。
  • 為 HTML 頁面添加全局 CSS 樣式,保證視覺效果統(tǒng)一。

三、doc轉(zhuǎn)換html

        示例代碼如下:

public static void doctoHtml(String fileName, String outPutFile) throws TransformerException, IOException, ParserConfigurationException {
    // 開始計(jì)時(shí)
    long startTime = System.currentTimeMillis();
    // 讀取 Word 文檔
    HWPFDocument wordDocument = new HWPFDocument(new FileInputStream(fileName));
    // 創(chuàng)建 Word 轉(zhuǎn) HTML 轉(zhuǎn)換器
    WordToHtmlConverter wordToHtmlConverter = new WordToHtmlConverter(DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument());
    // 圖片保存路徑設(shè)置
    String imageFolderPath = tempPath + "images" + File.separator;  // 存儲(chǔ)圖片的絕對(duì)路徑
    // 設(shè)置圖片管理器,處理圖片保存邏輯
    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(); // 創(chuàng)建圖片文件夾
                if (created) {
                    System.out.println("在以下位置創(chuàng)建圖片文件夾:" + imageFolder.getAbsolutePath());
                } else {
                    System.out.println("創(chuàng)建圖片文件夾失敗");
                }
            }
            try {
                File pictureFile = new File(picturePath);
                try (FileOutputStream fos = new FileOutputStream(pictureFile)) {
                    fos.write(content);  // 寫入圖片數(shù)據(jù)
                    System.out.println("圖片保存路徑" + pictureFile.getAbsolutePath());
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            return picturePath;  // 返回圖片路徑
        }
    });
    // 處理文檔內(nèi)容,轉(zhuǎn)換為 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> 節(jié)點(diǎn)
        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)
                    // 創(chuàng)建自定義分頁符 HTML 元素
                    Element pageBreak = htmlDocument.createElement("div");
                    pageBreak.setAttribute("class", "page-break");  // 設(shè)置 class 屬性,方便樣式控制
                    pageBreak.appendChild(htmlDocument.createTextNode(" "));
                    // 在分頁符前插入自定義分頁符標(biāo)記
                    bodyNode.insertBefore(pageBreak, paragraph);
                }
            }
        }
    }
    // 將 HTML 文檔輸出為字節(jié)流
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    DOMSource domSource = new DOMSource(htmlDocument);
    StreamResult streamResult = new StreamResult(out);
    // 使用 Transformer 進(jìn)行 HTML 格式化輸出
    TransformerFactory tf = TransformerFactory.newInstance();
    Transformer serializer = tf.newTransformer();
    serializer.setOutputProperty(OutputKeys.ENCODING, "utf-8");  // 設(shè)置編碼為 UTF-8
    serializer.setOutputProperty(OutputKeys.INDENT, "yes");  // 格式化輸出
    serializer.setOutputProperty(OutputKeys.METHOD, "html");  // 輸出格式為 HTML
    serializer.transform(domSource, streamResult);
    out.close();
    // 將字節(jié)流轉(zhuǎn)換為字符串
    String htmlContent = new String(out.toByteArray());
    // 處理特殊標(biāo)記符,例如去掉目錄標(biāo)記(根據(jù)需要調(diào)整)
    htmlContent = htmlContent.replaceAll("TOC \\\\o \"1-3\" \\\\h \\\\z \\\\u", "");
    // 將生成的 HTML 內(nèi)容寫入文件
    writeFile(htmlContent, outPutFile);
    // 輸出生成文件的信息及用時(shí)
    System.out.println("Generate " + outPutFile + " with " + (System.currentTimeMillis() - startTime) + " ms.");
}

        該方法功能實(shí)現(xiàn):

  • .doc 格式的 Word 文檔轉(zhuǎn)換為 HTML 文件。
  • 提取并保存文檔中的圖片到指定路徑,并在 HTML 中插入圖片引用。
  • 處理分頁符,將分頁符(\f)替換為自定義的 HTML 標(biāo)記。
  • 格式化生成的 HTML 文件,便于閱讀和使用。

到此這篇關(guān)于關(guān)于java實(shí)現(xiàn)word(docx、doc)轉(zhuǎn)html的解決方案的文章就介紹到這了,更多相關(guān)java word轉(zhuǎn)html內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java連接Linux服務(wù)器過程分析(附代碼)

    Java連接Linux服務(wù)器過程分析(附代碼)

    這篇文章主要介紹了Java連接Linux服務(wù)器過程分析(附代碼),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-12-12
  • springboot2.0使用Hikari連接池的方法(替換druid)

    springboot2.0使用Hikari連接池的方法(替換druid)

    這篇文章主要介紹了springboot 2.0使用Hikari連接池的方法(替換druid),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12
  • Springboot怎么解決循環(huán)依賴(基于單例 Bean)

    Springboot怎么解決循環(huán)依賴(基于單例 Bean)

    循環(huán)依賴指兩個(gè)或多個(gè) Bean 之間相互依賴,導(dǎo)致在創(chuàng)建 Bean 的過程中出現(xiàn)“死循環(huán)”,增加了對(duì)象依賴的混亂性,依賴關(guān)系變得錯(cuò)綜復(fù)雜,下面給大家介紹Springboot怎么解決循環(huán)依賴,感興趣的朋友一起看看吧
    2025-05-05
  • Java集合的組內(nèi)平均值的計(jì)算方法總結(jié)

    Java集合的組內(nèi)平均值的計(jì)算方法總結(jié)

    在Java中,經(jīng)常需要對(duì)集合進(jìn)行各種操作,其中之一就是計(jì)算集合的組內(nèi)平均值,本文將介紹如何使用Java集合來計(jì)算組內(nèi)平均值,并提供一些示例代碼和實(shí)用技巧
    2024-08-08
  • java開啟遠(yuǎn)程debug竟有兩種參數(shù)(最新推薦)

    java開啟遠(yuǎn)程debug竟有兩種參數(shù)(最新推薦)

    這篇文章主要介紹了java開啟遠(yuǎn)程debug竟有兩種參數(shù),本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-07-07
  • mybatis中string和date的轉(zhuǎn)換方式

    mybatis中string和date的轉(zhuǎn)換方式

    這篇文章主要介紹了mybatis中string和date的轉(zhuǎn)換方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • Java實(shí)現(xiàn)給PDF文件增加背景圖的操作指南

    Java實(shí)現(xiàn)給PDF文件增加背景圖的操作指南

    本文介紹了如何在Java中生成PDF文件并為其添加背景圖,通過兩種不同的方式實(shí)現(xiàn):一種使用了iText庫,另一種使用了PdfBox庫,這兩種方法都可以實(shí)現(xiàn)將背景圖片添加到PDF文件中,并且可以根據(jù)項(xiàng)目需求選擇合適的方法,需要的朋友可以參考下
    2025-11-11
  • SpringBoot整合LocalDateTime的過程

    SpringBoot整合LocalDateTime的過程

    LocalDateTime 和 Date 是 Java 中處理日期和時(shí)間的兩種不同的類,在 JDK8 中引入了 java.time 包,這篇文章主要介紹了SpringBoot整合LocalDateTime的過程,需要的朋友可以參考下
    2024-08-08
  • Java基于遞歸解決全排列問題算法示例

    Java基于遞歸解決全排列問題算法示例

    這篇文章主要介紹了Java基于遞歸解決全排列問題算法,結(jié)合實(shí)例形式分析了Java使用遞歸算法解決全排列問題的原理與具體實(shí)現(xiàn)技巧,需要的朋友可以參考下
    2017-11-11
  • 詳解java關(guān)于對(duì)象的比較

    詳解java關(guān)于對(duì)象的比較

    這篇文章主要為大家介紹了java關(guān)于對(duì)象的比較,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-01-01

最新評(píng)論

兰坪| 雅江县| 衡山县| 兴和县| 南宁市| 新密市| 博兴县| 五常市| 金山区| 金湖县| 榆中县| 竹北市| 辉南县| 绥棱县| 金乡县| 安福县| 天津市| 晋江市| 石台县| 兴城市| 阜阳市| 伊春市| 大田县| 保德县| 玉门市| 襄城县| 鱼台县| 黄骅市| 寿宁县| 射洪县| 佛学| 福建省| 遂宁市| 隆德县| 土默特左旗| 滦南县| 格尔木市| 隆德县| 镇巴县| 天祝| 高唐县|