一鍵將Word文檔轉(zhuǎn)成Vue組件mammoth的應(yīng)用詳解
正文
在開(kāi)發(fā)后臺(tái)管理系統(tǒng)的過(guò)程中,經(jīng)常有這樣的需求:將 Word 文檔(比如用戶(hù)協(xié)議文檔)轉(zhuǎn)換為 HTML 頁(yè)面(Vue 組件)。轉(zhuǎn)換 Word 文檔過(guò)程通常是枯燥的。開(kāi)源社區(qū)的 mammoth.js 正好可以解壓 .docx,并解析 XML 結(jié)構(gòu),最終將 Word 轉(zhuǎn)成 HTML 文件。因此可以基于該開(kāi)源庫(kù)開(kāi)發(fā)「Word 文檔轉(zhuǎn) Vue 組件」工具,讓轉(zhuǎn)換流程自動(dòng)化,從而有效提升了工作效率。本文介紹該工具的實(shí)現(xiàn)原理。
mammoth.js 的不足
mammoth.js 雖然可以直接生成 HTML 文件,但是使用過(guò)程還是遇到不少問(wèn)題。比如下圖所示的 Word 文檔:
經(jīng)過(guò) mammoth.js 轉(zhuǎn)換后的頁(yè)面卻是這個(gè)樣子:
從上圖我們可以發(fā)現(xiàn)以下幾個(gè)問(wèn)題:
- 標(biāo)題欄不居中
- 本來(lái)是 Word 中的排序,卻只是
<li></li>
默認(rèn)樣式 1 2 3 - 跟現(xiàn)有的協(xié)議規(guī)范樣式不匹配
- 超鏈接沒(méi)有交互
- Table 表單不符合預(yù)期
改造
因此有必要通過(guò)對(duì) mammoth 進(jìn)行定制來(lái)滿足當(dāng)前項(xiàng)目的需求。mammoth 提供了方法可以獲取轉(zhuǎn)換后的 AST 節(jié)點(diǎn),那我們就利用這個(gè)方法,對(duì) AST 進(jìn)行轉(zhuǎn)換,最后生成一份可用的 Vue 文件。整個(gè)流程如下圖所示:
解析 AST
首先先獲取 AST。
var options = { transformDocument: transformElement, }; mammoth.convertToHtml({ path }, options).done(async () => { // Word處理完畢 });
AST 節(jié)點(diǎn)
每個(gè)節(jié)點(diǎn)都會(huì)標(biāo)明 type 類(lèi)型、是否居中、字號(hào)大小、是否粗體、是否斜體、是否有下劃線等。
type 類(lèi)型如下所示:
Document 根節(jié)點(diǎn)
Paragraph 段落
- Text
- Run (這種情況,表示 mammoth 把一段話分成幾小部分,所以需要拼接 children 內(nèi)的 text 節(jié)點(diǎn)。)
- hyperlink
Table 表單
- tableRow
- tableCell
處理 AST 節(jié)點(diǎn)
在處理節(jié)點(diǎn)的過(guò)程中,有以下幾個(gè)注意事項(xiàng):
- Q: 何時(shí)換行?
A: 經(jīng)觀察,type: 'paragraph', children: []
的時(shí)候表示需要換行。
- Q: 哪些是正標(biāo)題、副標(biāo)題
A: 在我們項(xiàng)目中,把居中且字號(hào) 16 的文本定義為正標(biāo)題,居中且字號(hào) 14 的文本定義為副標(biāo)題。
- Q: 段落首行縮進(jìn)
A: 這點(diǎn)需要手動(dòng)處理,默認(rèn)增加 4 個(gè)縮進(jìn)
。
- Q: 如何處理粗體、字號(hào)、空格、超鏈接?
A: 粗體、字號(hào)生成公共的 class,比如'bold' 'font-size-14' 'font-size-16'
;空格需要將\s
替換為
;對(duì)于 type === 'hyperlink'的超鏈接,轉(zhuǎn)成<a target="_blank" class="blue" href="${txt.href}">${txt.children[0].value}</a>
。
- Q: Word 文檔中排序是如何轉(zhuǎn)換的?
A: 用 node 節(jié)點(diǎn)中的numbering
字段來(lái)判斷,需要排序則numbering
有值;不需要排序則numbering: null
; 維護(hù)一個(gè)公共變量保存排序數(shù)值,再將英文數(shù)字 1 2 3 等 轉(zhuǎn)換為中文一、二、三等。
- Q: Table 樣式如何處理?
A: 在該節(jié)點(diǎn)中,第一個(gè)元素為thead
標(biāo)簽,后續(xù)元素為tbody
標(biāo)簽;tbody 中的children
節(jié)點(diǎn)是由type: paragraph
節(jié)點(diǎn)構(gòu)成,可以handleParagraph
遞歸處理。
下面的代碼展示了處理段落、表單的邏輯。
function transformElement(element) { // 根節(jié)點(diǎn) const document = element.children; if (Array.isArray(document)) { document.forEach((ele) => { switch (ele.type) { case 'paragraph': str += handleParagraph(ele); break; case 'table': handleTable(ele); break; default: break; } }); } return element; }
代碼格式化與生成
首先將字符串拼接成為 Vue 組件源碼。
const originalStr = `<template> ... </template> <script> // ... </script> <style lang="less" scoped> // ... </style>\n`;
每次給組件起名字也挺煩的,所以可以使用 translate-shell 就根據(jù)協(xié)議文檔的中文名稱(chēng),進(jìn)行翻譯得出。
// 讀取word路徑名,并進(jìn)行翻譯,自動(dòng)生成template name和文件名 function getTranslatedNames(path) { return new Promise((resolve) => { const chArr = path.replace('.docx', '').split('/'); exec( `trans -t english '${chArr[chArr.length - 1]}'`, (error, stdout, stderr) => { const arr = stdout.split('\n'); // ... resolve(target.replace(/[^a-zA-Z-]/gi, '')); }, ); }); }
至此我們已經(jīng)得到符合項(xiàng)目需求的代碼,文件名稱(chēng)也有了,現(xiàn)在只需要將代碼內(nèi)容格式化寫(xiě)入文件就完成了。
// 格式化 const finalStr = prettier.format(originalStr, config); fs.writeFileSync(`${templateName}.vue`, finalStr, 'utf-8');
最終的效果如下圖所示:
總結(jié)
簡(jiǎn)而言之,這個(gè)工具站在了 mammoth 的肩膀上,利用 AST 節(jié)點(diǎn),再根據(jù) UI 稿相應(yīng)地做不同轉(zhuǎn)換。生成符合規(guī)范的代碼后,再拼接成 vue 組件,寫(xiě)入項(xiàng)目中。mammoth 處理 Word 文檔還是非常方便的,推薦使用。
以上就是一鍵將Word文檔轉(zhuǎn)成Vue組件mammoth的應(yīng)用詳解的詳細(xì)內(nèi)容,更多關(guān)于Word轉(zhuǎn)成Vue組件mammoth的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- vue在線預(yù)覽word、excel、pdf、txt、圖片的方法實(shí)例
- vue實(shí)現(xiàn)導(dǎo)出word文檔功能實(shí)例(含多張圖片)
- vue+elementUI實(shí)現(xiàn)多文件上傳與預(yù)覽功能實(shí)戰(zhàn)記錄(word/PDF/圖片/docx/doc/xlxs/txt)
- Vue中如何實(shí)現(xiàn)在線預(yù)覽word文件、excel文件
- vue實(shí)現(xiàn)導(dǎo)出Word文件(數(shù)據(jù)流方式)
- vue預(yù)覽 pdf、word、xls、ppt、txt文件的實(shí)現(xiàn)方法
相關(guān)文章
使用ElementUI寫(xiě)一個(gè)前端分頁(yè)查詢(xún)的實(shí)例
本文主要介紹了使用ElementUI寫(xiě)一個(gè)前端分頁(yè)查詢(xún)的實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-02-02vue之帶參數(shù)跳轉(zhuǎn)打開(kāi)新頁(yè)面、新窗口
這篇文章主要介紹了vue之帶參數(shù)跳轉(zhuǎn)打開(kāi)新頁(yè)面、新窗口方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-04-04vue+SSM實(shí)現(xiàn)驗(yàn)證碼功能
這篇文章主要介紹了vue+SSM實(shí)現(xiàn)驗(yàn)證碼功能,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-12-12vue項(xiàng)目中添加electron的詳細(xì)代碼
這篇文章通過(guò)實(shí)例代碼給大家介紹了vue項(xiàng)目中添加electron的方法,代碼簡(jiǎn)單易懂,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2021-11-11Vue3嵌套路由中使用keep-alive緩存多層的實(shí)現(xiàn)
本文介紹了Vue3 嵌套路由中使用?keep-alive緩存多層的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-04-04vue修改swiper框架輪播圖小圓點(diǎn)的樣式不起作用的解決
這篇文章主要介紹了vue修改swiper框架輪播圖小圓點(diǎn)的樣式不起作用的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-04-04element ui table(表格)實(shí)現(xiàn)點(diǎn)擊一行展開(kāi)功能
這篇文章主要給大家介紹了關(guān)于element ui table(表格)實(shí)現(xiàn)點(diǎn)擊一行展開(kāi)功能的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2018-12-12