【前端】批量将echarts图表以word方式导出

1.使用技术

vue+docxtemplater

2.需要安装依赖

(1)依赖版本
"docxtemplater": "^3.30.0",
"docxtemplater-image-module-free": "^1.1.1",
"file-saver": "^2.0.5",
"jszip": "^2.6.0",
"jszip-utils": "^0.1.0",
"pizzip": "^3.1.1",
复制代码
(2)安装依赖
npm install jszip-utils --save 
​
npm install jszip --save
​
npm install file-saver --save
​
npm install --save docxtemplater-image-module-free 
复制代码

3.引入所需依赖

import { saveAs } from 'file-saver';
​
const Docxtemplater = require('docxtemplater');
​
const JSZipUtils = require('jszip-utils');
​
const PizZip = require('pizzip');
复制代码

4.将echarts图表转为base64

方法一: 利用canvas的toDataURL()

export function echartsBase64 (className) {
 const [...baseCancas] = document.querySelectorAll(className);
 return baseCancas.map((item) => {
  return item.getElementsByTagName('canvas')[0].toDataURL();
 });
}
复制代码

方法二:echarts的getDataURL方法,此方法可设置导出图表背景色

export function echartsBase64 (instance) {
​
 return instance.map(item => {
​
  const img = new Image();
​
  img.src = item.$children[0].getDataURL({
​
   pixelRatio: 2,
​
   backgroundColor: '#0D283E '
​
  });
​
  return img.src;
​
 });
​
}
复制代码

5.base64放入word中的方法

function base64DataURLToArrayBuffer (dataURL) {
​
 console.log('写入图片成功');
​
 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 = Buffer.from(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;
​
}
复制代码

6.利用docxtemplater-image-module-free处理图片进行导出

export async function exportEchartsDocx (imagesSrc, fileName = '图形导出') {
​
 const ImageModule = require('docxtemplater-image-module-free');
​
 JSZipUtils.getBinaryContent('echarts.docx', async function (error, content) {
​
  // model.docx是模板。我们在导出的时候,会根据此模板来导出对应的数据
​
  // 抛出异常
​
  if (error) {
​
   throw error;
​
  }
​
  // 创建一个PizZip实例,内容为模板的内容
​
  const zip = new PizZip(content);
​
  // 创建并加载docxtemplater实例对象
​
  const doc = new Docxtemplater().loadZip(zip);
​
  // 图片处理
​
  const opts = {};
​
  opts.centered = true; // 图片居中,在word模板中定义方式为{%image}
​
  opts.fileType = 'docx';
​
  opts.getImage = function (chartId) {
​
   return base64DataURLToArrayBuffer(chartId);
​
  };
​
  opts.getSize = function () {
​
   return [480, 240];
​
  };
​
  let imageModule = new ImageModule(opts);
​
  doc.attachModule(imageModule);
​
  // 设置模板变量的值,主要就是把图片地址去转成base64后,在存给src
​
  let base64List = [];
​
  imagesSrc.forEach(item => {
​
   base64List.push({
​
•    'src': item
​
   });
​
  });
​
  console.log(base64List);
​
  let docxData = {
​
   images: [...base64List] // 批量图片 模板里复杂一些  {#images} {%src} {/images}
​
  };
​
  doc.setData({
​
   ...docxData
​
  });
​
  // debugger;
​
  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.message }));
​
   throw error;
​
  }
​
  // 生成一个代表docxtemplater对象的zip文件(不是一个真实的文件,而是在内存中的表示)
​
  let out = doc.getZip().generate({
​
   type: 'blob',
​
   mimeType: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
​
  });
​
  // 将目标文件对象保存为目标类型的文件,并命名
​
  saveAs(out, fileName);
​
 });
​
}
复制代码

7.在public中放入docx后缀的模板

企业微信截图_16552656801599.png

猜你喜欢

转载自juejin.im/post/7109312156956360712