1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > 如何使用JavaScript实现前端导入和导出excel文件

如何使用JavaScript实现前端导入和导出excel文件

时间:2022-03-25 01:07:12

相关推荐

如何使用JavaScript实现前端导入和导出excel文件

本文转载自【微信公众号:趣谈前端,ID:beautifulFront】经微信公众号授权转载,如需转载与原文作者联系

正文

本文接下来的内容素材都是基于H5可视化编辑器(H5-Dooring)项目的截图, 如果想实际体验, 可以访问H5-Dooring网站实际体验. 接下来我们直接开始我们的方案实现.

1. 使用JavaScript实现前端导入excel文件并自动生成可编辑的Table组件

在开始实现之前, 我们先来看看实现效果.

1.1 实现效果

导入excel文件并通过antd的table组件渲染table:

编辑table组件:

保存table数据后实时渲染可视化图表:

以上就是我们实现导入excel文件后, 编辑table, 最后动态生成图表的完整流程.

1.2 实现一键导入excel文件并生成table表格

导入excel文件的功能我们可以用javascript原生的方式实现解析, 比如可以用fileReader这些原生api,但考虑到开发效率和后期的维护, 笔者这里采用antd的Upload组件和XLSX来实现上传文件并解析的功能. 由于我们采用antd的table组件来渲染数据, 所以我们需要手动将解析出来的数据转换成table支持的数据格式.大致流程如下:

所以我们需要做的就是将Upload得到的文件数据传给xlsx, 由xlsx生成解析对象, 最后我们利用javascript算法将xlsx的对象处理成ant-table支持的数据格式即可. 这里我们用到了FileReader对象, 目的是将文件转化为BinaryString, 然后我们就可以用xlsx的binary模式来读取excel数据了, 代码如下:

// 解析并提取excel数据let reader = new FileReader();reader.on​load = function(e) {let data = e.target.result; let workbook = XLSX.read(data, {type: inary}); let sheetNames = workbook.SheetNames; // 工作表名称集合 let draftObj = {} sheetNames.forEach(name => { // 通过工作表名称来获取指定工作表 let worksheet = workbook.Sheets[name];for(let key in worksheet) {// v是读取单元格的原始值if(key[0] !== !) { if(draftObj[key[0]]) {draftObj[key[0]].push(worksheet[key].v) }else {draftObj[key[0]] = [worksheet[key].v] }} } }); // 生成ant-table支持的数据格式 let sourceData = Object.values(draftObj).map((item,i) => ({ key: i + \, name: item[0], value: item[1]}))

复制代码

经过以上处理, 我们得到的sourceData即是ant-table可用的数据结构, 至此我们就实现了表格导入的功能.

1.3 table表格的编辑功能实现

table表格的编辑功能实现其实也很简单, 我们只需要按照antd的table组件提供的自定义行和单元格的实现方式即可. antd官网上也有实现可编辑表格的实现方案, 如下:

大家感兴趣的可以私下研究以下. 当然自己实现可编辑的表格也很简单, 而且有很多方式, 比如用column的render函数来动态切换表格的编辑状态, 或者使用弹窗编辑等都是可以的.

1.4 根据编辑的table数据动态生成图表

根据table数据动态生成图表这块需要有一定的约定, 我们需要符合图表库的数据规范, 不过我们有了table数据, 处理数据规范当然是很简单的事情了, 笔者的可视化库采用antv的f2实现, 所以需要做一层适配来使得f2能消费我们的数据.

还有一点就是为了能使用多张图表, 我们需要对f2的图表进行统一封装, 使其成为符合我们应用场景的可视化组件库. 我们先看看f2的使用的数据格式:

const data = [{ genre: Sports, sold: 275 }, { genre: Strategy, sold: 115 }, { genre: Action, sold: 120 }, { genre: Shooter, sold: 350 }, { genre: Other, sold: 150 }];

复制代码

此数据格式会渲染成如下的图表:

所以说我们总结下来其主要有2个纬度的指标, 包括它们的面积图, 饼图, 折线图, 格式都基本一直, 所以我们可以基于这一点封装成组件的可视化组件, 如下:

import { Chart } from @antv/f2;import React, { memo, useEffect, useRef } from eact;import ChartImg from @/assets/chart.png;import styles from ./index.less;import { IChartConfig } from ./schema;interface XChartProps extends IChartConfig {isTpl: boolean;}const XChart = (props: XChartProps) => { const { isTpl, data, color, size, paddingTop, title } = props; const chartRef = useRef(null); useEffect(() => { if (!isTpl) {const chart = new Chart({ el: chartRef.current || undefined, pixelRatio: window.devicePixelRatio, // 指定分辨率});// step 2: 处理数据const dataX = data.map(item => ({ ...item, value: Number(item.value) }));// Step 2: 载入数据源chart.source(dataX);// Step 3:创建图形语法,绘制柱状图,由 genre 和 sold 两个属性决定图形位置,genre 映射至 x 轴,sold 映射至 y 轴chart .interval() .position( ame*value) .color( ame);// Step 4: 渲染图表chart.render(); } }, [data, isTpl]); return ( <div className={styles.chartWrap}><div className={styles.chartTitle} style={{ color, fontSize: size, paddingTop }}> {title}</div>{isTpl ? <img src={ChartImg} alt="dooring chart" /> : <canvas ref={chartRef}></canvas>} </div> );};export default memo(XChart);

复制代码

当然其他的可视化组件也可以用相同的模式封装,这里就不一一举例了. 以上的组件封装使用react的hooks组件, vue的也类似, 基本原理都一致.

2. 使用JavaScript实现前端基于Table数据一键导出excel文件

同样的, 我们实现将table数据一键导出为excel也是类似, 不过方案有所不同, 我们先来看看在Dooring中的实现效果.

2.1 一键导出为excel实现效果

以上就是用户基于后台采集到的数据, 一键导出excel文件的流程, 最后一张图是生成的excel文件在office软件中的呈现.

2.2 使用javascript实现一键导出excel文件功能

一键导出功能主要用在H5-Dooring的后台管理页面中, 为用户提供方便的导出数据能力. 我们这里导出功能也依然能使用xlsx来实现, 但是综合对比了一下笔者发现有更简单的方案, 接下来笔者会详细介绍, 首先我们还是来看一下流程:

很明显我们的导出流程比导入流程简单很多, 我们只需要将table的数据格式反编译成插件支持的数据即可. 这里笔者使用了js-export-excel来做文件导出, 使用它非常灵活,我们可以自定义:

自定义导出的excel文件名自定义excel的过滤字段自定义excel文件中每列的表头名称由于js-export-excel支持的数据结构是数组对象, 所以我们需要花点功夫把table的数据转换成数组对象, 其中需要注意的是ant的table数据结构中键对应的值可以是数组, 但是js-export-excel键对应的值是字符串, 所以我们要把数组转换成字符串,如[a,b,c]变成a,b,c, 所以我们需要对数据格式进行转换, 具体实现如下:

const generateExcel = () => {let option = {}; //option代表的就是excel文件 let dataTable = []; //excel文件中的数据内容 let len = list.length; if (len) { for(let i=0; i<len; i++) { let row = list[i]; let obj:any = {}; for(let key in row) {if(typeof row[key] === object) {let arr = row[key];obj[key] = arr.map((item:any) => (typeof item === object ? item.label : item)).join(,)}else {obj[key] = row[key]} } dataTable.push(obj); //设置excel中每列所获取的数据源 } } let tableKeys = Object.keys(dataTable[0]); option.fileName = tableName; //excel文件名称 option.datas = [{ sheetData: dataTable, //excel文件中的数据源 sheetName: tableName, //excel文件中sheet页名称 sheetFilter: tableKeys, //excel文件中需显示的列数据 sheetHeader: tableKeys, //excel文件中每列的表头名称} ] let toExcel = new ExportJsonExcel(option); //生成excel文件 toExcel.saveExcel(); //下载excel文件 }

复制代码

注意, 以上笔者实现的方案对任何table组件都使用, 可直接使用以上代码在大多数场景下使用. 至此, 我们就实现了使用JavaScript实现前端导入和导出excel文件的功能.

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。