一追驴、需要的js依賴
實現(xiàn)此功能需要使用到docxtemplater
肛走、jszip-utils
、jszip
衣迷、FileSaver
等js文件
1、docxtemplater
介紹
docxtemplater是一種郵件合并工具酱酬,它以編程方式使用壶谒,處理條件、循環(huán)岳悟,并且可以擴展為表格佃迄、HTML、圖像等贵少。
參考鏈接:https://docxtemplater.readthedocs.io/en/latest/index.html
用到的API
- new window.docxtemplater:
創(chuàng)建docxtemplater實例對象呵俏,返回一個新的docxtemplater對象 - loadZip(zip):
docxtemplater對象加載zip實例
注意:必須從jszip的2.x版本向該方法傳遞一個zip實例 - setData(Tags):
設置模板變量的值 - render():
此函數(shù)用模板變量的值替換所有模板變量 - getZip():
此函數(shù)返回代表docxtemplater對象的zip
2、jszip-utils
介紹
jszip-utils是與jszip一起使用的跨瀏覽器的工具庫
參考鏈接:https://stuk.github.io/jszip-utils/
用到的API
- getBinaryContent():
讀取并獲得模板文件的二進制內(nèi)容
3滔灶、jszip
介紹
jszip是一個用于創(chuàng)建普碎、讀取和編輯.zip文件的JavaScript庫,且API的使用也很簡單录平。
參考鏈接:https://stuk.github.io/jszip/
用到的API
- new JSZip():
創(chuàng)建一個JSZip實例 - generate():
此函數(shù)可以生成一個zip文件(不是一個真實的文件麻车,而是在內(nèi)存中的表示)
4缀皱、FileSaver
介紹
FileSaver.js 是在客戶端保存文件的解決方案,非常適合需要生成文件动猬,或者保存不應該發(fā)送到外部服務器的敏感信息的應用啤斗。
參考鏈接:
https://www.cnblogs.com/yunser/p/7629399.html
https://www.npmjs.com/package/file-saver
用到的API
- saveAs(blob, "1.docx"):
將目標文件對象保存為目標類型的文件,并命名
二赁咙、實現(xiàn)步驟
1钮莲、完成word模板
首先,根據(jù)需要導出的word文件的要求彼水,先使用word制作出模板崔拥,數(shù)據(jù)使用{變量}
代替。如下圖:
word模板.png
注意:
模板文件推薦放在靜態(tài)目錄文件下凤覆。
使用vue-cli2的時候链瓦,放在static目錄下。使用vue-cli3的時候盯桦,放在public目錄下慈俯。
因為我在使用的時候,放入.vue文件的同級目錄下拥峦,發(fā)現(xiàn)會讀不到模板肥卡。
2、寫出頁面模板
頁面代碼:
<template>
<div class="threeLevelMain">
<!-- 報價容器 -->
<div class="quoteContainer">
<!-- 報價頂部信息 -->
<div class="quote_info clearfix">
<h3 class="h3_title">報價單</h3>
<div class="quote_itemBox">
<div class="quote_item">
<span class="quote_label">客戶名稱:</span>
<p class="quote_p">{{form.custName}}</p>
</div>
<div class="quote_item">
<span class="quote_label">聯(lián)系方式:</span>
<p class="quote_p">{{form.phoneNumber}}</p>
</div>
</div>
<div class="quote_itemBox">
<div class="quote_item">
<span class="quote_label">項目要求:</span>
<p class="quote_p">{{form.projectRequirement}}</p>
</div>
<div class="quote_item">
<span class="quote_label">備注:</span>
<p class="quote_p">{{form.remark}}</p>
</div>
</div>
</div>
<!-- 設備選取表格 -->
<div class="quote_table clearfix">
<el-table
border
class="table_domQuote"
ref="tableDomQuote"
size="small"
:data="tableData"
style="width: 100%"
>
<el-table-column prop="number" width="80" label="序號" align="center"></el-table-column>
<el-table-column label="設備名稱" prop="name" align="center"></el-table-column>
<el-table-column label="數(shù)量" prop="num" align="center"></el-table-column>
<el-table-column prop="salePrice" label="銷售單價" align="center"></el-table-column>
<el-table-column prop="saleTotal" label="銷售合計" align="center"></el-table-column>
<el-table-column label="備注" prop="remark" align="center"></el-table-column>
<div slot="append">
<div class="quoteTable">
<span class="quoteTable_sp1">合計:</span>
<span class="quoteTable_sp1">{{form.totalPrice}}</span>
</div>
</div>
</el-table>
</div>
</div>
<!-- 審核備注容器 -->
<div class="reasonBox clearfix">
<div class="title_checkReason">審核備注:</div>
<div class="checkReasonMain">
<div class="p_box">
<p class="p_checkReason">{{form.checkReason}}</p>
</div>
</div>
</div>
<!-- 底部按鈕容器 -->
<div class="botmBtnContainer">
<el-button @click="exportWord" size="small" type="primary">導出word</el-button>
</div>
</div>
</template>
頁面效果:
頁面效果.png
3事镣、script代碼
<script>
export default {
name: "home",
data() {
return {
// 表單對象
form: {
custName: "杰斯", // 客戶姓名
phoneNumber: "138xxxxxxxx", // 聯(lián)系方式
projectRequirement: "為了更美好的明天而戰(zhàn)", // 項目要求
totalPrice: 140, // 合計報價
remark: "QEWARAEQAAAAAAAAA", // 備注
checkReason: '同意' // 審核備注
},
// 表格信息
tableData: []
};
},
created() {
this.tableData = [
{
number: 1, // 序號
name: "設備1", // 設備名稱
num: 1, // 數(shù)量
salePrice: 10, // 銷售單價
saleTotal: 10, // 銷售合計
remark: "啦啦啦" // 備注
},
{
number: 2, // 序號
name: "設備2", // 設備名稱
num: 2, // 數(shù)量
salePrice: 20, // 銷售單價
saleTotal: 40, // 銷售合計
remark: "啦啦啦" // 備注
},
{
number: 3, // 序號
name: "設備3", // 設備名稱
num: 3, // 數(shù)量
salePrice: 30, // 銷售單價
saleTotal: 90, // 銷售合計
remark: "啦啦啦" // 備注
}
];
},
methods: {
// 點擊導出word
exportWord: function() {
let _this = this;
// 讀取并獲得模板文件的二進制內(nèi)容
JSZipUtils.getBinaryContent("input.docx", function(error, content) {
// input.docx是模板。我們在導出的時候揪胃,會根據(jù)此模板來導出對應的數(shù)據(jù)
// 拋出異常
if (error) {
throw error;
}
// 創(chuàng)建一個JSZip實例璃哟,內(nèi)容為模板的內(nèi)容
let zip = new JSZip(content);
// 創(chuàng)建并加載docxtemplater實例對象
let doc = new window.docxtemplater().loadZip(zip);
// 設置模板變量的值
doc.setData({
..._this.form,
table: _this.tableData
});
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文件(不是一個真實的文件,而是在內(nèi)存中的表示)
let out = doc.getZip().generate({
type: "blob",
mimeType:
"application/vnd.openxmlformats-officedocument.wordprocessingml.document"
});
// 將目標文件對象保存為目標類型的文件喊递,并命名
saveAs(out, "報價單.docx");
});
}
}
};
</script>
4随闪、測試結果
點擊導出的結果:
word效果.png