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

前端實(shí)現(xiàn)將HTML轉(zhuǎn)成Word文檔的踩坑指南

 更新時(shí)間:2026年02月12日 08:37:19   作者:沈小鬧  
這篇文章主要為大家詳細(xì)介紹了前端實(shí)現(xiàn)將HTML轉(zhuǎn)成Word文檔的相關(guān)方法和避坑內(nèi)容,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

在項(xiàng)目中,我需要實(shí)現(xiàn)一個(gè)功能:將頁面渲染出來的 HTML 內(nèi)容導(dǎo)出為 Word 文檔(.docx)

看起來很簡單,但真正落地時(shí)踩了不少坑。這篇文章記錄一下從插件選擇到最終解決方案的全過程。

一、插件選型對(duì)比

html-docx-js

最早嘗試的是 html-docx-js。

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

  • 使用簡單
  • 直接將 HTML 字符串轉(zhuǎn)換成 Word

但是很快遇到了問題:

多層級(jí)有序列表在 WPS 中顯示異常

當(dāng) HTML 中存在:

<ol>
  <li>一級(jí)</li>
  <li>
    二級(jí)
    <ol>
      <li>子級(jí)</li>
    </ol>
  </li>
</ol>

Microsoft Word 中顯示正常,但在 WPS 中會(huì)出現(xiàn):

  • 序號(hào)錯(cuò)亂
  • 層級(jí)縮進(jìn)異常
  • 列表結(jié)構(gòu)被打亂

也就是說:

html-docx-js 在生成的 docx 結(jié)構(gòu)中,列表兼容性并不穩(wěn)定。

對(duì)于需要兼容 WPS 的場(chǎng)景來說,這是不可接受的。

html-to-docx / htmltodoc

后來嘗試 html-to-docx 這一類庫。

問題也很明顯:

不支持 canvas 圖片

如果頁面中有:

  • canvas 圖表
  • 圖形繪制
  • Echarts
  • GPT 可視化圖表

導(dǎo)出后:

圖片為空白

原因是:

  • 這些庫只識(shí)別 <img>
  • 不會(huì)處理 <canvas> 的內(nèi)容
  • 不會(huì)主動(dòng)把 canvas 轉(zhuǎn)成圖片

在圖表場(chǎng)景下,這幾乎無法使用。

最終選擇:docx

最后選擇了 docx(dolanmiu/docx)。

原因:

  • 底層生成真實(shí) docx 結(jié)構(gòu)
  • 可控性強(qiáng)
  • 可自定義 ImageRun / Paragraph
  • 兼容性更好

但同時(shí):自己要負(fù)責(zé) HTML → docx 的映射邏輯。

這也是后面踩坑的開始。

二、使用 docx 時(shí)踩到的坑

坑 1:canvas 圖片第一次導(dǎo)出是空白

現(xiàn)象:

  • 頁面中 canvas 渲染正常
  • 第一次導(dǎo)出 Word,圖片是空白
  • 第二次導(dǎo)出卻正常

原因

docx 需要的是:

Uint8Array(二進(jìn)制圖片數(shù)據(jù))

而 canvas:

  • 是繪圖上下文
  • 不是圖片資源
  • 如果在 clone 之后再去讀取,很可能上下文已經(jīng)丟失

尤其是:

element.cloneNode(true)

克隆出來的 canvas:不包含繪制內(nèi)容

正確做法

必須在克隆 HTML 之前:

  • 遍歷所有 canvas
  • 調(diào)用 canvas.toDataURL()
  • 緩存結(jié)果
  • 在 clone 后替換成 <img src="dataURL">

核心原則:

canvas 先轉(zhuǎn)圖片,再克隆 DOM。

坑 2:ImageRun 被嵌套在 Paragraph 中,圖片直接消失

這是最隱蔽、最坑的一個(gè)問題。

現(xiàn)象:

  • 圖片數(shù)據(jù)正確
  • 不跨域
  • 二進(jìn)制正常
  • 但導(dǎo)出 Word 后圖片消失
  • 有時(shí) Office Word 還會(huì)提示文件有問題

打印結(jié)構(gòu)后發(fā)現(xiàn):

Paragraph
  └─ Paragraph
       └─ ImageRun

也就是說:

ImageRun 外面包了兩層 Paragraph。

問題本質(zhì)

在 docx 結(jié)構(gòu)中:

  • Paragraph 是塊級(jí)元素
  • Paragraph 不能嵌套 Paragraph
  • ImageRun 必須直接存在于 Paragraph.children 中

非法結(jié)構(gòu)雖然可以被創(chuàng)建,但:

Word 會(huì)忽略或報(bào)結(jié)構(gòu)錯(cuò)誤。

正確結(jié)構(gòu)

new Paragraph({
  children: [
    new ImageRun(...)
  ]
})

而不是:

new Paragraph({
  children: [
    new Paragraph({
      children: [
        new ImageRun(...)
      ]
    })
  ]
})

坑 3:HTML 的結(jié)構(gòu) ≠ docx 的結(jié)構(gòu)

在 Markdown 渲染后,HTML 往往是這樣:

<div>
  <p>
    文字
    <img />
  </p>
</div>

但 docx 并不是 DOM 樹結(jié)構(gòu)。

docx 的正確模型更像是:

Section
 ├─ Paragraph
 ├─ Paragraph
 ├─ Paragraph

是一個(gè)扁平結(jié)構(gòu)。

因此正確做法是:

  • 文字 → 一個(gè) Paragraph
  • 圖片 → 一個(gè) Paragraph
  • 保持順序
  • 不強(qiáng)行還原 HTML 嵌套

例如:

<p>hello <img /> world</p>

應(yīng)轉(zhuǎn)換為:

Paragraph("hello")
Paragraph(Image)
Paragraph("world")

而不是試圖在一個(gè) Paragraph 里混排。

三、最終總結(jié)

在前端做 HTML → Word 導(dǎo)出時(shí),需要注意:

插件層面

  • html-docx-js:WPS 兼容性問題
  • html-to-docx:不支持 canvas
  • docx:可控但需要自己處理結(jié)構(gòu)

使用 docx 時(shí)必須注意

  • canvas 必須提前轉(zhuǎn)為圖片
  • 不要嵌套 Paragraph
  • ImageRun 必須直接在 Paragraph.children 中
  • 不要試圖 1:1 還原 HTML 結(jié)構(gòu)

四、核心經(jīng)驗(yàn)

Word 文檔不是瀏覽器。HTML 的語義嵌套不能直接映射到 docx。

當(dāng)你開始:

  • 把結(jié)構(gòu)扁平化
  • 圖片獨(dú)立成段
  • 主動(dòng)控制文檔結(jié)構(gòu)

問題就會(huì)變得清晰很多。

到此這篇關(guān)于前端實(shí)現(xiàn)將HTML轉(zhuǎn)成Word文檔的踩坑指南的文章就介紹到這了,更多相關(guān)前端HTML轉(zhuǎn)Word內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 利用 Chrome Dev Tools 進(jìn)行頁面性能分析的步驟說明(前端性能優(yōu)化)

    利用 Chrome Dev Tools 進(jìn)行頁面性能分析的步驟說明(前端性能優(yōu)化)

    這篇文章主要介紹了利用 Chrome Dev Tools 進(jìn)行頁面性能分析的步驟說明(前端性能優(yōu)化),本文給大家介紹的非常想詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-02-02
  • JavaScript中的isXX系列是否繼續(xù)使用的分析

    JavaScript中的isXX系列是否繼續(xù)使用的分析

    我們很容易被漂亮的代碼吸引,也不知不覺的在自己的代碼庫中加入這些。卻沒有冷靜的想過它們的優(yōu)劣。這不,我就收集了一系列形如 “是否為……?” 的判斷的boolean函數(shù)。
    2011-04-04
  • 用javascript編寫的第一人稱射擊游戲

    用javascript編寫的第一人稱射擊游戲

    用javascript編寫的第一人稱射擊游戲...
    2007-02-02
  • JS實(shí)現(xiàn)輪播圖小案例

    JS實(shí)現(xiàn)輪播圖小案例

    這篇文章主要為大家詳細(xì)介紹了JS實(shí)現(xiàn)輪播圖小案例,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • Angular中針對(duì)路由Routing原理刨析

    Angular中針對(duì)路由Routing原理刨析

    在Angular中,最好在一個(gè)頂級(jí)模塊中加載和配置路由,它專注于路由功能,然后由根模塊AppModule導(dǎo)入它,最后還有初始化并監(jiān)聽瀏覽器的地址變化
    2023-01-01
  • javascript實(shí)現(xiàn)仿百度圖片的瀑布流加載效果

    javascript實(shí)現(xiàn)仿百度圖片的瀑布流加載效果

    這是一款仿照百度圖片的瀑布流效果,可以無限加載,兼容各大主流瀏覽器,這里分享給大家,希望小伙伴們能夠喜歡
    2016-04-04
  • window resize和scroll事件的基本優(yōu)化思路

    window resize和scroll事件的基本優(yōu)化思路

    在項(xiàng)目中使用scroll事件去加載數(shù)據(jù),結(jié)果IE下悲劇了。下面為大家介紹下window resize和scroll事件的基本優(yōu)化思路,需要的朋友可以參考下
    2014-04-04
  • Javascript函數(shù)式編程語言

    Javascript函數(shù)式編程語言

    JavaScript 是近年來非常受矚目的一門編程語言,它既支持面向?qū)ο缶幊蹋仓С趾瘮?shù)式編程。本文專門介紹JavaScript函數(shù)式編程的特性。
    2015-10-10
  • 前端JS實(shí)現(xiàn)瀏覽器跨標(biāo)簽頁數(shù)據(jù)共享的五大方案

    前端JS實(shí)現(xiàn)瀏覽器跨標(biāo)簽頁數(shù)據(jù)共享的五大方案

    這篇文章主要為大家詳細(xì)介紹了五大常見的瀏覽器跨頁簽數(shù)據(jù)共享方案,包括它們的實(shí)現(xiàn)原理、優(yōu)缺點(diǎn)以及適用場(chǎng)景,有需要的小伙伴可以跟隨小編一起參考一下
    2026-02-02
  • 常見Ajax下載文件方式以及報(bào)錯(cuò)解決辦法

    常見Ajax下載文件方式以及報(bào)錯(cuò)解決辦法

    AJAX(Asynchronous JavaScript and XML)是一種用于創(chuàng)建快速、動(dòng)態(tài)和交互式網(wǎng)頁的技術(shù),它的主要優(yōu)勢(shì)在于能夠在不刷新整個(gè)網(wǎng)頁的情況下與服務(wù)器進(jìn)行數(shù)據(jù)交互,這篇文章主要給大家介紹了關(guān)于常見Ajax下載文件方式以及報(bào)錯(cuò)解決辦法的相關(guān)資料,需要的朋友可以參考下
    2024-01-01

最新評(píng)論

磴口县| 湘阴县| 福建省| 麻栗坡县| 奉节县| 枣强县| 泾源县| 彭水| 深泽县| 乌拉特中旗| 通渭县| 和田市| 佛山市| 新巴尔虎右旗| 慈利县| 许昌县| 墨江| 信阳市| 廊坊市| 翁牛特旗| 吉木萨尔县| 大港区| 谷城县| 横山县| 华亭县| 泗阳县| 湖南省| 鹿邑县| 潢川县| 仙游县| 凌海市| 辽阳县| 搜索| 乌兰浩特市| 兴山县| 册亨县| 米林县| 湘潭县| 厦门市| 肃宁县| 永城市|