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>
	)
}

注意点

  1. table元素必须是可见的(挂载在页面上且可视),不然会报错,由于我是生成的table,所以我把它放到一个设置了低层级的容器里,让它不显示出来
  2. 如果不使用克隆节点,会出现剪切、粘贴的效果,页面上可视的table中的节点,粘贴到隐藏节点中去了
    在这里插入图片描述
    表头不见了
    在这里插入图片描述
  3. 为什么我要创建节点?
    在这里插入图片描述
  • 使用Antd的Table组件,原生的table标签包裹在里面,无法为其添加id属性
  • 我的Table组件设置了固定列和固定表头,antd实际生成了两个table出来,所以我就把thead和tbody节点取出来,放到一个创建的table节点里,生成一个新的table
  1. 为什么要禁止组件按钮的点击事件?
    因为没有点击按钮前,id为table-to-xls的table不存在,会报错找不到节点。所以我自定义了一个点击事件,在事件里创建并挂载节点后再用ref获取按钮实例,调用实例里下载的方法
    在这里插入图片描述

最终效果图

在这里插入图片描述
在这里插入图片描述

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐