如图:实现一个动态行列合并的表格的思路,比较简单不过多赘述,直接贴demo代码了
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;