1.下载需要的依赖
2.util文件夹下创建doc.js文件
doc.js
import docxtemplater from 'docxtemplater'
import PizZip from 'pizzip'
import JSZipUtils from 'jszip-utils'
import { saveAs } from 'file-saver'
import ImageModule from "docxtemplater-image-module-free";
/**导出docx@param { String } tempDocxPath 模板文件路径@param { Object } data 文件中传入的数据@param { String } fileName 导出文件名称
*/
export const exportDocx = (tempDocxPath, data, fileName) => {// 读取并获得模板文件的二进制内容JSZipUtils.getBinaryContent(tempDocxPath, (error, content) => {// input.docx是模板。我们在导出的时候,会根据此模板来导出对应的数据// 抛出异常if (error) {throw error}let opts = {};opts.centered = false;opts.getImage = function (tagValue) {return new Promise(function (resolve, reject) {JSZipUtils.getBinaryContent(tagValue, function (error, content) {if (error) {return reject(error);}return resolve(content);});});};//图片有关代码,没有图片的可以删除opts.getSize = (img, tagValue, tagName) => {return [200, 105]; //图片大小 (固定的)// 非固定(这里是设置宽度最大为300px的图片)// return new Promise(function (resolve, reject) {// let image = new Image();// image.src = tagValue;// let imgWidth, imgHeight, scale;// image.onload = function () {// imgWidth = image.width;// imgHeight = image.height;// scale = 0;// if (imgWidth > 300) {// scale = 300 / imgWidth;// imgWidth = 300;// imgHeight = imgHeight * scale;// }// resolve([imgWidth, imgHeight]);// };// image.onerror = function (e) {// console.log("img, tagValue, tagName : ", img, tagValue, tagName);// reject(e);// };// });};let imageModule = new ImageModule(opts);// 创建一个JSZip实例,内容为模板的内容const zip = new PizZip(content)// 创建并加载docxtemplater实例对象const doc = new docxtemplater().loadZip(zip).attachModule(imageModule).compile();doc.resolveData({ ...data.form }).then(() => {doc.render()const out = doc.getZip().generate({type: 'blob',mimeType: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'}) // Output the document using Data-URIsaveAs(out, fileName)}).catch(err => console.log('errorsss', err))})
}
3.创建.docx文档,示例:
注意: 这个.docx模板放在public文件夹里
word表格里面写的编码的含义:
- {xxx} 直接渲染数据的xxx字段
- {#xxx}{/xxx} 循环数组数据
- {%xxx} 渲染图片
例:若
let content = ["a", "b", "c"];
渲染用
{#content} // 循环开始{.} // 数组每个成员的内容{/content} // 循环结尾
let jtqkList = [{name:"独生子女", checked:false}, {name:"单亲", checked:false}, {name:"父母离异", checked:false}];
模板
{#jtqkList}{#checked}( √ ){/checked}{^checked}( ){/checked} {name}{/jtqkList}
4.要求后端返回数据格式如下:
const data = {title: "工作日报",officeName: '',options: [{index:1, name:'测试数据', number: 1, remark:'这是一条备注信息'}], //存放表格数据filler: '',filledTime: '',imgList: [{img: 'https://img-s-msn-com.akamaized.net/tenant/amp/entityid/AA17ORRg.img?w=640&h=336&m=6'},{img: 'https://images.pexels.com/photos/3291250/pexels-photo-3291250.jpeg?auto=compress&cs=tinysrgb&w=1600&lazy=load'}] //图片数据}
5.调用方法导出word
import { exportDocx } from '@/utils/doc.js'
const exportWord = () => {const data = {form: data}exportDocx('/template.docx', data, `${deta.title}.docx`)
}
成果