You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React导出Ant Design表格至Excel遇props.children.reduce错误求助

Ant Design可编辑表格导出Excel(修复reduce报错)

报错原因

Uncaught TypeError: props.children.reduce is not a function 报错源于导出工具处理列配置时遇到非预期结构:

  • 部分列的dataIndex与数据源(dataSource)字段不匹配(如'Abrir'列的abrir、'Deletar'列的operation)
  • 列配置中的render、filters等属性被导出工具误判为需要遍历的子节点
  • 自定义导出函数的max函数未处理空数组边界情况

修复方案

方案一:调整antd-table-saveas-excel使用逻辑

  1. 过滤不需要导出的操作类列
  2. 清理列配置,仅保留导出所需的核心属性(title、dataIndex、key)
  3. 确保导出列的dataIndex与数据源字段完全匹配

修改后的导出触发函数:

const handleClick = () => {
  // 过滤并清理导出列
  const exportColumns = columns
    .filter(col => ['id', 'name', 'age', 'address'].includes(col.dataIndex))
    .map(col => ({
      title: col.title,
      dataIndex: col.dataIndex,
      key: col.key
    }));

  const excel = new Excel();
  excel
    .addSheet("test")
    .addColumns(exportColumns)
    .addDataSource(dataSource, {
      str2Percent: true
    })
    .saveAs("Excel.xlsx");
};

方案二:修复自定义导出函数(excel.js)

  1. 给max函数添加空数组处理逻辑
  2. 在列遍历过程中过滤无效列(无dataIndex或数据源中不存在的字段)

修改后的excel.js关键部分:

// 修复max函数,处理空数组边界
function max(arr) {
  if (!arr.length) return 0;
  return arr.reduce((accu, curr) => curr > accu ? curr : accu);
}

// 修改列遍历逻辑,过滤无效列
function columnLine(column) {
  column.map(ele => {
    // 跳过无有效dataIndex的列
    if (!ele.dataIndex || !dataSource[0]?.hasOwnProperty(ele.dataIndex)) {
      return;
    }
    if (ele.children === undefined || ele.children.length === 0) {
      columnLineArr.push(ele);
    } else {
      columnLine(ele.children);
    }
  });
}

在TableExcel.js中调用自定义函数:

import exportExcel from './excel.js';

const handleClick = () => {
  exportExcel(columns, dataSource, 'Excel');
};

完整可运行代码(方案一)

TableExcel.js

import { Table, Drawer, Tooltip, Popconfirm, Button } from "antd";
import { RiFileExcel2Line } from 'react-icons/ri';
import { DeleteOutlined, FolderOpenOutlined } from '@ant-design/icons';
import DrawerDB from "../../Drawer/DrawerDB";
import React, { useState } from 'react';
import { Excel } from "antd-table-saveas-excel";

export default function TableExcel() {
    const [open, setOpen] = useState(false);
    const showDrawer = () => setOpen(true);
    const onClose = () => setOpen(false);

    const [dataSource, setDataSource] = useState([
        { key: "1", id: 156, name: "Emily", age: 32, address: "10 Downing Street" },
        { key: "2", id: 336, name: "Joana", age: 42, address: "10 Downing Street" },
        { key: "3", id: 2398, name: "Maria", age: 42, address: "10 Downing Street" }
    ]);

    const handleDelete = (id) => {
        setDataSource(dataSource.filter(item => item.id !== id));
    };

    const columns = [
        {
            key: '4', title: 'Abrir', dataIndex: 'abrir', width: 80,
            render: () => (
                <button onClick={showDrawer}>
                    <FolderOpenOutlined />
                </button>
            )
        },
        { key: '5', title: 'ID', dataIndex: 'id', ellipsis: true, width: 80 },
        { key: '6', title: 'name', dataIndex: 'name', ellipsis: true, width: 150 },
        { key: '7', title: 'age', dataIndex: 'age', ellipsis: true, width: 150 },
        {
            key: '8', title: 'Address', dataIndex: 'address', ellipsis: true, width: 100,
            render: (address) => (
                <Tooltip placement="topLeft" title={address}>{address}</Tooltip>
            )
        },
        {
            key: '9', title: 'Deletar', dataIndex: 'operation', width: 150,
            render: (_, record) => (
                <Popconfirm title="Tem certeza que deseja deletar?" cancelText='Cancelar' onConfirm={() => handleDelete(record.id)}>
                    <button><DeleteOutlined style={{ color: 'red', marginLeft: 15 }} /></button>
                </Popconfirm>
            )
        }
    ];

    const handleClick = () => {
        const exportColumns = columns
            .filter(col => ['id', 'name', 'age', 'address'].includes(col.dataIndex))
            .map(col => ({ title: col.title, dataIndex: col.dataIndex, key: col.key }));

        const excel = new Excel();
        excel.addSheet("test")
             .addColumns(exportColumns)
             .addDataSource(dataSource, { str2Percent: true })
             .saveAs("Excel.xlsx");
    };

    return (
        <>
            <div className="export-excel">
                <Button className='btn' onClick={handleClick}>
                    <RiFileExcel2Line />
                </Button>
            </div>
            <Table columns={columns} dataSource={dataSource} style={{ padding: 35 }} />
            <Drawer width={1100} title="Informações completas" placement="right" onClose={onClose} open={open}>
                <DrawerDB />
            </Drawer>
        </>
    );
}

内容的提问来源于stack exchange,提问作者Joyce

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 11:17:57