vue2.0导出word,使用docxtemplater(vue3.0也可使用)

1.安装相关依赖
// 安装 docxtemplater
npm i docxtemplater pizzip  --save
npm i jszip-utils --save 
npm i jszip --save
npm i file-saver --save
// 引入处理图片的插件
npm i docxtemplater-image-module-free --save
2.创建导出word方法文件word.js
import PizZip from 'pizzip'
import docxtemplater from 'docxtemplater'
import JSZipUtils from 'jszip-utils'
import { saveAs } from 'file-saver'
import ImageModule from 'docxtemplater-image-module-free'//图片有关
// import expressions from 'angular-expressions' 
export function getBase64Sync(imgUrl) {
    return new Promise(function (resolve, reject) {
        // 一定要设置为let,不然图片不显示
        let image = new Image();
        // 解决跨域问题
        image.crossOrigin = "anonymous";
        //图片地址
        image.src = imgUrl;
        // 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);
        };
    });
}
/**
 * 将base64格式的数据转为ArrayBuffer
 * @param {Object} dataURL base64格式的数据
 */
// 导出echarts图片,格式转换,官方自带,不需要修改
   function  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 导出文件名
 * @param {Object} imgSize 自定义图片尺寸
 */
export const exportWord = (tempDocxPath, wordData, fileName, imgSize) => {
    // 读取并获得模板文件的二进制内容
    JSZipUtils.getBinaryContent(tempDocxPath, function (error, content) {
        if (error) {
            throw error;
        }
        // 图片处理
        let opts = {}
        opts = {
            // 图像是否居中
            centered: false
        };
        opts.getImage = (chartId) => {
            // 将base64的数据转为ArrayBuffer
            return base64DataURLToArrayBuffer(chartId);
        }
        opts.getSize = function (img, tagValue, tagName) {
            //ArrayBuffer数据tagNamewordData对象的图像属性名
            // 自定义指定图像大小
            if (imgSize.hasOwnProperty(tagName)) {
                return imgSize[tagName];
            } else {
                return [620,190];
            }
        }
        // 创建一个PizZip实例,内容为模板的内容
        let zip = new PizZip(content);
        // 创建并加载docxtemplater实例对象
        let doc = new docxtemplater();
        // 定义模板
        // doc.load(fs.readFileSync(path.resolve(__dirname, 'template.docx')));
        doc.attachModule(new ImageModule(opts));
        doc.loadZip(zip);
        doc.setOptions({
                nullGetter: function () {
                    return "";
                }
            }); // 设置角度解析器
        doc.setData(wordData);
        try {
            // 用模板变量的值替换所有模板变量
            doc.render();
        } catch (error) {
            // 抛出异常
            let e = {
                message: error.message,
                name: error.name,
                stack: error.stack,
                properties: error.properties
            };
            throw error;
        }

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

将需要动态获取的值采用以下格式写好
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
模板格式:
(1) 文本:{db_asset}
(2) 图片:{%risk_img}图片是base64格式
(3) 对象数组:{#methodTopList}{index}…{doc_count}{/methodTopList}
(4) 判断:{#chartpieShow}暂无数据{/chartpieShow} chartpieShow是一个布尔类型的数据
前端组成数据注意echarts图表导出为图片采用以下方法,切记animation: false,不然图片导出来是空的

option && myChart.setOption(option);
window.onresize = function () {
    // 当屏幕尺寸发生变化时,图表尺寸同时发生改变
    myChart.resize();
};
this.wordData.risk_img = myChart.getDataURL({
    pixelRatio: 1, // 导出的图片分辨率比例,默认为 1。
    backgroundColor: "#fff", // 导出的图片背景色,默认使用 option 里的 backgroundColor
});
4.在前端页面调用该方法

案例使用中英文两种模板let reportType = localStorage.getItem(‘lang’) == ‘zh’ ? ‘reportZh.docx’ : 'reportEn.docx’按需使用即可

import { exportWord } from "@/utils/word";
// 导出报告
exportReport(){
  let imgSize = {
      imgUrl: [600,186], //控制导出的word图片大小
  };
  // 数据
  let obj = this.wordData;
  let reportType = localStorage.getItem('lang') == 'zh' ? 'reportZh.docx' : 'reportEn.docx'
  //1:模板文档  2:字段参数 3:输出文档 4:图片大小
  exportWord(
      reportType,
      obj,
      this.wordData.report_name + this.wordData.report_date + ".docx",
          imgSize
     );
},

导出之后的word内容
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

  • 16
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值