一、应用场景
批量导出word文档数据较多时,后台生成word文档响应时间过长,只能前端实现word文档下载,同时因为浏览器有下载数量限制,因此附上了打包下载的方法
二、环境准备
依赖包:
npm install --save docxtemplater jszip jszip-utils pizzip
npm install --save file-saver
模板文件:
三、注意事项
1.将模板文件放在项目public路径下
2.对于列表的循环,将其嵌套在{#Table}{/Table}中
四、代码文件
doc.js
import docxtemplater from "docxtemplater";
import PizZip from "pizzip";
import JSZipUtils from "jszip-utils";
import JSZip from "jszip";
import { saveAs } from 'file-saver';
下载单个word文件
export const exportDocx = (tempDocxpath,data,zipName) => {
//读取并获得模板文件的二进制内容
JSZipUtils.getBinaryContent(tempDocxpath,(error,content) =>{
if(error){
throw error;
}
//创建一个PiZip示例,内容为模板的内容
const zip = new PizZip(content);
//创建并加载docxtemplater实例对象
let doc = new docxtemplater().loadZip(zip);
//设置模板变量的值
doc.setData(data);
try{
//用模板变量的值替换所有模板变量
doc.render();
}catch(error){
const e = {
"message":error.message,
"name":error.name,
"stack":error.stack,
"properties":error.properties
};
console.log({error:e});
throw error;
}
//生成一个代表docxtemplater对象的zip文件(在内存中表示)
const out = doc.getZip().generate({
type:"blob",
mimeType:"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
});
saveAs(out,zipName);
});
}
以压缩包形式下载批量文件
export const exportDocx = (tempDocxpath,list,zipName) => {
const promises = [];
const zips = new JSZip();
list.forEach((element,index) => {
const fileName = index + "word模板.docx";
const data = element;
const promise = new Promise((resolver,reject) => {
JSZipUtils.getBinaryContent(tempDocxpath,(error,content) =>{
if(error){
throw error;
}
const zip = new PizZip(content);
let doc = new docxtemplater().loadZip(zip);
doc.setData(data);
try{
doc.render();
}catch(error){
const e = {
"message":error.message,
"name":error.name,
"stack":error.stack,
"properties":error.properties
};
console.log({error:e});
throw error;
}
const out = doc.getZip().generate({
type:"blob",
mimeType:"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
});
zips.file(fileName,out,{binary:true});
resolver();
});
})
promises.push(promise);
});
Promise.all(promises).then(() => {
zips.generateAsync({type:"blob"}).then(content => {
//生成二进制流
saveAs(content,zipName);
})
})
}
应用页面文件index.vue
当前页面为下载单个word文件,注释部分为批量导出word压缩包
<template>
<div>
<el-button type="primary" @click="export_wordTemplage">批量导出word模板</el-button>
</div>
</template>
<script>
import { exportDocx } from '../../utils/doc.js';
export default{
data(){
return {
}
},
methods:{
export_wordTemplage(){
let objList = [];
// let obj = {
// "CommonField":"普通字段",
// "Table":[{
// "no":1,
// "Column1":"Row1_Column1",
// "Column2":"Row1_Column2",
// "Column3":"Row1_Column3",
// "Column4":"Row1_Column4",
// },{
// "no":2,
// "Column1":"Row2_Column1",
// "Column2":"Row2_Column2",
// "Column3":"Row2_Column3",
// "Column4":"Row2_Column4",
// },{
// "no":3,
// "Column1":"Row3_Column1",
// "Column2":"Row3_Column2",
// "Column3":"Row3_Column3",
// "Column4":"Row3_Column4",
// }]
// }
for(let index = 1;index<=10;index++){
let obj = {
"CommonField":"普通字段",
"Table":[{
"no":1,
"Column1":"Row1_Column1",
"Column2":"Row1_Column2",
"Column3":"Row1_Column3",
"Column4":"Row1_Column4",
},{
"no":2,
"Column1":"Row2_Column1",
"Column2":"Row2_Column2",
"Column3":"Row2_Column3",
"Column4":"Row2_Column4",
},{
"no":3,
"Column1":"Row3_Column1",
"Column2":"Row3_Column2",
"Column3":"Row3_Column3",
"Column4":"Row3_Column4",
}]
}
objList.push(obj);
}
exportDocx("/模板文档.docx",objList,"word模板压缩包");
// exportDocx("/模板文档.docx",obj,"word模板");
}
}
}
</script>