我的项目需要:前端层面实现导出word性能
我的项目筹备:
- vue脚手架我的项目(vue-cli4)
- 插件:docxtemplater pizzip jszip jszip-utils file-saver
1.装置依赖:
npm install docxtemplater pizzip --save // 解决docx模板npm install jszip-utils --savenpm 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...