基于ant-design的table组件rowSpan、colSpan的行列合并

开发板推荐:天空星STM32F407VET6开发板

超高性价比 STM32主控 | 超高主频 | 一板兼容百芯 | 比赛神器 | 沉金彩色丝印

基本规则

表头只支持列合并,使用 column 里的 colSpan 进行设置。 表格支持行/列合并,使用 render 里的单元格属性 colSpan 或者 rowSpan 设值为 0 时,设置的表格不会渲染。

示例
export const columns = [
  {
    title: "num",
    dataIndex: "num",
    customCell: (_, index) => {
      // 将第二行与第三行进行合并,
      // 第二行设置rowSpan=2
      if (index === 2) {
        return { rowSpan: 2 };
      }
      // 第三行设置colSpan=0(隐藏)
      if (index === 3) {
        return { rowSpan: 0 };
      }
    },
  },
  {
    title: "other",
    dataIndex: "other",
  },
];

也就是说当需要合并时我们要设置合并行的 customCell 返回**{rowSpan:n}(n 为合并的行数),而被合并的地方则需要返回{rowSpan:0}**,而默认的则为{rowSpan:1}

整体思路

1、创建一个对象,key 为对应行的 dataIndex,值为需要返回的合并行数组

假设像一开始有 5 行数据,我们需要 1、2 行,3、4、5 行合并,则构建出一个这样的数组

const columnConfig = {num:[2,0,3,0,0]}

2、设置好对应列的 customCell

const colums=[{
    title: '数量',
    dataIndex: 'num',
    width: 120,
    customCell:(_, index)=>({
        rowSpan: columnConfig.num[index],
      }),
  }]
代码

1、准备数据

const data = [
  {
    key: '1',
    name: 'John Brown',
    age: 32,
    tel: '0571-22098909',
    phone: 18889898989,
    address: 'New York No. 1 Lake Park'
  },
  {
    key: '2',
    name: 'John Brown',
    tel: '0571-22098333',
    phone: 18889898888,
    age: 42,
    address: 'London No. 1 Lake Park'
  },
  {
    key: '3',
    name: 'Joe Black',
    age: 32,
    tel: '0575-22098909',
    phone: 18900010002,
    address: 'Sidney No. 1 Lake Park'
  },
  {
    key: '4',
    name: 'John Brown',
    age: 18,
    tel: '0575-22098909',
    phone: 18900010002,
    address: 'London No. 2 Lake Park'
  },
  {
    key: '5',
    name: 'Joe Black',
    age: 18,
    tel: '0575-22098909',
    phone: 18900010002,
    address: 'Dublin No. 2 Lake Park'
  }
]
let columns = [
  {
    title: 'Name',
    dataIndex: 'name'
  },
  {
    title: 'Age',
    dataIndex: 'age',
  },
  {
    title: 'Home phone',
    dataIndex: 'tel'
  },
  {
    title: 'Phone',
    dataIndex: 'phone',
  },
  {
    title: 'Address',
    dataIndex: 'address',
  }
]

2、以第一列为准,对 table 数据进行排序,将第一列相同的数据放在一起

function groupByName(data, key) {
  // 创建一个 Map 来存储按 name 分组的数据
  const groups = new Map()

  // 将数据按 name 分组
  data.forEach((item) => {
    const name = item[key]
    if (!groups.has(name)) {
      groups.set(name, [])
    }
    groups.get(name).push(item)
  })

  // 将分组后的数据扁平化
  const result = []
  groups.forEach((group) => {
    result.push(...group)
  })

  return result
}

// 根据name排序
const data2 = groupByName(data, 'name')

3、获取项数组

将配置好的 columns 中的 dataIndex 提取处理,用于将来构造配置

function getSpansColumn(sellColumns) {
  const spans = []
  for (let i = 0; i < sellColumns.length; i++) {
    const key = sellColumns[i].dataIndex
    spans.push(key)
  }
  return spans
}
// ['name', 'age', 'tel', 'phone', 'address']
const columnSpans = getSpansColumn(columns)

4、获取配置数据

// 计算每一列需要的rowsSpans
function calculateRowSpans(columnSpans,data) {
  const rows = data
  // 收集跨行映射
  const spanConfig = {}
  const spansData = new Array(rows.length).fill(0)
  // 遍历计算了所有列的合并配置数据,如果只需合并一列或者某几列,可以在这里进行过滤
  columnSpans.forEach((columnSpan) => {
    const spans = [...spansData]
    let currentSpanStart = 0
    for (let i = 0; i < rows.length; i++) {
      // 遇到不同组或最后一行时结算跨度
      if (i === rows.length - 1 || rows[i][columnSpan] !== rows[i + 1][columnSpan]) {
        spans[currentSpanStart] = i - currentSpanStart + 1
        for (let j = currentSpanStart + 1; j <= i; j++) {
          spans[j] = 0
        }
        currentSpanStart = i + 1
      }
    }
    spanConfig[columnSpan] = spans
  })
  return spanConfig
}

// {"name":[3,0,0,2,0],"age":[1,1,1,1,1],"tel":[1,1,3,0,0],"phone":[1,1,3,0,0],"address":[1,1,1,1,1]}

let spanConfig = calculateRowSpans(columnSpans,data2)

5、改造 columns

//生成带合并配置的列定义
function generateMergedColumns(columns,columnConfig) {
  return columns.map((column) => {
    if (!columnConfig[column.dataIndex]) return column

    return {
      ...column,
      customCell: (_, index) => ({
        rowSpan: columnConfig[column.dataIndex][index]
      })
    }
  })
}

columns2 = generateMergedColumns(columns,spanConfig)

6、渲染

<a-table :columns="columns2" :data-source="data2" bordered></a-table>

7、效果
在这里插入图片描述

开发板推荐:天空星STM32F407VET6开发板

超高性价比 STM32主控 | 超高主频 | 一板兼容百芯 | 比赛神器 | 沉金彩色丝印

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

k0933

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值