docxtemplater+vue+docxtemplater-image-module-free 导出word文档(包含图片)

docxtemplater+vue+docxtemplater-image-module-free 导出word文档(包含图片)

安装需要的插件

npm install  jszip-utils
npm install docxtemplater
npm install jszip
npm install file-saver
npm install docxtemplater-image-module-free

创建一个word模板

放项目的publid文件夹
正常的数据为 {title}
图片{%imgUrl}
循环{#list}{/list}
如下
在这里插入图片描述

处理图片为Base46

注意: 如果出现跨域的问题,需要后端帮忙生成Base46(PS:别傻乎乎自己搞,搞半天都搞不定)

前端获取Base46:

  /**
   * 将图片的url路径转为base64路径
   * @param {Object} imgUrl 图片路径
   */
  getBase64Sync(imgUrl) {
    
    
    window.URL = window.URL || window.webkitURL;
    var xhr = new XMLHttpRequest();
    xhr.open("get", imgUrl, true);
    xhr.responseType = "blob";
    xhr.onload = function () {
    
    
      if (this.status == 200) {
    
    
        //得到一个blob对象
        var blob = this.response;
        console.log("blob", blob)
        // 至关重要
        let oFileReader = new FileReader();
        oFileReader.onloadend = function (e) {
    
    
          // 此处拿到的已经是base64的图片了,可以赋值做相应的处理
          console.log(e.target.result)
        }
        oFileReader.readAsDataURL(blob);
      }
    }
    xhr.send();
  }

后端获取加上 this.base64 = 'data:image/png;base64,' + res.data
获取到后用官网上的代码如下

 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 = 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

// word导出

      let _this = this;
      // 读取并获得模板文件的二进制内容
      JSZipUtils.getBinaryContent("test.docx", function (error, content) {
    
    
        // 1.docx是模板。我们在导出的时候,会根据此模板来导出对应的数据
        // 抛出异常
        if (error) {
    
    
          throw error;
        }
        // 图片处理
        let opts = {
    
    };
        opts.centered = false; // 图片居中,在word模板中定义方式为{%%image}
        opts.fileType = "docx";
        opts.getImage = function (chartId) {
    
    
          return _this.base64DataURLToArrayBuffer(chartId);
        };
        opts.getSize = function () {
    
    
          return [150, 35];
        };
  

        let imageModule = new ImageModule(opts);
        // 创建一个JSZip实例,内容为模板的内容
        const zip = new JSZip(content);
        // 创建并加载docxtemplater实例对象
        let doc = new docxtemplater();
        doc.attachModule(imageModule);
        doc.loadZip(zip);
        
      =

        // 设置模板变量的值
        doc.setData({
    
    
          ..._this.list,
          list: _this.data,//需要循环的数据
          imgUrl :  _this.base64,//图片获取的base6
        });

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

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

注意如果是后端返回数据为null,导出会出现未定义记得转化成空字符串

猜你喜欢

转载自blog.csdn.net/sxmzhw/article/details/127653748