根据数据动态进行Antd表格行列合并的例子【bysking】

293 阅读2分钟

如图:实现一个动态行列合并的表格的思路,比较简单不过多赘述,直接贴demo代码了

image.png

import { ProColumns } from '@ant-design/pro-components';
import { Table } from 'antd';

const yearList = ['2024', '2023']; // 横向数据增加维度
let provinceList = ['贵州', '上海', '北京', '天津']; // 纵向列数据增加维度

// 渲染函数, keyList是全部的维度数组,根据这些信息取出对应的真是数据
const renderCell = (record: object, keyList: string[]) => {
  return <>{JSON.stringify(keyList)}</>;
};

// 抽离的渲染子列的函数
const getChildren = (key, childList) => {
  if (!childList.length) {
    return null;
  }
  return childList.map((o) => {
    return {
      dataIndex: o,
      title: o,
      key: key + o,
      render: (_, record: object, index: number) => {
        // 省份维度的索引
        let posIndex = Math.floor(index % provinceList.length);
        return <>{renderCell(record, [index, key, o, posIndex])}</>;
      },
    };
  });
};

const columns: ProColumns[] = [
  {
    title: '渠道(name)',
    dataIndex: 'name',
    align: 'center',
    render: (text, _, index) => {
      // 没有省份维度则不进行行合并
      if (!provinceList?.length) {
        return text;
      }

      // 按照省份数量进行行合并:
      // 比如省份有两个,那么位置为0,2,4 (省份长度的倍数,这些位置向后进行行合并),这块可以看一下antd Table的行列合并教程
      if (index % provinceList.length === 0) {
        return {
          children: text,
          props: {
            rowSpan: provinceList.length,
          },
        };
      } else {
        return {
          children: text,
          props: {
            rowSpan: 0,
          },
        };
      }
    },
  },
  {
    title: '省份(province)', // 我们可以通过判断provinceList的长度来决定是否添加这一个表头
    dataIndex: 'province',
    className: 'name-column',
    render: (text, _, index, ...ee) => {
      if (!provinceList?.length) {
        return '-'; // 没有省份数据,不渲染
      }
      let posIndex = Math.floor(index % provinceList.length);
      return <>{provinceList[posIndex]}</>;
    },
  },
  {
    title: '基本信息(baseInfo)',
    dataIndex: 'baseInfo',
    children: [
      {
        title: '地址(address)',
        align: 'center',
        dataIndex: 'address',
        children: getChildren('baseInfo.address', yearList),
      },
      {
        title: '电话(center)',
        align: 'center',
        dataIndex: 'phone',
        children: getChildren('baseInfo.phone', yearList),
      },
    ],
  },
];

const data = [
  {
    key: 1,
    name: '资源分配',
    age: 32,
    address: '北京市朝阳区',
    phone: '010-12345678',
  },
  {
    key: 2,
    name: '资源分配',
    age: 30,
    address: '北京市海淀区',
    phone: '010-87654321',
  },
  {
    key: 3,
    name: '资源分配',
    age: 28,
    address: '上海市',
    phone: '021-12345678',
  },

  {
    key: 5,
    name: '投资后销量',
    age: 35,
    address: '深圳市',
    phone: '0755-12345678',
  },
  {
    key: 6,
    name: '投资后销量',
    age: 33,
    address: '杭州市',
    phone: '0571-12345678',
  },
  {
    key: 7,
    name: '投资后销量',
    age: 31,
    address: '南京市',
    phone: '025-12345678',
  },

  {
    key: 9,
    name: '销量汇总',
    age: 35,
    address: '深圳市',
    phone: '0755-12345678',
  },
  {},
];

const App = () => (
  <Table columns={columns} pagination={false} dataSource={data} bordered />
);

export default App;