VUE使用docxtemplater导出word(带图片) 踩坑 表格循环空格 ,canvas.toDataURL图片失真模糊问题 您所在的位置:网站首页 1-200数字表格图片 VUE使用docxtemplater导出word(带图片) 踩坑 表格循环空格 ,canvas.toDataURL图片失真模糊问题

VUE使用docxtemplater导出word(带图片) 踩坑 表格循环空格 ,canvas.toDataURL图片失真模糊问题

2024-06-13 19:49| 来源: 网络整理| 查看: 265

参考:https://www.codetd.com/article/15219743

安装 // 安装 docxtemplater npm install docxtemplater pizzip --save // 安装 jszip-utils npm install jszip-utils --save // 安装 jszip npm install jszip --save // 安装 FileSaver npm install file-saver --save // 引入处理图片的插件1 npm install docxtemplater-image-module-free --save // 引入处理图片的插件2 npm install angular-expressions --save 关键代码JS部分 /** * 导出word文档(带图片) doc.js * */ import Docxtemplater from 'docxtemplater' import PizZip from 'pizzip' import JSZipUtils from 'jszip-utils' import { saveAs } from 'file-saver' /** * 将base64格式的数据转为ArrayBuffer * @param {Object} dataURL base64格式的数据 */ function base64DataURLToArrayBuffer(dataURL) { const base64Regex = /^data:image\/(png|jpg|jpeg|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 = Buffer.from(stringBase64, "base64").toString("binary"); } const len = binaryString.length; const bytes = new Uint8Array(len); for (let i = 0; i console.log(111, tempDocxPath, data, fileName, imgSize) //这里要引入处理图片的插件 var ImageModule = require('docxtemplater-image-module-free'); var expressions = require('angular-expressions') var assign = require('lodash/assign') var last = require("lodash/last") expressions.filters.lower = function (input) { // This condition should be used to make sure that if your input is // undefined, your output will be undefined as well and will not // throw an error if (!input) return input // toLowerCase() 方法用于把字符串转换为小写。 return input.toLowerCase() } function angularParser(tag) { tag = tag .replace(/^\.$/, 'this') .replace(/(’|‘)/g, "'") .replace(/(“|”)/g, '"') const expr = expressions.compile(tag) return { get: function (scope, context) { let obj = {} const index = last(context.scopePathItem) const scopeList = context.scopeList const num = context.num for (let i = 0, len = num + 1; i $index: index }) return expr(scope, obj) } } } JSZipUtils.getBinaryContent(tempDocxPath, (error, content) => { if (error) { console.log(error) } expressions.filters.size = function (input, width, height) { return { data: input, size: [width, height], }; }; let opts = {} opts = { //图像是否居中 centered: true }; opts.getImage = (chartId) => { //将base64的数据转为ArrayBuffer return base64DataURLToArrayBuffer(chartId); } opts.getSize = function (img, tagValue, tagName) { //自定义指定图像大小 if (imgSize.hasOwnProperty(tagName)) { return imgSize[tagName]; } else { return [200, 200]; } } // 创建一个JSZip实例,内容为模板的内容 const zip = new PizZip(content) // 创建并加载 Docxtemplater 实例对象 // 设置模板变量的值 let doc = new Docxtemplater(); doc.attachModule(new ImageModule(opts)); doc.loadZip(zip); doc.setOptions({parser:angularParser}); doc.setData(data) try { // 呈现文档,会将内部所有变量替换成值, doc.render() } catch (error) { const e = { message: error.message, name: error.name, stack: error.stack, properties: error.properties } console.log('err',{ error: e }) // 当使用json记录时,此处抛出错误信息 throw error } // 生成一个代表Docxtemplater对象的zip文件(不是一个真实的文件,而是在内存中的表示) const out = doc.getZip().generate({ type: 'blob', mimeType: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' }) // 将目标文件对象保存为目标类型的文件,并命名 saveAs(out, fileName) }) } /** 1. 将图片的url路径转为base64路径 2. 可以用await等待Promise的异步返回 3. @param {Object} imgUrl 图片路径 */ export function getBase64Sync(imgUrl) { return new Promise(function (resolve, reject) { // 一定要设置为let,不然图片不显示 let image = new Image(); //图片地址 image.src = imgUrl; // 解决跨域问题 image.setAttribute("crossOrigin", '*'); // 支持跨域图片 // image.onload为异步加载 image.onload = function () { let canvas = document.createElement("canvas"); canvas.width = image.width; canvas.height = image.height; let context = canvas.getContext("2d"); context.drawImage(image, 0, 0, image.width, image.height); //图片后缀名 let ext = image.src.substring(image.src.lastIndexOf(".") + 1).toLowerCase(); //图片质量 let quality = 0.8; //转成base64 let dataurl = canvas.toDataURL("image/" + ext, quality); //返回 resolve(dataurl); }; }) } 导出函数 vue 中引入上述js文件和方法 import {ExportBriefDataDocx,getBase64Sync} from './doc.js' //导出 async exports(){ //图片转base64 let imgurl= await getBase64Sync('图片路径') let imgurl2= await getBase64Sync('图片路径') let data= { name:this.name, imgurl:this.imgurl, imgurl2:this.imgurl2 } let imgSize = { //控制导出的word图片大小,可自定义 imgurl:[200, 200], imgurl2:[200, 200], }; ExportBriefDataDocx("/我的模板.docx", data, `${this.listname}.docx`, imgSize); //docx模板放在public文件夹下,如果是vue2放在static下 // ExportBriefDataDocx("/static/我的模板.docx", data, `${listname}.docx`, imgSize); } //运行导出 exports() 模板内容 自己准备一个docx文档,然后里面标注好需替换的参数 列表循环-- {#list}{name}{/list} 单个参数–{} 图片–{%imgUrl} 在这里插入图片描述 大概就这些,我也是从参考链接里看到的,至此基本能解决大部分问题,但是我还遇到了两个问题,所以自己记录补充一下表格循环打印会多出空格 在这里插入图片描述 我想循环表格出来,但是输入数据,出来后实际是这样的 let data= { ld:[{data1:1,data2:2},{data1:1,data2:2}], } ExportBriefDataDocx("/static/wd.docx", data, `${listname}.docx`, imgSize);

在这里插入图片描述 多出了很多空格,我想着去掉模板中的换行符,像这样 在这里插入图片描述 我本来是想着这样就能少一行,就是正常表格了,但是其实报错了 message: ‘The filetype for this file could not be identified, is this file corrupted ?’, stack: ‘Error: The filetype for this file could not be ide…//./node_modules/jszip-utils/lib/index.js:110:25)’ 大概就是类型不对,读不出来什么的 后来灵光一闪,想到参考链接里各种数据都是在表格里的,应该没问题,所以我就想着开始结束都放进去,就像这样 在这里插入图片描述 然后结果就对了 在这里插入图片描述

7.保存图片模糊问题 quality = 1也没啥用

改成这样,导出后的图片能经得起缩放

export function getBase64Sync(imgUrl,width,height) { //传入你想要的宽高,最好大一点,这个不会影响导出后的大小,这里的宽高可以理解为分辨率,就是canvas绘制的时候的大小,imgSize里的才是导出到文档的大小 return new Promise(function (resolve, reject) { // 一定要设置为let,不然图片不显示 let image = new Image(); //图片地址 image.src = imgUrl; // 解决跨域问题 image.setAttribute("crossOrigin", '*'); // 支持跨域图片 // image.onload为异步加载 image.onload = function () { let canvas = document.createElement("canvas"); canvas.width = width*2; canvas.height = height*2; //宽高放大两倍 let context = canvas.getContext("2d"); context.drawImage(image, 0, 0); //图片后缀名 let ext = image.src.substring(image.src.lastIndexOf(".") + 1).toLowerCase(); //图片质量 //let quality = 1; //转成base64 let dataurl = canvas.toDataURL("image/"+ext); //返回 resolve(dataurl); }; }) }


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有