网上搜到的代码都没办法直接使用,需要修改后才能用,我在这里发一版修改后的完美可用的代码,可以直接拿去用,也给自己留个备份。
我在使用网上搜到的代码的时候遇到一些问题,如果你也遇到了这些问题,那么表示这篇文章可以帮助你。
问题:
1、JSZIP版本太高(V3.x),导致docxtemplater无法使用,以及一些函数大改动。
2、Vue3使用的Vite而不是Webpack,因此 require,Buffer等功能不能使用。
解决方法:
1、手动将JSZIP由3.x改为2.3.0版本,重新npm i,即可解决。
2、Buffer要安装buffer依赖,使用
npm i buffer --save
进行安装,然后直接按如下引用:
import {Buffer} from "buffer";
另外,网络上的代码在加载图片处理依赖时使用的是
var ImageModule = require('docxtemplater-image-module-free');
需要改为
import ImageModule from "docxtemplater-image-module-free";
以上就是主要的问题所在,下面贴上完整代码和一些需要注意的东西。
完整代码
1、开始之前,你需要先安装如下依赖
-- 安装 docxtemplater npm install docxtemplater pizzip --save -- 安装 jszip-utils npm install jszip-utils --save -- 安装 jszip npm install jszip --save -- 安装 FileSaver npm install file-saver --save -- 安装 buffer 用作b64转buffer npm install buffer --save -- 安装 docxtemplater-image-module-free 用作图片处理 npm install docxtemplater-image-module-free --save
2、新建一个js文件,我是在/src/utils/下新建的fileExport.js,并粘贴如下内容。
import PizZip from 'jszip'; import docxtemplater from 'docxtemplater'; import JSZipUtils from 'jszip-utils'; import {saveAs} from 'file-saver'; import {Buffer} from "buffer"; import ImageModule from "docxtemplater-image-module-free"; const base64DataURLToArrayBuffer = (dataURL) => { const base64Regex = /^data:image\/(png|jpg|svg|svg\+xml);base64,/; if (!base64Regex.test(dataURL)) { return false; } const stringBase64 = dataURL.replace(base64Regex, ""); let binaryString; if (typeof window !== "undefined") { binaryString = window.atob(stringBase64); } else { binaryString = new Buffer(stringBase64, "base64").toString("binary"); } const len = binaryString.length; const bytes = new Uint8Array(len); for (let i = 0; i < len; i++) { const ascii = binaryString.charCodeAt(i); bytes[i] = ascii; } return bytes.buffer; } /** * 导出word,支持图片 * @param {Object} tempDocxPath 模板文件路径 * @param {Object} wordData 导出数据 * @param {Object} fileName 导出文件名 */ export const exportWord = (tempDocxPath, wordData, fileName, imageSize = {}) => { // 读取并获得模板文件的二进制内容 JSZipUtils.getBinaryContent(tempDocxPath, function (error, content) { if (error) { throw error; } let opts = {}; opts.centered = true; // 图片居中,在word模板中定义方式为{%%image} opts.fileType = "docx"; opts.getImage = function (chartId) { return base64DataURLToArrayBuffer(chartId); }; opts.getSize = function (img, tagValue, tagName) { // console.log(img);//ArrayBuffer数据 // console.log(tagValue);//base64数据 // console.log(tagName);//wordData对象的图像属性名 // 自定义指定图像大小 // eslint-disable-next-line no-prototype-builtins if (imageSize.hasOwnProperty(tagName)) { return imageSize[tagName]; } else { return [660, 440]; } } let imageModule = new ImageModule(opts); // 创建一个PizZip实例,内容为模板的内容 const zip = new PizZip(content); // 创建并加载docxtemplater实例对象 const doc = new docxtemplater(); doc.attachModule(imageModule); doc.loadZip(zip); doc.setData(wordData); try { // 用模板变量的值替换所有模板变量 doc.render(); } catch (error) { // 抛出异常 const e = { message: error.message, name: error.name, stack: error.stack, properties: error.properties }; console.log( JSON.stringify({ error: e }) ); throw error; } console.log('11'); // 生成一个代表docxtemplater对象的zip文件(不是一个真实的文件,而是在内存中的表示) const out = doc.getZip().generate({ type: 'blob', mimeType: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' }); // 将目标文件对象保存为目标类型的文件,并命名 saveAs(out, fileName); } ); };
3、参数说明
- tempDocxPath 是模板文件绝对路径
- wordData 模板数据
- fileName 要保存的文件名
- imageSize 图片大小,接受一个int对象,格式是{ width, height },单位是px,例如{ 400, 300 }
如需导出图片,则需要将图片转为base64后写入wordData对象内。
echarts转base64的方法是
echarts.getInstanceByDom(document.getElementById('echarts')).getDataURL({ type: 'png', backgroundColor: '#fff', pixelRatio: 1, })
4、模板变量
模板内变量要和wordData里的变量名一致。普通字段:{字段名},图片字段:{%字段名}
以上
发表回复