首发:

为保证最佳的阅读体验,建议前往语雀体验[比心]

先上图

show code

首先安装所需依赖

yarn add exceljs file-saver yarn add -D @types/file-saver

import { FC, useState, useEffect, useRef } from "react"; import { Table, Button } from "antd"; import { columns } from "./columns"; import { exportExcel } from "@mock/export-excel"; import { makeExportExcel } from "@utils/export-excel"; const ExportExcel: FC = () => { const [list, setList] = useState(); const [pageParams] = useState({ pageIndex: 1, pageSize: 10, totalCount: 0, }); const [chosenList, setChosenList] = useState([]); const [loading, setLoading] = useState(false); // 复选框全选/多选 const tableSelectedRowKeys = useRef({}); const downloadRowSelection: { selectedRowKeys: React.Key[]; onChange: (selectedRowKeys: React.Key[]) => void; } = { selectedRowKeys: tableSelectedRowKeys.current[pageParams.pageNum], onChange: (selectedRowKeys: React.Key[], selectedRows?: any) => { tableSelectedRowKeys.current[pageParams.pageNum] = selectedRowKeys; setChosenList(selectedRows); }, }; // excel导出 const onExportExcel = () => { makeExportExcel({ columns: columns(), listData: chosenList?.length > 0 ? chosenList : list, }); }; const fetchList = () => { setLoading(true); const { list: listData } = exportExcel(); setLoading(false); setList(listData); }; useEffect(() => { fetchList(); }, []); return (

className="table_container" rowSelection={downloadRowSelection} rowKey={(item) => item.id} dataSource={list} loading={loading} columns={columns() as IPageExportExcel.List} pagination={{ showQuickJumper: true, showSizeChanger: true, size: "small", showTotal: (totalCount, range) => `第${range[0] || "--"}~${range[1] || "--"}条 / 共${totalCount}条`, }} /> ); }; export default ExportExcel;

import * as ExcelJs from "exceljs"; import { Workbook } from "exceljs"; import { saveAs } from "file-saver"; // 生成头部columns function generateHeaders(columns: any = []) { return columns.map((col: any) => { const obj: ITableHeader = { // 显示的 name header: col?.title, // 用于数据匹配的 key key: col?.key, // 列宽 width: col.width ? col.width / 4 : 15, }; if (col.children) { col.children?.forEach((item: any) => ({ key: item.dataIndex, header: item.title, width: item.width, parentKey: col.key, })); } return obj; }); } // 导出excel function saveWorkbook(workbook: Workbook, fileName: string) { // 导出文件 workbook.xlsx .writeBuffer() .then((data: any) => { const blob = new Blob([data], { type: "" }); saveAs(blob, fileName); }) .catch((error) => { console.log("saveWorkbook:error----->:", error); }); } /** * @module makeExportExcel * @description excel文件导出 */ export function makeExportExcel(data: any) { const { columns = [], listData = [], rowHeight = 20, workSheetName = "测试excel", } = data || {}; // 创建工作簿 const workbook = new ExcelJs.Workbook(); // 添加sheet const worksheet = workbook.addWorksheet(workSheetName); // 设置 sheet 的默认行高 worksheet.properties.defaultRowHeight = rowHeight; // 设置列 worksheet.columns = generateHeaders(columns); // 添加行 worksheet.addRows(listData); // 导出excel saveWorkbook(workbook, `${workSheetName}.xlsx`); }

import { ColumnsType } from "antd/es/table"; import "./index.less"; export const columns = (): ColumnsType => { return [ { title: "ID", dataIndex: "id", key: "id", }, { title: "标题", dataIndex: "title", key: "title", width: 300, }, { title: "价格", dataIndex: "price", key: "price", }, { title: "照片", key: "goodsUrl", render: (item: IPageExportExcel.ListItem) => ( ), }, ]; };

import { mock } from "mockjs"; export function exportExcel() { const resp = mock({ "list|35": [ { id: /d{5,10}/, "title|1": [ "透明衣物收纳箱 衣柜装衣服被子整理箱子布艺", "透明衣物收纳箱", "被子整理箱子布艺衣柜装衣服被子", "整理箱子布艺衣柜装衣服被子整理箱子布艺 折叠家用换季收纳盒", "透明衣物收纳箱 衣柜装衣服被子整理箱子布艺衣柜装衣服被子整理箱子布艺衣柜装衣", ], "date|1": [1654999234000, 1655085634000, 1654826434000], "price|+10": 10, "count|+5": 5, "goodsUrl|1": [ "https://gw.alicdn.com/bao/uploaded/i1/1993812065/O1CN01jEcF4X1R7oOZIoqdx_!!0-item_pic.jpg", "https://fastly.jsdelivr.net/npm/@vant/assets/apple-1.jpeg", "https://fastly.jsdelivr.net/npm/@vant/assets/apple-2.jpeg", "https://fastly.jsdelivr.net/npm/@vant/assets/apple-3.jpeg", "https://fastly.jsdelivr.net/npm/@vant/assets/apple-4.jpeg", "https://fastly.jsdelivr.net/npm/@vant/assets/apple-5.jpeg", ], }, ], }); return resp; }

type ITableHeader = { header: string; // 用于数据匹配的 key key: string; // 列宽 width: number; // 父级的 key parentKey?: string; children?: ITableHeader[]; };

declare namespace IPageExportExcel { interface ListItem { id: string; title: string; date?: number; price?: number; count?: number; goodsUrl?: string; } type List = ListItem[]; }

附录

源码:https://github.com/Jairwin-L/react-demo/tree/feat/export-excel

在线预览:https://github.dev/Jairwin-L/react-demo/tree/feat/export-excel