如何使用JavaScript实现前端导入和导出excel文件(H5编辑器实战复盘)

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
简介: 最近笔者终于把H5-Dooring的后台管理系统初步搭建完成, 有了初步的数据采集和数据分析能力, 接下来我们就复盘一下其中涉及的几个知识点,并一一阐述其在Dooring H5可视化编辑器中的解决方案. 笔者将分成3篇文章来复盘, 主要解决场景如下

网络异常,图片无法展示
|

前言


最近笔者终于把H5-Dooring的后台管理系统初步搭建完成, 有了初步的数据采集和数据分析能力, 接下来我们就复盘一下其中涉及的几个知识点,并一一阐述其在Dooring H5可视化编辑器中的解决方案. 笔者将分成3篇文章来复盘, 主要解决场景如下:


  • 如何使用JavaScript实现前端导入和导出excel文件(H5编辑器实战复盘)
  • 前端如何基于table中的数据一键生成多维度数据可视化分析报表
  • 如何实现会员管理系统下的权限路由和权限菜单


以上场景也是前端工程师在开发后台管理系统中经常遇到的或者即将遇到的问题, 本文是上述介绍中的第一篇文章, 你将收获:


  • 使用JavaScript实现前端导入excel文件并自动生成可编辑的Table组件
  • 使用JavaScript实现前端基于Table数据一键导出excel文件
  • XLSXjs-export-excel基本使用


正文


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


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



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


1.1 实现效果


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


网络异常,图片无法展示
|


编辑table组件:


网络异常,图片无法展示
|


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


网络异常,图片无法展示
|


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


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


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


网络异常,图片无法展示
|


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

// 解析并提取excel数据letreader=newFileReader();
reader.onload=function(e) {
letdata=e.target.result;
letworkbook=XLSX.read(data, {type: 'binary'});
letsheetNames=workbook.SheetNames; // 工作表名称集合letdraftObj= {}
sheetNames.forEach(name=> {
// 通过工作表名称来获取指定工作表letworksheet=workbook.Sheets[name]; 
for(letkeyinworksheet) {
// v是读取单元格的原始值if(key[0] !=='!') {
if(draftObj[key[0]]) {
draftObj[key[0]].push(worksheet[key].v)
        }else {
draftObj[key[0]] = [worksheet[key].v]
        }
      }
    }
  });
// 生成ant-table支持的数据格式letsourceData=Object.values(draftObj).map((item,i) => ({ key: i+'', name: item[0], value: item[1]}))

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


1.3 table表格的编辑功能实现


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


网络异常,图片无法展示
|


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


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


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


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


我们先看看f2的使用的数据格式:


constdata= [
  { 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';
importReact, { memo, useEffect, useRef } from'react';
importChartImgfrom'@/assets/chart.png';
importstylesfrom'./index.less';
import { IChartConfig } from'./schema';
interfaceXChartPropsextendsIChartConfig {
isTpl: boolean;
}
constXChart= (props: XChartProps) => {
const { isTpl, data, color, size, paddingTop, title } =props;
constchartRef=useRef(null);
useEffect(() => {
if (!isTpl) {
constchart=newChart({
el: chartRef.current||undefined,
pixelRatio: window.devicePixelRatio, // 指定分辨率      });
// step 2: 处理数据constdataX=data.map(item=> ({ ...item, value: Number(item.value) }));
// Step 2: 载入数据源chart.source(dataX);
// Step 3:创建图形语法,绘制柱状图,由 genre 和 sold 两个属性决定图形位置,genre 映射至 x 轴,sold 映射至 y 轴chart        .interval()
        .position('name*value')
        .color('name');
// Step 4: 渲染图表chart.render();
    }
  }, [data, isTpl]);
return (
<divclassName={styles.chartWrap}><divclassName={styles.chartTitle} style={{ color, fontSize: size, paddingTop }}>        {title}
</div>      {isTpl?<imgsrc={ChartImg} alt="dooring chart"/> : <canvasref={chartRef}></canvas>}</div>  );
};
exportdefaultmemo(XChart);

当然其他的可视化组件也可以用相同的模式封装,这里就不一一举例了. 以上的组件封装使用reacthooks组件, 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', 所以我们需要对数据格式进行转换, 具体实现如下:


constgenerateExcel= () => {
letoption= {};  //option代表的就是excel文件letdataTable= [];  //excel文件中的数据内容letlen=list.length;
if (len) {
for(leti=0; i<len; i++) {
letrow=list[i];
letobj:any= {};
for(letkeyinrow) {
if(typeofrow[key] ==='object') {
letarr=row[key];
obj[key] =arr.map((item:any) => (typeofitem==='object'?item.label : item)).join(',')
                }else {
obj[key] =row[key]
                }
            }
dataTable.push(obj);  //设置excel中每列所获取的数据源        }
    }
lettableKeys=Object.keys(dataTable[0]);
option.fileName=tableName;  //excel文件名称option.datas= [
          {
sheetData: dataTable,  //excel文件中的数据源sheetName: tableName,  //excel文件中sheet页名称sheetFilter: tableKeys,  //excel文件中需显示的列数据sheetHeader: tableKeys,  //excel文件中每列的表头名称          }
    ]
lettoExcel=newExportJsonExcel(option);  //生成excel文件toExcel.saveExcel();  //下载excel文件  }

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

所以, 今天你又博学了吗?


最后


以上教程笔者已经集成到H5-Dooring中,对于一些更复杂的交互功能,通过合理的设计也是可以实现的,大家可以自行探索研究。


github地址:H5在线编辑器H5-Dooring



目录
相关文章
|
2月前
|
JavaScript 前端开发 程序员
前端原生Js批量修改页面元素属性的2个方法
原生 Js 的 getElementsByClassName 和 querySelectorAll 都能获取批量的页面元素,但是它们之间有些细微的差别,稍不注意,就很容易弄错!
|
5天前
|
设计模式 数据安全/隐私保护
Next.js 实战 (七):浅谈 Layout 布局的嵌套设计模式
这篇文章介绍了在Next.js框架下,如何处理中后台管理系统中特殊页面(如登录页)不包裹根布局(RootLayout)的问题。作者指出Next.js的设计理念是通过布局的嵌套来创建复杂的页面结构,这虽然保持了代码的整洁和可维护性,但对于特殊页面来说,却造成了不必要的布局包裹。文章提出了一个解决方案,即通过判断页面的skipGlobalLayout属性来决定是否包含RootLayout,从而实现特殊页面不包裹根布局的目标。
49 33
|
12天前
|
前端开发 API 开发者
Next.js 实战 (五):添加路由 Transition 过渡效果和 Loading 动画
这篇文章介绍了Framer Motion,一个为React设计的动画库,提供了声明式API处理动画和页面转换,适合创建响应式用户界面。文章包括首屏加载动画、路由加载Loading、路由进场和退场动画等主题,并提供了使用Framer Motion和next.js实现这些动画的示例代码。最后,文章总结了这些效果,并邀请读者探讨更好的实现方案。
|
10天前
|
JavaScript 前端开发 API
Next.js 实战 (六):如何实现文件本地上传
这篇文章介绍了在Next.js中如何实现文件上传到本地的方法。文章首先提到Next.js官方文档中没有提供文件上传的实例代码,因此开发者需要自行实现,通常有两种思路:使用Node.js原生上传或使用第三方插件如multer。接着,文章选择了使用Node.js原生上传的方式来讲解实现过程,包括如何通过哈希值命名文件、上传到指定目录以及如何分类文件夹。然后,文章展示了具体的实现步骤,包括编写代码来处理文件上传,并给出了代码示例。最后,文章通过一个效果演示说明了如何通过postman模拟上传文件,并展示了上传后的文件夹结构。
|
1月前
Next.js 实战 (二):搭建 Layouts 基础排版布局
本文介绍了作者在Next.js v15.x版本发布后,对一个旧项目的重构过程。文章详细说明了项目开发规范配置、UI组件库选择(最终选择了Ant-Design)、以及使用Ant Design的Layout组件实现中后台布局的方法。文末展示了布局的初步效果,并提供了GitHub仓库链接供读者参考学习。
Next.js 实战 (二):搭建 Layouts 基础排版布局
|
2月前
|
JavaScript 前端开发 Java
springboot解决js前端跨域问题,javascript跨域问题解决
本文介绍了如何在Spring Boot项目中编写Filter过滤器以处理跨域问题,并通过一个示例展示了使用JavaScript进行跨域请求的方法。首先,在Spring Boot应用中添加一个实现了`Filter`接口的类,设置响应头允许所有来源的跨域请求。接着,通过一个简单的HTML页面和jQuery发送AJAX请求到指定URL,验证跨域请求是否成功。文中还提供了请求成功的响应数据样例及请求效果截图。
springboot解决js前端跨域问题,javascript跨域问题解决
|
1月前
|
存储 网络架构
Next.js 实战 (四):i18n 国际化的最优方案实践
这篇文章介绍了Next.js国际化方案,作者对比了网上常见的方案并提出了自己的需求:不破坏应用程序的目录结构和路由。文章推荐使用next-intl库来实现国际化,并提供了详细的安装步骤和代码示例。作者实现了国际化切换时不改变路由,并把当前语言的key存储到浏览器cookie中,使得刷新浏览器后语言不会失效。最后,文章总结了这种国际化方案的优势,并提供Github仓库链接供读者参考。
|
1月前
Next.js 实战 (三):优雅的实现暗黑主题模式
这篇文章介绍了在Next.js中实现暗黑模式的具体步骤。首先,需要安装next-themes库。然后,在/components/ThemeProvider/index.tsx文件中新增ThemeProvider组件,并在/app/layout.tsx文件中注入该组件。如果想要加入过渡动画,可以修改代码实现主题切换时的动画效果。最后,需要在需要的位置引入ThemeModeButton组件,实现暗黑模式的切换。
|
2月前
|
缓存 JavaScript 前端开发
JavaScript 与 DOM 交互的基础及进阶技巧,涵盖 DOM 获取、修改、创建、删除元素的方法,事件处理,性能优化及与其他前端技术的结合,助你构建动态交互的网页应用
本文深入讲解了 JavaScript 与 DOM 交互的基础及进阶技巧,涵盖 DOM 获取、修改、创建、删除元素的方法,事件处理,性能优化及与其他前端技术的结合,助你构建动态交互的网页应用。
63 5
|
2月前
|
设计模式 前端开发 JavaScript
JavaScript设计模式及其在实战中的应用,涵盖单例、工厂、观察者、装饰器和策略模式
本文深入探讨了JavaScript设计模式及其在实战中的应用,涵盖单例、工厂、观察者、装饰器和策略模式,结合电商网站案例,展示了设计模式如何提升代码的可维护性、扩展性和可读性,强调了其在前端开发中的重要性。
44 2