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

这篇具有很好参考价值的文章主要介绍了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 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 < 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的数据转为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);
        };
    })
}
  1. 导出函数
    vue 中引入上述js文件和方法
import {ExportBriefDataDocx,getBase64Sync} from './doc.js'
async ExportBriefDataDocx(){
            //图片转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],
	        };
	        exportWord("/我的模板.docx", data, `${this.listname}.docx`, imgSize);
	        //docx模板放在public文件夹下,如果是vue2放在static下
	        // ExportBriefDataDocx("/static/我的模板.docx", data, `${listname}.docx`, imgSize);
	      }	
  1. 模板内容
    自己准备一个docx文档,然后里面标注好需替换的参数
    列表循环-- {#list}{name}{/list}
    单个参数–{}
    图片–{%imgUrl}
    VUE使用docxtemplater导出word(带图片) 踩坑 表格循环空格 ,canvas.toDataURL图片失真模糊问题,canvas,js,vue,vue.js,word,前端
    大概就这些,我也是从参考链接里看到的,至此基本能解决大部分问题,但是我还遇到了两个问题,所以自己记录补充一下
  2. 表格循环打印会多出空格
    VUE使用docxtemplater导出word(带图片) 踩坑 表格循环空格 ,canvas.toDataURL图片失真模糊问题,canvas,js,vue,vue.js,word,前端
    我想循环表格出来,但是输入数据,出来后实际是这样的
let  data= {
      ld:[{data1:1,data2:2},{data1:1,data2:2}],
    }      
    ExportBriefDataDocx("/static/wd.docx", data, `${listname}.docx`, imgSize);

VUE使用docxtemplater导出word(带图片) 踩坑 表格循环空格 ,canvas.toDataURL图片失真模糊问题,canvas,js,vue,vue.js,word,前端
多出了很多空格,我想着去掉模板中的换行符,像这样
VUE使用docxtemplater导出word(带图片) 踩坑 表格循环空格 ,canvas.toDataURL图片失真模糊问题,canvas,js,vue,vue.js,word,前端
我本来是想着这样就能少一行,就是正常表格了,但是其实报错了
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)’
大概就是类型不对,读不出来什么的
后来灵光一闪,想到参考链接里各种数据都是在表格里的,应该没问题,所以我就想着开始结束都放进去,就像这样
VUE使用docxtemplater导出word(带图片) 踩坑 表格循环空格 ,canvas.toDataURL图片失真模糊问题,canvas,js,vue,vue.js,word,前端
然后结果就对了
VUE使用docxtemplater导出word(带图片) 踩坑 表格循环空格 ,canvas.toDataURL图片失真模糊问题,canvas,js,vue,vue.js,word,前端

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

改成这样,导出后的图片能经得起缩放文章来源地址https://www.toymoban.com/news/detail-609750.html

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);
        };
    })
}

到了这里,关于VUE使用docxtemplater导出word(带图片) 踩坑 表格循环空格 ,canvas.toDataURL图片失真模糊问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 使用poi-tl向word插入图片、文本、表格行循环

    工作中难免会向word中操作数据,本文主要介绍poi-tl的使用,先来看效果图 核心介绍: 标签 1、插入文本标签 : {{var}} 2、插入图片标签: {{@var}} 操作步骤: 1、引入依赖 2、Java核心代码 官方网址:http://deepoove.com/poi-tl/ 1、准备模版,定义好需要的标签 2、查询模版 3、获取需要填

    2024年02月05日
    浏览(91)
  • java导出word(含图片、表格)

    1.pom 引入 2.java代码示例 3.效果展示

    2024年02月07日
    浏览(34)
  • element-ui框架下通过docxtemplater插件导出word文件

    预先写好的word 生成的带数据word文档 docxtemplater 使用 JSON 数据格式作为输入,可以处理docx 和 ppt模板。不像一些其它的工具,比如 docx.js, docx4j, python-docx 等,需要自己编写代码来生成文件,docxtemplater只需要用户通过标签的形式编写模板,就可以生成文件 安装依赖 项目所需依

    2024年02月04日
    浏览(25)
  • 若依框架中使用FreeMarker使用word动态模板生成pdf给前端展示(模板中并没用使用到图片,所以没有图片的方法,只用了表格展示数据,模板里面只涉及到了循环判断和日期格式)

    首先使用word创建动态模板  下方两组信息是通过循环展示的,在生成模板时注意,如果不点击里面表格,选择居中表格打印出来可能还有偏差,两边距离页面拒了可能不一样 存储需要的模板时注意      存成这个格式,如果不是2003可能会有坑,找到你生成的.xml文件,把后缀改成ftl  

    2024年02月04日
    浏览(31)
  • easypoi 导出word表格

    template.docx 模板内容: {{0}} {{1}} {{2}} {{3}} {{4}} {{5}} 学生姓名 学生年龄 学生生日 语文成绩 数学成绩 template_job.docx 模板内容: 名称 年龄 地址 名称2 {{user.name}} {{user.age}} {{user.address}} {{user.other}} 公司名称 地址 {{$fe:jobs t.name t.address}}

    2024年02月13日
    浏览(79)
  • 【工具插件类教学】NPOI插件使用Excel表格的导入和导出(包含图片)

    目录 一.导入Excel 解析读取 1.选择导入的目标文件 2.解析读取导入的文件

    2024年01月16日
    浏览(44)
  • vue 使用docx库生成word表格文档

            在Vue.js中生成Word表格文档,可以通过前端库来实现。这些库可以帮助我们轻松地将HTML表格转换为Word文档(通常是.docx格式)。以下是一些流行的前端库,它们可以用于在Vue项目中生成Word表格文档:                  docx是一个流行的JavaScript库,用于在浏览

    2024年02月21日
    浏览(43)
  • poi-tl导出word复杂表格(单元格合并,生成复杂表格)

    官方文档地址:http://deepoove.com/poi-tl/ 源码地址:https://github.com/Sayi/poi-tl poi-tl(poi template language)是Word模板引擎,使用Word模板和数据创建很棒的Word文档。 最近在做项目时候有一个关于导出Word的文件的需求,需要导出的word文件较大,并且格式比较复杂,使用poi-tl可以很好的

    2024年02月16日
    浏览(34)
  • 怎么把图片表格转换成word表格?几个步骤达成

    在处理文档时,图片表格的转换是一个常见的需求。而手动输入表格是非常耗时的,因此,使用文本识别软件来自动转换图片表格可以大大提高工作效率。在本文中,我们将介绍如何使用OCR文字识别技术来将图片表格转换为Word表格。   OCR文字识别软件 OCR技术可以识别图片中

    2024年02月13日
    浏览(28)
  • JAVA poi-tl 制作word模板 表格数据行循环 带有复选框勾选的表格

            java项目实际开发中经常会遇到制作word表单且表格数据行循环功能,甚至带有复选框勾选功能,本文简单介绍如何制作模板以及使用poi-tl生成word。 提示:以下是本篇文章正文内容,下面案例可供参考 如果只用到word那么需要导入的依赖如下(本案例只需要如下2个依

    2024年04月12日
    浏览(25)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包