ant-design表格自动合并相同内容的单元格
表格自动合并相同内容的单元格
合并hooks
import { TableColumnProps } from 'antd'export const useAutoMergeTableCell = <T extends object>(dataSource: Array<T>,columns: Array<TableColumnProps> | Array<keyof T>
): Map<keyof T, Array<number>> => {const cellToIndexMap = new Map<keyof T, Array<number>>()const countInfoMap = new Map<keyof T, { startIndex: number; count: number; value: any } | null>()const length = dataSource.lengthconst parseColumns = columns.map((m) => {if (typeof m === 'string') {return {dataIndex: m}}return m})parseColumns.forEach((it) => {cellToIndexMap.set(it.dataIndex as keyof T, new Array(length).fill(0))countInfoMap.set(it.dataIndex as keyof T, null)})const updateCellCount = (key: string) => {const countInfo = countInfoMap.get(key as keyof T)const indexArray = cellToIndexMap.get(key as keyof T)indexArray![countInfo!.startIndex] = countInfo!.count}const calculateCount = (key: string, value: any, index: number) => {const countInfo = countInfoMap.get(key as keyof T)if (countInfo === null) {countInfoMap.set(key as keyof T, { startIndex: index, count: 1, value })} else {if (countInfo!.value === value) {countInfo!.count++} else {updateCellCount(key)countInfoMap.set(key as keyof T, { startIndex: index, count: 1, value })}}if (index === length - 1) {updateCellCount(key)}}for (let i = 0; i < length; ++i) {parseColumns.forEach((column) => {const key = column.dataIndex as stringcalculateCount(key, Reflect.get(dataSource[i], key), i)})}return cellToIndexMap
}
使用
让所有的列都进行单元格合并
// dataSource 用自己表格的数据
// columns 为你定义的列
const cellToIndexMap = useAutoMergeTableCell(dataSource, columns)
const parseColumns = columns.map((m) => {return {...m,onCell: (_, index) => {const indexArray = cellToIndexMap.get(m.dataIndex as keyof T)return {rowSpan: indexArray![index!] ?? 1}}} as TableColumnPropsreturn m
})
只想部分列进行合并
只需要传递对应的想要合并的 key
即可
const cellToIndexMap = useAutoMergeTableCell(dataSource, ['key1', 'key2'])
const parseColumns = columns.map((m) => {return {...m,onCell: (_, index) => {const indexArray = cellToIndexMap.get(m.dataIndex as keyof T)return {rowSpan: indexArray![index!] ?? 1}}} as TableColumnPropsreturn m
})
关于element-ui
如果想要适配于 element-ui
,只需要把 hooks
中的 dataIndex
替换为 prop
即可。
使用:
const cellToIndexMap = useAutoMergeTableCell(dataSource, ['key1', 'key2'])
// or
// const cellToIndexMap = useAutoMergeTableCell(dataSource, columns)
spanMethods ({ row, column, rowIndex, columnIndex }) {const indexArray = cellToIndexMap.get(column.prop)return {rowSpan: indexArray![index!] ?? 1colspan: 1}
}