一鍵將Word文檔轉成Vue組件mammoth的應用詳解
正文
在開發(fā)后臺管理系統(tǒng)的過程中,經(jīng)常有這樣的需求:將 Word 文檔(比如用戶協(xié)議文檔)轉換為 HTML 頁面(Vue 組件)。轉換 Word 文檔過程通常是枯燥的。開源社區(qū)的 mammoth.js 正好可以解壓 .docx,并解析 XML 結構,最終將 Word 轉成 HTML 文件。因此可以基于該開源庫開發(fā)「Word 文檔轉 Vue 組件」工具,讓轉換流程自動化,從而有效提升了工作效率。本文介紹該工具的實現(xiàn)原理。
mammoth.js 的不足
mammoth.js 雖然可以直接生成 HTML 文件,但是使用過程還是遇到不少問題。比如下圖所示的 Word 文檔:
經(jīng)過 mammoth.js 轉換后的頁面卻是這個樣子:
從上圖我們可以發(fā)現(xiàn)以下幾個問題:
- 標題欄不居中
- 本來是 Word 中的排序,卻只是
<li></li>
默認樣式 1 2 3 - 跟現(xiàn)有的協(xié)議規(guī)范樣式不匹配
- 超鏈接沒有交互
- Table 表單不符合預期
改造
因此有必要通過對 mammoth 進行定制來滿足當前項目的需求。mammoth 提供了方法可以獲取轉換后的 AST 節(jié)點,那我們就利用這個方法,對 AST 進行轉換,最后生成一份可用的 Vue 文件。整個流程如下圖所示:
解析 AST
首先先獲取 AST。
var options = { transformDocument: transformElement, }; mammoth.convertToHtml({ path }, options).done(async () => { // Word處理完畢 });
AST 節(jié)點
每個節(jié)點都會標明 type 類型、是否居中、字號大小、是否粗體、是否斜體、是否有下劃線等。
type 類型如下所示:
Document 根節(jié)點
Paragraph 段落
- Text
- Run (這種情況,表示 mammoth 把一段話分成幾小部分,所以需要拼接 children 內(nèi)的 text 節(jié)點。)
- hyperlink
Table 表單
- tableRow
- tableCell
處理 AST 節(jié)點
在處理節(jié)點的過程中,有以下幾個注意事項:
- Q: 何時換行?
A: 經(jīng)觀察,type: 'paragraph', children: []
的時候表示需要換行。
- Q: 哪些是正標題、副標題
A: 在我們項目中,把居中且字號 16 的文本定義為正標題,居中且字號 14 的文本定義為副標題。
- Q: 段落首行縮進
A: 這點需要手動處理,默認增加 4 個縮進
。
- Q: 如何處理粗體、字號、空格、超鏈接?
A: 粗體、字號生成公共的 class,比如'bold' 'font-size-14' 'font-size-16'
;空格需要將\s
替換為
;對于 type === 'hyperlink'的超鏈接,轉成<a target="_blank" class="blue" href="${txt.href}">${txt.children[0].value}</a>
。
- Q: Word 文檔中排序是如何轉換的?
A: 用 node 節(jié)點中的numbering
字段來判斷,需要排序則numbering
有值;不需要排序則numbering: null
; 維護一個公共變量保存排序數(shù)值,再將英文數(shù)字 1 2 3 等 轉換為中文一、二、三等。
- Q: Table 樣式如何處理?
A: 在該節(jié)點中,第一個元素為thead
標簽,后續(xù)元素為tbody
標簽;tbody 中的children
節(jié)點是由type: paragraph
節(jié)點構成,可以handleParagraph
遞歸處理。
下面的代碼展示了處理段落、表單的邏輯。
function transformElement(element) { // 根節(jié)點 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é)議文檔的中文名稱,進行翻譯得出。
// 讀取word路徑名,并進行翻譯,自動生成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àn)在只需要將代碼內(nèi)容格式化寫入文件就完成了。
// 格式化 const finalStr = prettier.format(originalStr, config); fs.writeFileSync(`${templateName}.vue`, finalStr, 'utf-8');
最終的效果如下圖所示:
總結
簡而言之,這個工具站在了 mammoth 的肩膀上,利用 AST 節(jié)點,再根據(jù) UI 稿相應地做不同轉換。生成符合規(guī)范的代碼后,再拼接成 vue 組件,寫入項目中。mammoth 處理 Word 文檔還是非常方便的,推薦使用。
以上就是一鍵將Word文檔轉成Vue組件mammoth的應用詳解的詳細內(nèi)容,更多關于Word轉成Vue組件mammoth的資料請關注腳本之家其它相關文章!
相關文章
Vue3嵌套路由中使用keep-alive緩存多層的實現(xiàn)
本文介紹了Vue3 嵌套路由中使用?keep-alive緩存多層的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2023-04-04element ui table(表格)實現(xiàn)點擊一行展開功能
這篇文章主要給大家介紹了關于element ui table(表格)實現(xiàn)點擊一行展開功能的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2018-12-12