vue项目根据word模版导出word文件

一、安装依赖

复制代码
//1、docxtemplater

npm install docxtemplater pizzip -S


//2、jszip-utils

npm install jszip-utils -S


//3、pizzip

npm install pizzip -S


//4、FileSaver
npm install file-saver --save

二、创建word模版

也就是编辑一个word文档,文档中需要动态取值的地方用{变量}取值;表格数据可以进行循环,以{#数组变量名}开始,以{/数组变量名}结束,如果数组变量是字符串而非对象则{#table}{.}{/table}。图片以{%图片base64变量名}展示,{%%图片base64变量名}表示图片居中。word模版放在public下。

word模版占位符用法

三、导出方法

复制代码
//导入包
import PizZip from 'pizzip'
import docxtemplater from 'docxtemplater'
import JSZipUtils from 'jszip-utils'
import { saveAs } from 'file-saver'

data() {
    return {
        form: {
            userName: "杰克",
            value: "666", 
        },
        // 表格信息
        tableData: [],
        //图片
        img1: '',
        img2: ''
    };
},



methods:{
// 导出echarts图片,格式转换,官方自带,不需要修改
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
exportWord() {
    //这里要引入处理图片的插件,下载docxtemplater后,引入的就在其中了
    var ImageModule = require('docxtemplater-image-module-free');
    var fs = require("fs");
    const expressions = require("angular-expressions");

    let _this = this;

    // 读取并获得模板文件的二进制内容,放在项目中即可(wordTemplate.docx是public文件下的word模版)
    JSZipUtils.getBinaryContent("wordTemplate.docx", function(error, content) {
        if (error) {
            throw error;
        };

        expressions.filters.size = function (input, width, height) {
            return {
                data: input,
                size: [width, height],
            };
        };
        function angularParser(tag) {
            const expr = expressions.compile(tag.replace(/'/g, "'"));
            return {
                get(scope) {
                    return expr(scope);
                },
            };
        }

        // 图片处理
        let opts = {}
            opts = { centered: false };
            opts.getImage = (chartId)=> {
            return _this.base64DataURLToArrayBuffer(chartId);
        }
        opts.getSize = function(img, tagValue, tagName) {
            console.log(tagName)
            //自定义指定图像大小,此处可动态调试各别图片的大小
            if (tagName === "chartImg1") return [249,200];
            return [300,200];
        }

        // 创建一个PizZip实例,内容为模板的内容
        let zip = new PizZip(content);
        // 创建并加载docxtemplater实例对象
        let doc = new docxtemplater();
        // 去除未定义值所显示的undefined
        doc.setOptions({nullGetter: function() { 
            return ""; 
        }});
        doc.attachModule(new ImageModule(opts));
        doc.loadZip(zip);


        // 设置模板变量的值(键是word模版中用的值,值是vue文件data中的变量)
        doc.setData({
            ..._this.form,
            table: _this.tableData,
            img1: _this.img1,
            img2: _this.img2
        });

        try {
            // 用模板变量的值替换所有模板变量
            doc.render();
        } catch (error) {
            // 抛出异常
            let e = {
                message: error.message,
                name: error.name,
                stack: error.stack,
                properties: error.properties
            };
            console.log(JSON.stringify({ error: e }));
            throw error;
        }

        // 生成一个代表docxtemplater对象的zip文件(不是一个真实的文件,而是在内存中的表示)
        let out = doc.getZip().generate({
            type: "blob",
            mimeType:"application/vnd.openxmlformats-officedocument.wordprocessingml.document"
        });
        // 将目标文件对象保存为目标类型的文件,并命名
        saveAs(out, "测试.docx");
    });
},
}

ECHARTS图表的图片并转为base64格式,在图表加载完成时

复制代码
this.img2 = myChart2.getDataURL({
      pixelRatio: 2,      // 导出的图片分辨率比例,默认为 1。
      backgroundColor: '#fff'   // 导出的图片背景色,默认使用 option 里的 backgroundColor
});

如果是需要动态添加的背景图,可以直接将图片的base64码赋值给img1变量。

相关推荐
计算机学姐7 分钟前
基于SpringBoot的小型民营加油站管理系统
java·vue.js·spring boot·后端·mysql·spring·tomcat
Elastic 中国社区官方博客12 分钟前
JavaScript 中使用 Elasticsearch 的正确方式,第一部分
大数据·开发语言·javascript·数据库·elasticsearch·搜索引擎·全文检索
万物得其道者成23 分钟前
从零开始创建一个 Next.js 项目并实现一个 TodoList 示例
开发语言·javascript·ecmascript
海天胜景30 分钟前
无法加载文件 E:\Program Files\nodejs\npm.ps1,因为在此系统上禁止运行脚本
前端·npm·node.js
MingT 明天你好!33 分钟前
在vs code 中无法运行npm并报无法将“npm”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查
前端·npm·node.js·visual studio code
老兵发新帖38 分钟前
pnpm 与 npm 的核心区别
前端·npm·node.js
超级土豆粉39 分钟前
怎么打包发布到npm?——从零到一的详细指南
前端·npm·node.js
OpenTiny社区44 分钟前
TinyEngine 2.5版本正式发布:多选交互优化升级,页面预览支持热更新,性能持续跃升!
前端·低代码·开源·交互·opentiny
声声codeGrandMaster1 小时前
Django框架的前端部分使用Ajax请求一
前端·后端·python·ajax·django
sunbyte1 小时前
50天50个小项目 (Vue3 + Tailwindcss V4) ✨ | Expanding Cards (展开式卡片)
javascript·vue.js·ecmascript