我的项目需要:前端层面实现导出 word 性能
我的项目筹备:
- vue 脚手架我的项目(vue-cli4)
- 插件:docxtemplater pizzip jszip jszip-utils file-saver
1. 装置依赖:
npm install docxtemplater pizzip --save // 解决 docx 模板
npm install jszip-utils --save
npm install jszip@2.6.1 --save
npm install file-saver --save // 解决输入文件
- 坑 1:执行 npm install jszip –save 会下载最新版本导致报错,必须指定版本号,亲测 2.6.1 版本可行
2. 创立 word 模板:public/test.docx
- vuecli3/vuecli4 在 public 文件下寄存 word 模板 test.docx;vuecli2 在 static 文件下寄存 word 模板 test.docx;
- word 模板示例:
- 坑 2:如果间接在代码编辑器内通过新建文件的形式创立 test.docx 前面会报错,应该和文件编码格局无关,所以须要进入我的项目文件夹内右键新建 docx 文件,test.docx 内编辑后编辑器内能够看到 pulic 文件下多了一个~$test.docx 文件;呈现这个文件夹根本就 okay 了
3. 封装导出 word 组件:src/components/export2word.vue
<template>
<div>
<div class="word-box" @click="exportWord">word</div>
</div>
</template>
<script>
import Docxtemplater from 'docxtemplater';
import JSZip from 'jszip';
import JSZipUtils from 'jszip-utils';
import {saveAs} from 'file-saver';
export default {
name: 'Docx',
props: {
fileName: {
type: String, // 输入文件名
default: ''
},
fileTemplete: {
type: String, // public 下寄存的 word 模板名称
default: ''
},
exportData: {
type: Object, // 导出的 word 数据
default: () => {}
}
},
methods: {
// 点击导出 word
exportWord() {
// 读取并取得模板文件的二进制内容
JSZipUtils.getBinaryContent(this.fileTemplete + '.docx', (error, content) => {
// 抛出异样
if (error) throw error;
// 创立一个 JSZip 实例,内容为模板的内容
let zip = new JSZip(content);
// 创立并加载 docxtemplater 实例对象
let doc = new Docxtemplater();
doc.loadZip(zip);
// 设置模板变量的值
doc.setData({...this.exportData});
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, this.fileName + '.docx');
});
},
},
}
</script>
4. 页面应用 word 组件:src/views/page.vue
<template>
<div class="page">
<Download
class="download"
:fileName="fileName"
:fileTemplete="fileTemplete"
:exportData="exportData"
/>
</div>
</template>
<script>
import Download from '@/components/export2word.vue';
export default {data() {
return {
fileName: '2021 年度销售业绩报告',
fileTemplete: 'test',
exportData: {
"code": "value",
"data": {
"dataArr0": {
"key1": "value1",
"key1": "value1",
"key1": "value1",
"key1": "value1",
},
"dataArr1": {
"key1": "value1",
"key1": "value1",
"key1": "value1",
"key1": "value1",
},
"dataArr2": {
"key1": "value1",
"key1": "value1",
"key1": "value1",
"key1": "value1",
},
"dataArr3": {
"obj1": {
"key1": "value1",
"key1": "value1",
"key1": "value1",
"key1": "value1",
},
"obj2": {
"key1": "value1",
"key1": "value1",
"key1": "value1",
"key1": "value1",
},
"obj3": {
"key1": "value1",
"key1": "value1",
"key1": "value1",
"key1": "value1",
},
"key2": "value2",
"key3": "value3",
},
"dataArr4": [
{
"key1": "value1",
"key1": "value1",
"key1": "value1",
"key1": "value1",
},
{
"key1": "value1",
"key1": "value1",
"key1": "value1",
"key1": "value1",
},
{
"key1": "value1",
"key1": "value1",
"key1": "value1",
"key1": "value1",
},
{
"key1": "value1",
"key1": "value1",
"key1": "value1",
"key1": "value1",
},
{
"key1": "value1",
"key1": "value1",
"key1": "value1",
"key1": "value1",
}
],
"dataArr5": {
"key1": "value1",
"key1": "value1",
"key1": "value1",
"key1": "value1",
}
}
},
}
},
components: {Download,},
}
</script>
<style>
.page {
box-sizing: border-box;
width: 100%;
height: 100vh;
user-select: none;
}
.page .download {
border: 1px solid #000;
padding: 5px 10px;
height: 50px;
margin-left: 100px;
cursor: pointer;
}
</style>
5. 填充 word 模板数据:
-
填充数据依据渲染数据的构造而定,这里提供了数组和对象数据结构
解析变量:{变量名} 循环:{# 数组名} {元素名 1}{元素名 2}.... {/ 数组名} 条件:{# 条件} {变量} {/ 条件}
- 坑 3:留神应用 JS 对象点语法是拜访不到变量的,对象格局数据拜访{# 父对象名}{子属性}{/ 父对象名}
论断
好好啃官网,就是看起来好烦,附上官网供你们持续烦:https://docxtemplater.com/doc…