react+antd 导出excel文件(简单数据&多级表头)
需求:
在基于react+antd进行开发的页面中,实现导出excel报表的功能
实际场景:
1.简单数据:单层表头+数据
2.复杂数据:多层表头+数据
实现方式:
1.简单数据
简单数据的导出使用了js-export-excel插件,需要自己转换表头数据与表格数据,代码如下:
import { useState } from 'react';
import { message, Button } from 'antd';
import ExportJsonExcel from 'js-export-excel';
import type { RequestData } from '@/utils/request';
import type { ProjectInfoParams } from '@/services/summary';
import type { PaginationProps } from 'antd';
import { downloadChannelSettle } from '@/services/xxx'; // 接口地址 interface DownloadEffortsProps {
columnsData: any[];
totalList?: any[];
tableParams?: ProjectInfoParams & PaginationProps & { order?: string; sort?: string };
}
const DownloadEfforts: React.FC<DownloadEffortsProps> = (props) => {
const { columnsData, tableParams } = props; // 按钮loading
const [downLoading, setDownLoading] = useState<boolean>(false); // 下载结算申请报表
const downloadEffectExcel = async () => {
// 请求所有数据
const downloadParams = { ...tableParams, current: 1, pageSize: 0, pageNum: 1 };
// 开启按钮loading
setDownLoading(true);
try {
const res: RequestData = await downloadChannelSettle(downloadParams);
if (res.result) {
const { tableList } = res.result;
// 表头数组去掉操作栏
const newestHeaderList = columnsData.filter((arr: any) => arr.valueType !== 'option');
// 导出报表的表头与数据的处理
const resultData: any[] = [];
if (tableList) {
tableList.forEach((item: any, index: number) => {
const resultItem = {};
newestHeaderList.forEach((el: any, i: number) => {
if (newestHeaderList[i].title) {
resultItem[newestHeaderList[i].title] =
tableList[index][newestHeaderList[i].dataIndex];
}
});
resultData.push(resultItem);
});
}
const newHeader = newestHeaderList.map((item: any) => item.title);
const option = {
fileName: '导出数据', // 文件名字
datas: [
{
sheetData: resultData, // 数据
sheetName: 'sheet',
sheetFilter: newHeader, // 表头
sheetHeader: newHeader, // 表头
},
],
};
const toExcel = new ExportJsonExcel(option);
toExcel.saveExcel();
} else {
message.error('下载失败!');
}
} catch (error) {
//
} finally {
// 关闭按钮loading
setDownLoading(false);
}
}; return (
<Button key="downloadExcel" type="ghost" onClick={downloadEffectExcel} loading={downLoading}>
下载报表
</Button>
);
};
export default DownloadEfforts;
2.复杂数据
复杂数据,我只处理了多层表头的情况,table组件展示如图:
因为js-export-excel插件无法直接导出多层表头的数据(并且产品要求excel文件要与table展示布局相同),因此选用了react-html-table-to-excel插件进行开发,代码如下:
import { useState, useRef, useEffect } from 'react';
import { isEmpty } from 'lodash';
import { message, Table, Button } from 'antd';
import ReactHTMLTableToExcel from 'react-html-table-to-excel';
import type { RequestData } from '@/utils/request';
import type { ParamsType } from '@ant-design/pro-provider';
import type { PaginationProps } from 'antd';
import { downloadChannelGoBackReport } from '@/services/xxx';
import type { SettleApplicationParams } from '@/services/xxx'; interface DownloadEffortsProps {
columnsData: any[];
totalList?: any[];
tableParams?: ParamsType & PaginationProps & { order?: string; sort?: string; month?: string[] };
}
const DownloadEfforts: React.FC<DownloadEffortsProps> = (props) => {
const { columnsData, tableParams } = props;
const buttonRef = useRef<any>(null);
const tableRef = useRef<any>(null);
const [tableData, setTableData] = useState<SettleApplicationParams[]>([]); // 按钮loading
const [downLoading, setDownLoading] = useState<boolean>(false); // 下载报表
const downloadEffectExcel = async (e: any) => {
e.stopPropagation();
// 请求所有数据
const downloadParams = { ...tableParams, current: 1, pageSize: 0, pageNum: 1 };
if (downloadParams.month && !isEmpty(downloadParams.month)) {
// 开启按钮loading
setDownLoading(true);
try {
const res: RequestData = await downloadChannelGoBackReport(downloadParams);
if (res.result) {
const { tableList } = res.result;
setTableData(tableList);
} else {
message.error('下载失败!');
setDownLoading(false);
}
} catch (error) {
//
}
} else {
message.error('查询时间不能为空');
}
}; useEffect(() => {
// 拿到本次请求的数据后,再进行下载
if (columnsData.length > 0 && tableData.length > 0) {
const table = tableRef?.current?.querySelector('table');
table.setAttribute('id', 'table-to-xls');
buttonRef.current.handleDownload();
// 关闭按钮loading
setDownLoading(false);
// 下载完后,清除数据
setTimeout(() => {
setTableData([]);
}, 0);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [tableData]) useEffect(() => {
// 禁止组件按钮的默认点击事件(因为ts默认用的是Element,需要声明为HTMLElement)
const button = document.querySelector('#test-table-xls-button') as HTMLElement;
if (button) button.style['pointer-events'] = ('none');
}, []); return (<>
<Button key="downloadExcel" type="ghost" onClick={(e) => downloadEffectExcel(e)} loading={downLoading}>
下载报表
</Button>
<span style={{ visibility: 'hidden' }}>
<ReactHTMLTableToExcel
ref={buttonRef}
key="downloadExcel"
id="test-table-xls-button"
className="ant-btn"
table="table-to-xls"
filename="报表"
sheet="报表"
buttonText="下载报表"
/>
</span>
<div ref={tableRef} style={{ position: 'absolute', zIndex: -1, top: 0, left: 0, width: 0, height: 0 }}>
<Table
rowKey='id'
columns={columnsData.filter((arr: any) => arr.valueType !== 'option')}
dataSource={tableData}
/>
</div>
</>
);
};
export default DownloadEfforts;
最终导出效果:
【ps】:因为YYYY-MM格式的表头数据会在导出时自动转格式(如上图),因此可以在表头处理时手动转为【YYYY年MM月】的格式避免此类情况。
参考文档:https://blog.csdn.net/weixin_44240581/article/details/115265810
这两个依赖的配置项很接近,肉眼可以明确属性名的含义,不做赘述。
react+antd 导出excel文件(简单数据&多级表头)的更多相关文章
- POI导出大量数据的简单解决方案(附源码)-Java-POI导出大量数据,导出Excel文件,压缩ZIP(转载自iteye.com)
说明:我的电脑 2.0CPU 2G内存 能够十秒钟导出 20W 条数据 ,12.8M的excel内容压缩后2.68M 我们知道在POI导出Excel时,数据量大了,很容易导致内存溢出.由于Excel ...
- java POI导出Excel文件数据库的数据
在web开发中,有一个经典的功能,就是数据的导入导出.特别是数据的导出,在生产管理或者财务系统中用的非常普遍,因为这些系统经常要做一些报表打印的工作.这里我简单实现导出Excel文件. POI jar ...
- JavaScript 上万条数据 导出Excel文件(改装版)
最近项目要js实现将数据导出excel文件,网上很多插件实现~~那个开心呀,谁知道后面数据量达到上万条时出问题:浏览器不仅卡死,导出的excel文件一直提示网络失败.... debug调试发现var ...
- JavaScript 上万条数据 导出Excel文件 页面卡死
最近项目要js实现将数据导出excel文件,网上很多插件实现~~那个开心呀,谁知道后面数据量达到上万条时出问题:浏览器不仅卡死,导出的excel文件一直提示网络失败.... debug调试发现var ...
- 纯前端实现数据导出excel文件
一 安装依赖 npm install -S file-saver xlsx npm install -D script-loader 二 新建文件夹 在网上百度引入即可 三 在main.js中引入 ...
- PHP导出excel文件,第一步先实现PHP模板导出不带数据
今天继续研究PHP导出excel文件,把复杂的事情简单化,一步步实现功能,首先实现模板文件的导出,随后再实现写入数据后导出,最终实现功能,这是基本思路.中间可以加一步,先自己写入数据导出试试,随后再数 ...
- 前端必读3.0:如何在 Angular 中使用SpreadJS实现导入和导出 Excel 文件
在之前的文章中,我们为大家分别详细介绍了在JavaScript.React中使用SpreadJS导入和导出Excel文件的方法,作为带给广大前端开发者的"三部曲",本文我们将为大家 ...
- PHPExcel导出excel文件
今天园子刚开,先来个货顶下,后续园丁qing我会再慢慢种园子的,希望大家多来园子逛逛. PHPExcel导出excel文件,先说下重要的参数要记住的东西 impUser() 导入方法 exportEx ...
- asp.net 导出excel文件
之前做过winfrom程序的导出excel文件的功能,感觉非常简单.现在试着做asp.net中导出excel的功能,之前用的是Microsoft.Office.Interop.Excel这个对象来实现 ...
- JQGrid导出Excel文件
系列索引 Web jquery表格组件 JQGrid 的使用 - 从入门到精通 开篇及索引 Web jquery表格组件 JQGrid 的使用 - 4.JQGrid参数.ColModel API.事件 ...
随机推荐
- python+ffmpeg,批量转换手机中的m3u8文件
前段时间,有朋友找我帮忙,自述其手机上使用UC浏览器,缓存的电影有近千个,手机存储不够了,想把这些电影转存到PC机上,并且将其转换为Mp4文件.小事情,安排! 一.分析情况,确定方案. 首先连接手机, ...
- Day23:个人小结的撰写&&对coderunner的熟悉
今日完成的任务: 1.完成个人小结的撰写 2.阅读Moodle文档,了解Moodle平台以及Moodle出题格式 明日计划: 1.撰写总报告中的结论 2.将插件安装完成 每日小结: 为了研究题库,特 ...
- Ginan-PEA例程下载
输入以下命令可在Ubuntu系统中进行下载,但受到网络限制并不能有效下载或者下载很慢 python3 scripts/download_examples.py 通过阅读python脚本,可将下载网址拷 ...
- springboot启动日志:Multiple Spring Data modules found, entering strict repository configuration mode
问题描述 最近启动springboot项目的时候,发现有一条日志:Multiple Spring Data modules found, entering strict repository conf ...
- hive复制表
create table talbe_copy as select * from talbe_origin;
- 第一个WCF程序(最小实现)
环境:Microsoft Visual Studio 2017 注意事项:右键"以管理员身份"启动VS. 目标:实现一个加法运算,并在服务器端D盘新建一个文件夹. 一.服务器端创建 ...
- Navicate破解安装
1.安装Navicate客户端 2. 注意安装完毕不要打开navicate,打开后后面可能出现rsa public key not found之类的错误,直接点击注册机,选择版本,点击patc ...
- python测试IP地址是否ping通
import timeimport osdef pingComputer(): for i in range(1, 256): host = '192.168.2.' + str(i) status1 ...
- linux 使用tc做限速
#!/bin/bash#针对不同的ip进行限速 #清空原有规则tc qdisc del dev em3 root #创建根序列tc qdisc add dev em3 root handle 1: h ...
- tomcat反向代理,监控,性能优化详细步骤
第1章 tomcat简介Tomcat是Apache软件基金会(Apache Software Foundation)的Jakarta项目中的一个核心项目,由Apache,Sun和其他一些公司及个人共同 ...