ant-design表格自动合并相同内容的单元格

发布于:2024-09-19 ⋅ 阅读:(16) ⋅ 点赞:(0)

表格自动合并相同内容的单元格

合并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.length

  const 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 string
      calculateCount(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 TableColumnProps
  return 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 TableColumnProps
  return 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!] ?? 1
    colspan: 1
  }
}

网站公告

今日签到

点亮在社区的每一天
去签到