vue 项目前端导出word文档

首先安装以下的结构包分别是

手打的可能不太对 然后第一个建议装3.5 不然后面会有报错(我出现了 不知道大家会不会出现)

npm i docxtemplater@3.5
npm i file-saver
npm i jszip-utils
npm i open-docxtemplater-image-module
npm i pizzip

然后就是我们的代码了 我就不分开截图了 全丢的一起 不出意外的话 应该拿过去能直接跑的

我的使用环境是 表格里面有图片

<template>
  <div class="myfiletest-container">
    <el-button type="primary" @click="exportWord">下载模板</el-button>
  </div>
</template>

<script>
import docxtemplater from "docxtemplater";
import PizZip from "pizzip";
import JSZipUtils from "jszip-utils";
import { saveAs } from "file-saver";
//import ImageModule from "docxtemplater-image-module-free";

export default {
  data() {
    return {
      data: {
        table: [
          {
            index: 1,
            tablename: "测试1",
            tabledesc: "测试1的描述",
            tableimg:
              "网络链接",
          },
          {
            index: 2,
            tablename: "测试2",
            tabledesc: "测试2的描述",
            tableimg:
              "网络连接",
          },
        ],
      },
    };
  },
  mounted() {
    this.changedata();
  },
  methods: {
    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;
      }
      console.log(bytes.buffer);
      return bytes.buffer;
    },
    getBase64Image(src, wordList, i) {
      let _this = this
      var image = new Image();
      // image.src = src + '?v=' + Math.random(); // 处理缓存
      image.src = src
      image.setAttribute("crossOrigin", '*');  // 支持跨域图片
      image.onload = async function() {
        let base64 = ""
        var canvas = document.createElement("canvas");
        canvas.width = image.width;
        canvas.height = image.height;
        var ctx = canvas.getContext("2d");
        ctx.drawImage(image, 0, 0, image.width, image.height);
        base64 = await canvas.toDataURL("image/png");  // 可选其他值 image/jpeg
        wordList[i].tableimg = base64
        // 这里调用的原因是防止tableimg还未转换成base64就调用exportWord接口
        if(i == _this.data.table.length - 1) {
         //_this.exportWord()
        }
        return base64;
      }
      // 图片加载失败警告
      image.onerror = function() {
        wordList[i].tableimg = ''
        if(i == _this.data.table.length - 1) {
          //_this.exportWord()
          return
        }

      }
    },

    changedata() {
      let temp = this.data.table;
      for (let i = 0; i < temp.length; i++) {
        this.getBase64Image(temp[i].tableimg,temp,i);
      }
      console.log(temp[0].tableimg);
    },
    // 点击导出word
    exportWord() {
      //图片
      var ImageModule = require("open-docxtemplater-image-module");
      let that = this;
      // 读取并获得模板文件的二进制内容
      //../../assets/file/
      console.log(JSZipUtils);
      JSZipUtils.getBinaryContent("demo.docx", function (error, content) {
        // model.docx是模板。我们在导出的时候,会根据此模板来导出对应的数据
        // 抛出异常
        console.log(content);
        if (error) {
          throw error;
        }
        // 图片处理
        let opts = {};
        opts.centered = true; // 图片居中,在word模板中定义方式为{%%image}
        opts.fileType = "docx";
        opts.getImage = function (chartId) {
          return that.base64DataURLToArrayBuffer(chartId);
        };
        opts.getSize = function () {
          return [200, 200];
        };
        let imageModule = new ImageModule(opts);
        // 创建一个PizZip实例,内容为模板的内容
        let zip = new PizZip(content);
        // 创建并加载docxtemplater实例对象
        let doc = new docxtemplater();
        doc.loadZip(zip);
        doc.attachModule(imageModule);

        // 设置模板变量的值
        setTimeout(() => {
          doc.setData({
            table: that.data.table,
          });

          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, "111.docx");
        }, 0);
      });
    },
  },
};
</script>

<style lang="scss" scoped>
.myfiletest-container {
  
}
</style>
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值