react-html-table-to-excel 简介
安装 yarn add react-html-table-to-excel
属性说明
属性 | 类型 | 描述 |
---|---|---|
table | string | 需要导出的table的id,需要为table标签添加,两者要对应 |
filename | string | Excel文件的名字 |
sheet | string | Excel文件里面Sheet的名字 |
id | string | 添加到按钮上的id属性 |
className | string | 添加到按钮上的class属性 |
buttonText | string | 按钮中显示的文字 |
className
组件的按钮默认是没有样式的,我们可以把Ant Design中按钮的类名给他,让它显示出样式来
按钮的自带类名是没有样式的
手动给他改个类名
filename
sheet
使用方法
import React, { useState, useRef, useEffect } from 'react';
import ReactHTMLTableToExcel from 'react-html-table-to-excel';
export default function Mrtj(props) {
// 用ref来获取组件按钮实例,使用里面的方法
const buttonRef = useRef(null);
// 禁止组件按钮的默认点击事件
useEffect(() => {
const button = document.querySelector('#test-table-xls-button');
button.style['pointer-events'] = ('none');
},[]);
// 渲染折叠面板头部
const renderHeader = () => {
return (
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
<span>
日统计报表
</span>
<div>
<Button
style={{ margin: '0 15px' }}
type='primary'
disabled={!filterChange}
onClick={(e) => {
e.stopPropagation();
renderTableColumns();
setFilterChange(false);
}}
>
更新报表
</Button>
// 组件元素不能挂载自定义onClick事件,所以包个标签
<span onClick={(e) => exportTable(e)}>
<ReactHTMLTableToExcel
ref={buttonRef}
table="table-to-xls"
id='test-table-xls-button'
className='ant-btn'
filename='考勤每日统计'
sheet='每日统计'
buttonText='导出Excel'
/>
</span>
</div>
</div>
)
};
// 导出表格
const exportTable = (e) => {
e.stopPropagation(); // 防止Collapse组件收起
const thead = document.querySelector('thead').cloneNode(true); // 深克隆DOM节点
const tbody = document.querySelector('tbody').cloneNode(true); // 深克隆DOM节点
const container = document.querySelector('#hiddenBox');
const tempTable = document.createElement('table'); // <table></table>
tempTable.appendChild(thead); // <table><thead></thead></table>
tempTable.appendChild(tbody); // <table><thead></thead><tbody></tbody></table>
tempTable.setAttribute('id', 'table-to-xls'); // 给table添加id,值与按钮上的table字段对应
container.appendChild(tempTable); // 把创建的节点添加到页面容器中
buttonRef.current.handleDownload(); // 手动触发下载
// 可选,设置定时器删除table节点
// 可选,下次点击,判断容器里面有没有table,有就替换节点
};
return (
<div>
...
<Table
bordered
columns={tableColumns}
dataSource={data}
scroll={{ x: 'max-content', y: 'max-content' }}
/>
{/* 隐藏的table容器 */}
<div id='hiddenBox' style={{ position: 'absolute', zIndex: -1, top: 0, left: 0 }} />
</div>
)
}
注意点
- table元素必须是可见的(挂载在页面上且可视),不然会报错,由于我是生成的table,所以我把它放到一个设置了低层级的容器里,让它不显示出来
- 如果不使用克隆节点,会出现剪切、粘贴的效果,页面上可视的table中的节点,粘贴到隐藏节点中去了
表头不见了
- 为什么我要创建节点?
- 使用Antd的Table组件,原生的table标签包裹在里面,无法为其添加id属性
- 我的Table组件设置了固定列和固定表头,antd实际生成了两个table出来,所以我就把thead和tbody节点取出来,放到一个创建的table节点里,生成一个新的table
- 为什么要禁止组件按钮的点击事件?
因为没有点击按钮前,id为table-to-xls的table不存在,会报错找不到节点。所以我自定义了一个点击事件,在事件里创建并挂载节点后再用ref获取按钮实例,调用实例里下载的方法
最终效果图