导出word文档

导出word文档

需求

  • 导出word文档

思路

  1. 本地模板,文档中固定占位符
  2. 代码中对应data
  3. 运行代码,生成word文档

依赖

  1. docxtemplater (V3.22.3) 由模板生成文档的库
  2. pizzip (V3.0.6) 使用JavaScript创建读取和编辑文件的库
  3. file-saver(V2.0.5) 保存文件的库
  4. docxtemplater-image-module-free(V1.1.1) 开源docxtemplater图像模块

正文

  • 安装依赖
import Docxtemplater from "docxtemplater";
import PizZip from "pizzip";
import PizZipUtils from "pizzip/utils/index.js";
import { saveAs } from "file-saver";
import ImageModule from "docxtemplater-image-module-free";  
  • 图片转为base64图片
async getBase64(imgUrl, callback) {
      const image = new Image();
      // 解决跨域问题
      image.setAttribute("crossOrigin", "anonymous");
      const imageUrl = imgUrl;
      image.src = imageUrl;
      // image.onload为异步加载
      // eslint-disable-next-line no-undef
      image.onload = function () {
        var canvas = document.createElement("canvas");
        canvas.width = image.width;
        canvas.height = image.height;
        var context = canvas.getContext("2d");
        context.fillStyle = "#fff";
        context.fillRect(0, 0, canvas.width, canvas.height);

        // eslint-disable-next-line no-undef
        context.drawImage(image, 0, 0, image.width, image.height);
        var quality = 0.8;
        // 这里的dataurl就是base64类型
        // 使用toDataUrl将图片转换成jpeg的格式,不要把图片压缩成png,因为压缩成png后base64的字符串可能比不转换前的长!
        const dataurl = canvas.toDataURL("image/jpeg", quality);
        callback ? callback(dataurl) : null; //调用回调函数
      };
    },
base64DataURLToArrayBuffer(dataURL) {
      const base64Regex = /^data:image\/(png|jpeg|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;
    },
  • 加载文件
function loadFile(url, callback) {
  PizZipUtils.getBinaryContent(url, callback);
}
  • 导出方法
  renderDoc(record) {
      loadFile("demo.docx", function (error, content) {
        // 抛出异常
        if (error) {
          throw error;
        }
        const imageOpts = {
          getImage(tag) {
            return that.base64DataURLToArrayBuffer(tag);
          },
          getSize() {
            return [100, 160];
          },
        };
        const imageModule = new ImageModule(imageOpts);

        // 创建一个JSZip实例,内容为模板的内容
        var zip = new PizZip(content);
        // 创建并加载docxtemplater实例对象
        var doc = new Docxtemplater().loadZip(zip).attachModule(imageModule);
        // 设置模板变量的值

        doc.setData(this.renderData);

        try {
          // 用模板变量的值替换所有模板变量
          doc.render();
        } catch (error) {
          // The error thrown here contains additional information when logged with JSON.stringify (it contains a properties object containing all suberrors).
          function replaceErrors(key, value) {
            if (value instanceof Error) {
              return Object.getOwnPropertyNames(value).reduce(function (error, key) {
                error[key] = value[key];
                return error;
              }, {});
            }
            return value;
          }

          if (error.properties && error.properties.errors instanceof Array) {
            const errorMessages = error.properties.errors
              .map(function (error) {
                return error.properties.explanation;
              })
              .join("\n");
            console.log("errorMessages", errorMessages);
            // errorMessages is a humanly readable message looking like this : 'The tag beginning with "foobar" is unopened'
          }
          throw error;
        }
        // 生成一个代表docxtemplater对象的zip文件(不是一个真实的文件,而是在内存中的表示)
        var out = doc.getZip().generate({
          type: "blob",
          // type: "text/plain;charset=utf-8",
          mimeType:
            "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
        });

        // 将目标文件对象保存为目标类型的文件,并命名

        let fileName = `out.docx`;
        saveAs(out, fileName);
      });
    },
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值