React中Antd Table动态表头横向排布实现方案
Antd Table实现时段横向、星期纵向的课程表排布
实现思路
- 保留Days作为固定首列,承担纵向表头职能
- 从接口原始数据中提取全量不重复的时段值,动态生成横向表头列
- 对原始扁平数据做分组聚合,以日期为维度组装行数据,将每个时段对应的内容映射到对应列下
代码改造步骤
1. 替换原有静态列配置+新增数据聚合逻辑
废弃原来写死的columns常量,在拿到接口数据后动态生成列配置,同时把原始扁平数据转换成表格需要的二维结构:
const [tableData, setTableData] = useState([]); const [columns, setColumns] = useState([]); const [loading, setLoading] = useState(false); const fetchData = async () => { setLoading(true); const { data: rawData } = await getTimetable(); // 提取所有不重复时段,按需排序后生成动态列 const periodList = [...new Set(rawData.map(item => item.period))]; // 若时段需要按特定顺序展示,在这里对periodList做排序处理,比如: // periodList.sort((a,b) => a.periodNum - b.periodNum) // 固定首列:星期列 const dayColumn = { title: 'Days', dataIndex: 'date', defaultSortOrder: 'ascend', key: 'dayCol', sorter: (a, b) => a.date.localeCompare(b.date), sortDirections: ['descend', 'ascend'], render: (date) => getDayName(new Date(date)), }; // 生成时段对应的横向列 const periodColumns = periodList.map(period => ({ title: period, dataIndex: period, key: period, // 自定义单元格内容,根据业务需求调整 render: (cellVal) => cellVal?.courseName ?? '-' })); setColumns([dayColumn, ...periodColumns]); // 按日期分组聚合行数据 const groupedData = rawData.reduce((groupMap, item) => { const dateKey = item.date; if (!groupMap[dateKey]) { groupMap[dateKey] = { date: dateKey, key: dateKey }; } groupMap[dateKey][item.period] = item; return groupMap; }, {}); setTableData(Object.values(groupedData)); setLoading(false); }; useEffect(() => { fetchData(); }, []);
2. 调整Table组件传参
替换原来的静态columns、未聚合的data和错误的rowKey配置,传入处理后的数据和列:
<TableContainer columns={columns} rowKey={record => record.key} dataSource={tableData} loading={loading} bordered />
适配提示
- 如果时段有固定排序规则(比如早1节到晚上第N节的顺序),一定要在生成periodColumns前对periodList做排序,避免表头顺序错乱
- 单元格需要展示多信息(比如课程名+上课地点+授课老师),直接在periodColumns的render函数中返回自定义JSX即可
- 若存在某天某时段无排课的情况,聚合后对应字段为空,记得在render中做空值兜底,避免渲染报错
内容的提问来源于stack exchange,提问作者Ahmed Hosny
相关产品推荐
相关产品推荐

