当前位置: 首页 > news >正文

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

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

  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
// 引入处理图片的插件1
npm install docxtemplater-image-module-free --save
// 引入处理图片的插件2
npm install angular-expressions --save
  1. 关键代码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 < len; i++) {const ascii = binaryString.charCodeAt(i);bytes[i] = ascii;}return bytes.buffer;
}export const ExportBriefDataDocx = (tempDocxPath, data, fileName, imgSize) => {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 errorif (!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.scopeListconst num = context.numfor (let i = 0, len = num + 1; i < len; i++) {obj = assign(obj, scopeList[i])}//word模板中使用 $index+1 创建递增序号obj = assign(obj, { $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的数据转为ArrayBufferreturn 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;//转成base64let dataurl = canvas.toDataURL("image/" + ext, quality);//返回resolve(dataurl);};})
}
  1. 导出函数
    vue 中引入上述js文件和方法
import {ExportBriefDataDocx,getBase64Sync} from './doc.js'
async ExportBriefDataDocx(){//图片转base64let 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],};exportWord("/我的模板.docx", data, `${this.listname}.docx`, imgSize);//docx模板放在public文件夹下,如果是vue2放在static下// ExportBriefDataDocx("/static/我的模板.docx", data, `${listname}.docx`, imgSize);}	
  1. 模板内容
    自己准备一个docx文档,然后里面标注好需替换的参数
    列表循环-- {#list}{name}{/list}
    单个参数–{}
    图片–{%imgUrl}
    在这里插入图片描述
    大概就这些,我也是从参考链接里看到的,至此基本能解决大部分问题,但是我还遇到了两个问题,所以自己记录补充一下
  2. 表格循环打印会多出空格
    在这里插入图片描述
    我想循环表格出来,但是输入数据,出来后实际是这样的
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;//转成base64let dataurl = canvas.toDataURL("image/"+ext);//返回resolve(dataurl);};})
}

相关文章:

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

参考&#xff1a;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-save…...

ubuntu 安装 Pycharm社区版

在Ubuntu中安装pycharm社区版_上玄下纁的博客-CSDN博客 里面可以创建快捷方式&#xff0c;蛮好用的...

IP 监控软件

IP 监控软件可帮助管理员主动监控网络资源。随着各种设备连接到网络&#xff0c;监控设备和接口可能很复杂&#xff0c;为管理员提供这些设备的IP监控&#xff0c;了解其各种性能指标和问题。 使用有效的 IP 监控软件的优势 使用有效的 IP 监控系统和一套全面的 IP 监控工具&…...

C#实现读写CSV文件的方法详解

目录 CSV文件标准 文件示例RFC 4180简化标准读写CSV文件 使用CsvHelper使用自定义方法总结 项目中经常遇到CSV文件的读写需求&#xff0c;其中的难点主要是CSV文件的解析。本文会介绍CsvHelper、TextFieldParser、正则表达式三种解析CSV文件的方法&#xff0c;顺带也会介绍一…...

04 http连接处理(上)

基础知识&#xff1a;epoll、http报文格式、状态码和有限状态机 代码&#xff1a;对服务端处理http请求的全部流程进行简要介绍&#xff0c;然后结合代码对http类及请求接收进行详细分析。 epoll epoll_create函数 #include <sys/epoll.h> int epoll_create(int size)…...

c++(强生成关键字+可变参数模板+emplace)[26]

强制生成 不生成 在C中&#xff0c;可以通过一些方式来控制编译器是否生成某些特殊成员函数&#xff08;如默认构造函数、拷贝构造函数、拷贝赋值运算符、析构函数等&#xff09;。 默认生成&#xff1a;如果你没有显式地定义这些特殊成员函数&#xff0c;编译器会自动生成它们…...

Mysql 数据库开发及企业级应用

文章目录 1、Mysql 数据库开发及企业级应用1.1、为什么要使用数据库1.1.1、数据库概念&#xff08;Database&#xff09;1.1.2、为什么需要数据库 1.2、程序员为什么要学习数据库1.3、数据库的选择1.3.1、主流数据库简介1.3.2、使用 MySQL 的优势1.3.3、版本选择 1.4、Windows …...

【数据结构】_6.队列

目录 1.概念 2.队列的使用 3.队列模拟实现 4.循环队列 5.双端队列 6.OJ题 6.1 用队列实现栈 6.2 用栈实现队列 1.概念 &#xff08;1&#xff09;队列是只允许在一端进行插入数据操作&#xff0c;在另一端进行删除数据操作的特殊线性表&#xff1b; &#xff08;2&am…...

7 网络通信(上)

文章目录 网络通信概述ip地址ip的作用ip地址的分类私有ip 掩码和广播地址 linux 命令&#xff08;ping ifconfig&#xff09;查看或配置网卡信息&#xff1a;ifconfig(widows 用ipconfig)测试远程主机连通性&#xff1a;ping路由查看 端口端口是怎样分配的知名端口动态端口 查看…...

MFC图表控件high-speed-charting的使用

high-speed-charting是MFC上的开源图表库,Teechart的替代品。 high-speed-charting的下载地址 https://www.codeproject.com/Articles/14075/High-speed-Charting-Control 特性 High-speed drawing (when axis is fixed) which allows fast plotting of dataUnlimited number …...

Unity中常用方法

1.基础 //初始化引入 [RequireComponent(typeof(BoxCollider2D))] [RequireComponent(typeof(Rigidbody2D))]//游戏帧率设置 60帧Application.targetFrameRate 60;//获取物体对象 //获取到当前物体(根据名称&#xff0c;也可以根据路径)GameObject go GameObject.Find("…...

【监控系统】可视化工具Grafana简介及容器化部署实战

1.什么是Grafana 官网地址&#xff1a;https://grafana.com/ Grafana用Go语言开发的开源数据可视化工具&#xff0c;可以做数据监控和数据统计&#xff0c;带有告警功能。支持快速灵活的客户端图表&#xff0c;面板插件有许多不同方式的可视化指标和日志&#xff0c;官方库中…...

VUE之VueRouter页面跳转

参考资料&#xff1a; 参考视频 参考demo及视频资料 VUE之基本部署及VScode常用插件 VUE之基本组成和使用 VUE之Bootstrap和Element-UI的使用 VUE之axios使用&#xff0c;跨域问题&#xff0c;拦截器添加Token Vue Router官网 Vue Router说明&#xff1a; 说明&#xf…...

【188】Java8利用AVL树实现Map

AVL树又被叫做平衡二叉搜索树、平衡二叉树。AVL是其发明者的首字母缩写。 这篇文章中&#xff0c;AVLTreeMap 类集成了 java.util.Map 接口&#xff0c;并利用 AVL 树结构实现了 Map 接口的所有方法。本文还给出了测试代码。 为什么要发明AVL树&#xff1f; 当我按照从小到大…...

[SQL挖掘机] - 右连接: right join

介绍: 右连接是一种多表连接方式&#xff0c;它以右侧的表为基础&#xff0c;并返回满足连接条件的匹配行以及右侧表中的所有行&#xff0c;即使左侧的表中没有匹配的行。右连接将右表的每一行与左表进行比较&#xff0c;并根据连接条件返回结果集。其实, 左连接和右连接原理一…...

bug篇之基于docker安装nacos(2.1.1)使用dubbo连接不上的问题

说明&#xff1a;首先我的nacos安装是2.1.1版本&#xff0c;请注意版本问题。另外启动时用dubbo的话必须先启动服务提供者再启动服务使用者&#xff0c;否则会报错&#xff0c;同时也必须开放三个端口&#xff1a;8848&#xff0c;9848&#xff0c;9849 java.lang.IllegalStat…...

【Python入门系列】第二十一篇:Python物联网和传感器应用

文章目录 前言一、Python在物联网和传感器应用中的优势二、连接传感器和设备三、读取传感器数据四、示例代码和讲解五、进一步处理和分析传感器数据六、更多应用示例1、温湿度监测系统2、智能家居系统 - 灯光控制 总结 前言 物联网和传感器在现代科技中扮演着重要的角色。物联…...

Python爬虫的urlib的学习(学习于b站尚硅谷)

目录 一、页面结构的介绍  1.学习目标  2.为什么要了解页面&#xff08;html&#xff09;  3. html中的标签&#xff08;仅介绍了含表格、无序列表、有序列表、超链接&#xff09;  4.本节的演示 二、Urllib  1.什么是互联网爬虫&#xff1f;  2.爬虫核心  3.爬虫…...

【MongoDB】--MongoDB聚合Aggregation

目录 一、前言二、聚合管道操作2.1、实际案例1(1)、案例--根据学生no&#xff0c;找到对应班级名称(2)、案例--这个班级有哪些学生和哪些老师在任课 2.2、实际案例2(1)、案例--主表和关联表都有条件限制&#xff0c;且分页返回 一、前言 聚合操作组值来自多个文档&#xff0c;…...

Hadoop学习指南:探索大数据时代的重要组成——Hadoop概述

前言 在当今大数据时代&#xff0c;处理海量数据成为了一项关键任务。Hadoop作为一种开源的分布式计算框架&#xff0c;为大规模数据处理和存储提供了强大的解决方案。本文将介绍Hadoop的组成和其在大数据处理中的重要作用&#xff0c;让我们一同踏上学习Hadoop的旅程。 Hado…...

Win11虚拟内存配置全解析:从临时页面文件到永久解决方案(含DISM命令详解)

Win11虚拟内存深度优化指南&#xff1a;从原理到实战的完整解决方案 每次开机看到那个烦人的"页面文件配置问题"提示&#xff0c;是不是让你感到困惑又无奈&#xff1f;作为Windows系统内存管理的关键组件&#xff0c;虚拟内存的配置直接影响着系统性能和稳定性。本文…...

优盈杯数据泄露事件复盘:隐私保护的警钟

300 万张照片泄露&#xff1a;优盈杯隐私防线的崩塌2014 年 9 月&#xff0c;Clarifai 公司首席执行官向优盈杯一位创始人发邮件&#xff0c;请求提供大量优盈杯照片数据集。由于优盈杯部分创始人对 Clarifai 有投资&#xff0c;Humor Rainbow 为其提供了近 300 万张 优盈杯用户…...

Phi-4-mini-reasoning开源大模型教程:免配置镜像+128K长文本推理实战

Phi-4-mini-reasoning开源大模型教程&#xff1a;免配置镜像128K长文本推理实战 1. 模型简介 Phi-4-mini-reasoning是一个轻量级开源大语言模型&#xff0c;专注于高质量推理任务。作为Phi-4模型家族成员&#xff0c;它具备以下核心特点&#xff1a; 推理能力突出&#xff1…...

5块钱的国产RISC-V芯片CH32V103能干啥?我用它复刻了一个STM32F103的小项目

5元国产RISC-V芯片实战&#xff1a;用CH32V103复刻STM32经典项目 在电子DIY领域&#xff0c;成本始终是创客们无法回避的现实问题。当我在某电商平台发现CH32V103这颗标价仅5元的RISC-V芯片时&#xff0c;第一反应是怀疑它的实用性——毕竟同级别的STM32F103C8T6价格通常在15-2…...

Phi-3-mini-128k-instruct实战:利用VLOOKUP逻辑进行多源数据关联与报告生成

Phi-3-mini-128k-instruct实战&#xff1a;利用VLOOKUP逻辑进行多源数据关联与报告生成 1. 引言 如果你用过Excel&#xff0c;肯定对VLOOKUP这个函数不陌生。它的核心就一句话&#xff1a;根据一个表格里的某个值&#xff0c;去另一个表格里找到对应的信息&#xff0c;然后“…...

GLM-4.1V-9B-Base开发入门:PyCharm专业版连接远程解释器进行模型调试

GLM-4.1V-9B-Base开发入门&#xff1a;PyCharm专业版连接远程解释器进行模型调试 1. 为什么需要远程调试 在AI模型开发过程中&#xff0c;我们经常遇到一个典型问题&#xff1a;本地机器性能不足&#xff0c;无法高效运行大型语言模型。GLM-4.1V-9B-Base这类模型通常需要GPU加…...

河海大学材料科学与工程及材料与化工专业考研复试资料(含《材料分析方法》笔试专项)

温馨提示&#xff1a;文末有联系方式河海大学材料类考研复试资料全面升级 本套资料专为报考河海大学材料科学与工程、材料与化工两个硕士专业的考生设计&#xff0c;聚焦复试核心笔试科目——《材料分析方法》&#xff0c;助力精准高效备考。由2025届一志愿录取考生权威整理 所…...

【建议收藏】彻底剥离“机器味”:2026硬核横评10款降AI神器,实录97.98%极限降至7.46%

现在的知网、维普AIGC检测已经不同往日了&#xff0c;哪怕你逐字手打&#xff0c;只要句式稍显机械&#xff0c;系统就会判定疑似AI生成。很多同学为了降低ai率&#xff0c;把论文改成了毫无逻辑的口水话&#xff0c;结果AI率反而炸了。 别再盲目试错&#xff0c;为了帮大家在…...

通义千问3-VL-Reranker-8B保姆级部署教程:5分钟搞定Nginx反向代理与HTTPS配置

通义千问3-VL-Reranker-8B保姆级部署教程&#xff1a;5分钟搞定Nginx反向代理与HTTPS配置 1. 为什么需要反向代理与HTTPS 当你成功在本地运行通义千问3-VL-Reranker-8B服务后&#xff0c;默认只能通过 http://localhost:7860 访问。这种配置存在三个明显问题&#xff1a; 安…...

Realtek RTL8821CU无线网卡驱动解决方案 - Linux系统WiFi适配完美指南

Realtek RTL8821CU无线网卡驱动解决方案 - Linux系统WiFi适配完美指南 【免费下载链接】rtl8821CU Realtek RTL8811CU/RTL8821CU USB Wi-Fi adapter driver for Linux 项目地址: https://gitcode.com/gh_mirrors/rt/rtl8821CU 你是否在Linux系统上使用Realtek RTL8821CU…...