MENU

使用原生 JS 实现 Echarts 数据导出 Excel 的功能

January 30, 2024 • Read: 2331 • 杂谈阅读设置

Echarts toolbox 增加数据导出 Excel 的功能

Echarts 的 toolbox 提供了很多工具,例如 saveAsImage(导出图片)、magicType(切换类型) 等,具体的可以参考 toolbox 官方文档。toolbox 原生提供的功能算是比较全面的了,但唯独缺少了一键将数据导出为 Excel 的功能。虽然可以通过 toolbox 中的 dataView(数据视图) 查看数据,然后复制粘贴到 Excel 中,但这种做法着实不够优雅。好在 toolbox 支持用户自定义工具。

在自定义功能之前,需要注意的是,自定义的工具名字,只能以 my 开头,例如 myTool1、myTool2......,具体示例可以参考 toolbox.feature 文档,示例代码如下:

  • toolbox: {
  • feature: {
  • myTool1: {
  • show: true,
  • title: '自定义扩展方法1',
  • icon: 'path://M432.45,595.444c0,2.177-4.661,6.82-11.305,6.82c-6.475,0-11.306-4.567-11.306-6.82s4.852-6.812,11.306-6.812C427.841,588.632,432.452,593.191,432.45,595.444L432.45,595.444z M421.155,589.876c-3.009,0-5.448,2.495-5.448,5.572s2.439,5.572,5.448,5.572c3.01,0,5.449-2.495,5.449-5.572C426.604,592.371,424.165,589.876,421.155,589.876L421.155,589.876z M421.146,591.891c-1.916,0-3.47,1.589-3.47,3.549c0,1.959,1.554,3.548,3.47,3.548s3.469-1.589,3.469-3.548C424.614,593.479,423.062,591.891,421.146,591.891L421.146,591.891zM421.146,591.891',
  • onclick: function () {
  • alert('myToolHandler1')
  • }
  • }
  • }
  • }

其中的重点就是 onclick 函数,我希望实现点击按钮自动下载 Excel 的功能,下面我先给出最终实现的代码:

  • myTool: {
  • show: true,
  • title: '导出EXCEL',
  • icon: 'path://M925.248 356.928l-258.176-258.176a64 64 0 0 0-45.248-18.752H144a64 64 0 0 0-64 64v736a64 64 0 0 0 64 64h736a64 64 0 0 0 64-64V402.176a64 64 0 0 0-18.752-45.248zM288 144h192V256H288V144z m448 736H288V736h448v144z m144 0H800V704a32 32 0 0 0-32-32H256a32 32 0 0 0-32 32v176H144v-736H224V288a32 32 0 0 0 32 32h256a32 32 0 0 0 32-32V144h77.824l258.176 258.176V880z',
  • onclick: function(opt) {
  • opt = opt.option;
  • var cell, csv, csvContent, encodedUri, head, i, j, k, len, line, lines, link, ref, s, tr, tr_list, value, x, y;
  • x = opt.xAxis[0].data
  • y = [
  • (function() {
  • var k, len, ref, results;
  • ref = opt.series;
  • results = [];
  • for (k = 0, len=ref.length; k < len; k++) {
  • i = ref[k];
  • results.push(i.name)
  • }
  • return results;
  • })()
  • ];
  • y[0].splice(0, 0, "日期");
  • value = [
  • (function() {
  • var k, len, ref, results;
  • ref = opt.series;
  • results = [];
  • for (k=0, len = ref.length; k < len; k++) {
  • i = ref[k];
  • results.push(i.data);
  • }
  • return results;
  • })()
  • ][0];
  • tr = "";
  • csvContent = "data:text/csv;charset=utf-8,%EF%BB%BF";
  • csv = y[0].join(",") + ",\n";
  • head = "<tr>";
  • ref = y[0];
  • for (k = 0, len = ref.length; k < len; k++) {
  • i = ref[k];
  • head += '<th>' + i + '</th>';
  • }
  • head += "</tr>";
  • tr_list = [];
  • i = 0;
  • lines = [];
  • while (i < value[0].length) {
  • j = 0;
  • tr = "";
  • tr += "<tr>";
  • tr += "<td>" + x[i].replace(/,/g, " ") + "</td>";
  • line = x[i].replace(/,/g, ' ');
  • while (j < value.length) {
  • cell = value[j][i];
  • tr += "<td>" + cell + "</td>";
  • line += ", " + cell;
  • j += 1;
  • }
  • line += "\n";
  • tr += "</tr>";
  • i += 1;
  • lines.push(line);
  • tr_list.push(tr);
  • }
  • csv += lines.join("");
  • encodedUri = csvContent + encodeURI(csv);
  • var downloadLink = document.createElement('a');
  • // 设置<a>元素的属性
  • downloadLink.href = encodedUri;
  • downloadLink.target = '_blank'; // 在新窗口中打开下载
  • downloadLink.download = '气井分类.csv'; // 设置下载文件的名称
  • // 将<a>元素添加到文档中
  • document.body.appendChild(downloadLink);
  • // 触发<a>元素的点击事件,开始下载
  • downloadLink.click();
  • // 下载完成后,从文档中移除<a>元素
  • document.body.removeChild(downloadLink);
  • }
  • }

从上往下看比较重要的几个参数,icon 顾名思义就是按钮的图标,我从阿里巴巴矢量图标库中选择了一个类似于 "保存" 的图标。onclick 函数可以传参数,这个参数具体代表什么我也不太清楚,在函数里 log 打印看看就清楚了,我个人觉得大概是类似于 this 之类的东西,里面保存了这个 echarts 对象的很多信息,其中就有完整的数据信息。csvContent 设置的是保存文件的类型,我保存的 csv 格式的文件,类型名和文件后缀名必须对应上,否则就会出问题。常见的文件类型可以看 MIME 类型列表。其实大体设计思路就是将数据编码为 HTML 的表格(前端不会展示该表格),最终下载这个表格,<th> 包裹的是最终导出 Excel 文件中每一列的列名。一个 < tr > 中是一种类别的数据,<tr > 中一般来说会有很多 < td>,每个 < td > 包裹的就是具体属于该类的每一个样本。我的数据如下图所示:

导出的 csv 如下所示:

后记

其实在网上搜 Echarts导出Excel 字样,有很多大佬给出了解决方案,有些是用了第三方库,有些是基于 Vue 的,但是由于笔者并不会 Vue,并且某些第三方库可能会和我本身的项目冲突,因此我才想着能否使用原生 JS 解决,不过由于我的 JS 水平也就属于半吊子,所以我自己写不出来,翻遍了搜索引擎也没找到用原生 JS 实现的代码。后来我是在 Echarts 的 Github Issues 中翻到了一位大佬的提问,从他的提问代码中窥探到了答案,在这里贴出这个 Issue,并且感谢下这位大佬

Archives Tip
QR Code for this page
Tipping QR Code