js-xlsx + handsontable + echarts实现excel上传编辑然后显示成图表

js-xlsx + handsontable + echarts 实现在前端导入excel数据并生成echart报表

前言

最近都在做类似 ERP 的项目,所以呢,又碰到一个比较变态的需求(至少对我来说是),在前端导入 excel 文件,
然后在浏览器里面预览和编辑, 最后再选择一些数据,用echarts生成报表.

依赖

js-xlsx 读取excel数据到js

handsontable 类似Excel一样显示和编辑列表数据

echarts 一个生成各种报表的库

数据导入

数据导入这边需要用到 浏览器的 FileReader对象readAsBinaryString() 函数, 把选择的文件读取出来,
然后再监听 FileReader 对象的 onload 事件 , 在 onload 事件 的回调函数中,我们可以获取到 读取的二进制数据.
这里顺便提一下, FileReader 对象提供以下方法,用来读取各种格式的数据(参考自MDN)

FileReader.readAsArrayBuffer() // 读取文件的 ArrayBuffer 数据对象.

FileReader.readAsBinaryString() // 读取文件的原始二进制数据

FileReader.readAsDataURL() // 返回一个URL格式的字符串以表示所读取文件的内容

FileReader.readAsText() // 返回一个字符串以表示所读取的文件内容

tips: 需要注意的是 readXxxxx() 函数,是不直接返回读取结果的,因为读取这个动作异步的.

readAsBinaryString 读取到的内容应该是一个二进制的字符串,这个时候,需要调用 js-xlsx
read 方法, read 返回的是一个可读性很强的对象了,我看了一下,里面有关于表格的属性很多都有
,如 样式, vsb宏, sheets等等 (反正我对excel也不熟,认识的也就这些哈),

npm i xlsx
import XLSX from 'xlsx'
...
let res = XLSX.read(data, {type: 'binary'})
let sheetName = res.Sheets[res.SheetNames[0]]
let table = XLSX.utils.sheet_to_json(sheetName, {header: 'A', raw: true, defval: ' '})

这里的 res 得到的我猜是 excel 表格原有的数据,里面包含上面说的很多种数据,而正常情况下,
我们需要的往往只是第一个 sheet 里面的 纯数据, 所以调用 XLSX.utils.sheet_to_json
获取第一个 sheet 的数据, table 拿到的应该是一个我们熟悉的数组了.这个时候如果你只是单纯的渲染的话,
你甚至可以就此打住,自己写一个渲染方法(比如字符串拼接哈)把数据渲染出来即可.

如果单纯的显示无法满足你的需求,那么你可能需要 handsontable 了.

tips: sheet_to_json 的 第二个参数里面的 header,可以传数字,也可以转 'A', 两个的主要区别在于转化出来的表第一行如果是空行会不会正常显示,
传 'A' 会正常显示,传数字的话,如果表格的第一行有空白单元格,表格会错乱。

数据展示

首先当然是安装,我的项目是基于 vue 的,所以要安装 vue 版本的,其他框架的,只要安装响应的版本即可.

npm i @handsontable/vue

然后就可以直接这么用

<template>
 <HotTable :settings="settings"></HotTable>
</template>

<script>
import HotTable from '@handsontable/vue'
export default {
  ...
  components: {HotTable}
  ...
}
</script>

模板里面的 settings 是 handsontable 的一些配置, 每个项目的需求不同,配置也不同,这里就不列举出来了, 上面获取到的 table 在这里要赋值给 settings.data

我这里用 handsontable 显示数据的目的,是让用户可以清晰的看到上传的表的数据和结构,可以删除屌部分无用的数据,减少冗余。

生成报表

数据都处理完了之后,就是生成报表了, 报表这里稍微做的灵活了一点,是要让用户根据上传的数据,自己选择字段,然后用 echart 去生成对应的报表。

为了<del>偷懒</del>降低复杂度,我这里只提供了3种报表类型供选择,分别是 饼图,柱状图,折线图,稍微分析 echart 的配置手册,我发现各种类型的图表,
其实主要的区别在 series 配置项下面,其他位置几乎没啥区别 <del>就算有区别,也被我无视</del> 。最终的实现大概是这样

let option = {
  title: {...},
  tooltip: {...},
  xAxis: {...},
  yAxis: {...},
  toolbox: {...},
}

switch (type) {
  case 'pie' : 
    option.series = {...}
    break
  case 'pie' : 
    option.series = {...}
    break
  case 'pie' : 
    option.series = {...}
    break
}

myChart.setOption(option)

echart 第一次渲染完以后,如果改变 option 的数据然后重新渲染,新的 option 数据是采用追加的方式加进去的,类似 javascript 的 Object.assign(),
所以如果新的数据没办法完全覆盖掉就旧的数据的话,旧的那些没有被覆盖掉的数据,还会渲染出来. 我对这种情况的处理方法是调用 dispose.dispose() 把实例销毁掉,
然后重新创建一个新实例,设置新的 option

最后

源码再这里记得star 和follow哦。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,236评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,867评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,715评论 0 340
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,899评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,895评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,733评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,085评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,722评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,025评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,696评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,816评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,447评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,057评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,009评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,254评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,204评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,561评论 2 343

推荐阅读更多精彩内容