共计 3324 个字符,预计需要花费 9 分钟才能阅读完成。
网上搜到的代码都没办法直接使用,需要修改后才能用,我在这里发一版修改后的完美可用的代码,可以直接拿去用,也给自己留个备份。
我在使用网上搜到的代码的时候遇到一些问题,如果你也遇到了这些问题,那么表示这篇文章可以帮助你。
问题:
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 里的变量名一致。普通字段:{字段名},图片字段:{% 字段名}
以上
正文完