vue导出echarts图表及文本到word

实现这个功能我们用到一个插件 docxtemplater

一.引入包

import PizZip from 'pizzip'
import docxtemplater from 'docxtemplater'
import JSZipUtils from 'jszip-utils'
import { saveAs } from 'file-saver'

二.建立本地的模板(变量渲染到里面)

可以把模板放到项目里

vue导出echarts图表及文本到word_第1张图片

三.代码

data() {
    return {
      // 表单对象,一一对应模板中变量
      form: {
        custName: "杰克", // 客户姓名
        phoneNumber: "1234567890", // 联系方式
        projectRequirement: "为了更美好的明天而战", // 项目要求
        totalPrice: 666, // 合计报价
      },
      // 表格信息
      tableData: [],
      //图片
      img1: '',
      img2: ''
    };
  },
此处渲染规则
单个变量模板中直接用{}
表格变量对应{#table} {/table}
图片{%}   图片渲染,先把echarts转换为base64格式,再到模板上解码
图片居中{%%}
// ECHARTS图表的图片并转为base64格式
    this.img2 = myChart2.getDataURL({
      pixelRatio: 2,      // 导出的图片分辨率比例,默认为 1。
      backgroundColor: '#fff'   // 导出的图片背景色,默认使用 option 里的 backgroundColor
    });
// 导出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: function() {
      //这里要引入处理图片的插件,下载docxtemplater后,引入的就在其中了
      var ImageModule = require('docxtemplater-image-module-free');
      var fs = require("fs");
      const expressions = require("angular-expressions");

      let _this = this;

      // 读取并获得模板文件的二进制内容,放在项目中即可
      JSZipUtils.getBinaryContent("input.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) {
          //自定义指定图像大小,此处可动态调试各别图片的大小
          if (tagName === "img2") return [400,250];
          return [600,350];
        }

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

        console.log(_this.logo);

        // 设置模板变量的值
        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, "demo.docx");
      });
    }
导出显示

vue导出echarts图表及文本到word_第2张图片
vue导出echarts图表及文本到word_第3张图片

你可能感兴趣的:(vue,echarts)