一. 組件介紹
要實現前端純js導出word文檔,我們需要用到docxtemplater,jszip-utils,file-saver三個組件,接下來簡要的介紹以下三個組件。
1、docxtemplater
介紹
docxtemplater是一種郵件合並工具,它以編程方式使用,處理條件、循環,並且可以擴展為表格、HTML、圖像等。
參考鏈接:https://docxtemplater.readthedocs.io/en/latest/index.html
用到的API
- new window.docxtemplater:
創建docxtemplater實例對象,返回一個新的docxtemplater對象 - loadZip(zip):
docxtemplater對象加載zip實例
注意:必須從jszip的2.x版本向該方法傳遞一個zip實例 - setData(Tags):
設置模板變量的值 - render():
此函數用模板變量的值替換所有模板變量 - getZip():
此函數返回代表docxtemplater對象的zip
2、jszip-utils
介紹
jszip-utils是與jszip一起使用的跨瀏覽器的工具庫
參考鏈接:https://stuk.github.io/jszip-utils/
用到的API
- getBinaryContent():
讀取並獲得模板文件的二進制內容
3、jszip
介紹
jszip是一個用於創建、讀取和編輯.zip文件的JavaScript庫,且API的使用也很簡單。
參考鏈接:https://stuk.github.io/jszip/
用到的API
- new JSZip():
創建一個JSZip實例 - generate():
此函數可以生成一個zip文件(不是一個真實的文件,而是在內存中的表示)
4、FileSaver
介紹
FileSaver.js 是在客戶端保存文件的解決方案,非常適合需要生成文件,或者保存不應該發送到外部服務器的敏感信息的應用。
參考鏈接:
https://www.cnblogs.com/yunser/p/7629399.html
https://www.npmjs.com/package/file-saver
用到的API
- saveAs(blob, "1.docx"):
將目標文件對象保存為目標類型的文件,並命名
二. 操作步驟
2.1 安裝
接下來就是安裝以上組件工具,安裝命令如下
-- 安裝 docxtemplater cnpm install docxtemplater pizzip --save -- 安裝 jszip-utils cnpm install jszip-utils --save -- 安裝 jszip cnpm install jszip --save -- 安裝 FileSaver cnpm install file-saver --save 沒有cnpm可以使用npm
2.2 引入
在需要用到的組件中引入以上工具
import docxtemplater from 'docxtemplater' import PizZip from 'pizzip' import JSZipUtils from 'jszip-utils' import {saveAs} from 'file-saver'
2.3 創建模板文件
我們要先創建一個模板文件,事先定義好格式和內容。docxtemplater 之前介紹到是通過標簽的形式來填充數據的,簡單的數據我們可以使用{} + 變量名來實現簡單的文本替換。
- 簡單的文本替換
如果在模板中,定義
hello {name}
在設置數據時,定義
{name:'John'}
最終生成的文件,如下
hello John
- 循環輸出
稍微復雜點的像表格,我們會傳遞一個數組。那這個表格標簽實現起來挺簡單的,例子如下:
模板文件定義:
{#products}
{name}, {price} €
{/products}
設置數據時,定義如下:
{ "products": [ { name :"Windows", price: 100}, { name :"Mac OSX", price: 200}, { name :"Ubuntu", price: 0} ] }
最終實現效果如下:
Windows, 100 € Mac OSX, 200 € Ubuntu, 0€
如果數組中的都是字符串,不是對象類型,比如數據結構如下
{ "products": [ "Windows", "Mac OSX", "Ubuntu" ] }
那么,模板文件中應該這樣設置
{#products} {.} {/products}
最終的文件內容如下:
Windows Mac OSX Ubuntu
此次模板如下:
模板文件推薦放在靜態目錄文件下。
使用vue-cli2的時候,放在static目錄下。使用vue-cli3的時候,放在public目錄下。
script代碼
我們可以參照 docxtemplater 給出的例子, 來實現文件導出。
- 讀取模板文件內容
- 裝載到zip對象中
- 設置文件數據
- 生成文件
- 保存文件
//點擊導出 deriveword(e) { console.log(e) let docxsrc = "../../../../static/daily.docx"; //模板文件的位置 let docxname = "工作日志.docx"; //導出文件的名字 // 讀取並獲得模板文件的二進制內容 JSZipUtils.getBinaryContent(docxsrc, function(error, content) { // docxsrc是模板。我們在導出的時候,會根據此模板來導出對應的數據 // 拋出異常 if (error) { throw error; } // 創建一個PizZip實例,內容為模板的內容 let zip = new PizZip(content); // 創建並加載docx templater實例對象 let doc = new docxtemplater().loadZip(zip); // 設置模板變量的值 doc.setData({ ...e, // e中的數據可以再模板中直接使用 cause: e.form[4].val, arrive: e.form[2].val, starttime: e.form[1].val[0], endtime: e.form[1].val[1] }); try { // 用模板變量的值替換所有模板變量 doc.render(); } catch (error) { // 拋出異常 let e = { message: error.message, name: error.name, stack: error.stack, properties: error.properties }; console.log(JSON.stringify({ error: e })); throw error; } // 生成一個代表docxtemplater對象的zip文件(不是一個真實的文件,而是在內存中的表示) let out = doc.getZip().generate({ type: "blob", mimeType: "application/vnd.openxmlformats-officedocument.wordprocessingml.document" }); // 將目標文件對象保存為目標類型的文件,並命名 saveAs(out, docxname); }); },
參數e的數據
{ user_name: "XXX", remark: "XXX的外出申請", form:[ { val: "私事" }, { val: ["2020-09-23","2020-09-25"] }, { val: "市內" }, { val: "回家" }, { val: "回家吃飯" }, ] }
導出后文件

循環數據使用
循環數據導出結果
完整小Demo
碼雲地址:https://gitee.com/xhxdd/vue-export-word
參考文章鏈接:
https://www.jianshu.com/p/b3622d6f8d98
https://www.jianshu.com/p/0de31429b12a