首先看一下antd的Table表单组件,合并单元格,用到了rowSpan(合并行)和colSpan(合并列)
后台返回的数据
[
{
key: 0,
category: '水果',
name: '桃子',
desc: '好吃',
},
{
key: 1,
category: '水果',
name: '梨子',
desc: '真好吃',
},
{
key: 2,
category: '蔬菜',
name: '茄子',
desc: '真好吃',
},
{
key: 9,
category: '蔬菜',
name: '茄子',
desc: '真好吃',
},
{
key: 3,
category: '家禽',
name: '牛肉',
desc: '太好吃了',
},
{
key: 4,
category: '家禽',
name: '羊肉',
desc: '真不错',
},
{
key: 5,
category: '家禽',
name: '猪肉',
desc: '吃不起,太贵',
},
{
key: 4,
category: '家禽',
name: '羊肉',
desc: '真不错',
},
{
key: 5,
category: '家禽',
name: '猪肉',
desc: '吃不起,太贵',
},
]
我们希望把category的值相同的,行合并成一个单元格
类似于这种
rowSpan这个属性可以指定合并行。例如说第一行,指定rowSpan为3,意思就是合并三行,则后面紧挨的两行的rowSpan就需要设置为0。因为他们一共就占有3份,第一行的为3份,已经占完了,下面俩就不能再占了,就必须为0
官网实例中,使用onCell属性,来指定合并多少行/列,onCell的值是一个函数,默认接收2个参数,第一个参数是当前行数据,第二个参数就是这行的索引
我在网上看了一些大佬的做法,感觉直接处理源数据,在源数据中添加它这个所占的份数,直接通过在onCell中指定他所需要合并的行的个数,这种做法最简单
也就是把源数据处理成这种
[
{
key: 0,
category: '水果',
name: '桃子',
desc: '好吃',
rowSpan: 2,
},
{
key: 1,
category: '水果',
name: '梨子',
desc: '真好吃',
rowSpan: 0,
},
{
key: 2,
category: '蔬菜',
name: '茄子',
desc: '真好吃',
rowSpan: 2,
},
{
key: 9,
category: '蔬菜',
name: '茄子',
desc: '真好吃',
rowSpan: 0,
},
{
key: 3,
category: '家禽',
name: '牛肉',
desc: '太好吃了',
rowSpan: 3,
},
{
key: 4,
category: '家禽',
name: '羊肉',
desc: '真不错',
rowSpan: 0,
},
{
key: 5,
category: '家禽',
name: '猪肉',
desc: '吃不起,太贵',
rowSpan: 0,
},
{
key: 4,
category: '家禽',
name: '羊肉',
desc: '真不错',
rowSpan: 0,
},
{
key: 5,
category: '家禽',
name: '猪肉',
desc: '吃不起,太贵',
rowSpan: 0,
},
]
具体代码如下
import { Table } from 'antd'
const Demo1 = () => {
let field = 'category'
const data = [
{
key: 0,
category: '水果',
name: '桃子',
desc: '好吃',
// rowSpan: 2,
},
{
key: 1,
category: '水果',
name: '梨子',
desc: '真好吃',
// rowSpan: 0,
},
{
key: 2,
category: '蔬菜',
name: '茄子',
desc: '真好吃',
// rowSpan: 2,
},
{
key: 9,
category: '蔬菜',
name: '茄子',
desc: '真好吃',
// rowSpan: 0,
},
{
key: 3,
category: '家禽',
name: '牛肉',
desc: '太好吃了',
// rowSpan: 3,
},
{
key: 4,
category: '家禽',
name: '羊肉',
desc: '真不错',
// rowSpan: 0,
},
{
key: 5,
category: '家禽',
name: '猪肉',
desc: '吃不起,太贵',
// rowSpan: 0,
},
{
key: 4,
category: '家禽',
name: '羊肉',
desc: '真不错',
// rowSpan: 0,
},
{
key: 5,
category: '家禽',
name: '猪肉',
desc: '吃不起,太贵',
// rowSpan: 0,
},
]
const columns = [
{
title: '姓名',
dataIndex: 'category',
onCell: (record, index) => {
// console.log(record.category, record.rowSpan)
return { rowSpan: record.rowSpan }
},
},
{
title: '床位',
// colSpan: 2, // 设置占位2格
dataIndex: 'parentType',
/**
* 每4行都是一个日期,从index = 0 开始,
* 每隔4行的rowSpan为4,其余的rowSpan为0
*/
// onCell: (_, index) => ({
// rowSpan: index % 2 === 0 || index === 0 ? 2 : 0,
// }),
},
{
title: '组',
// colSpan: 0, // 设置占位0格
dataIndex: 'type',
},
{
title: '药房',
dataIndex: 'user1',
},
{
title: '类型',
dataIndex: 'user2',
},
{
title: '项目名称',
dataIndex: 'user3',
},
{
title: '规格',
dataIndex: 'user4',
},
]
const changeData = (data, field) => {
let count = 0 //重复项的第一项
let indexCount = 1 //下一项
while (indexCount < data.length) {
var item = data.slice(count, count + 1)[0] //获取没有比较的第一个对象
if (!item.rowSpan) {
item.rowSpan = 1 //初始化为1
}
if (item[field] === data[indexCount][field]) {
//第一个对象与后面的对象相比,有相同项就累加,并且后面相同项设置为0
item.rowSpan++
data[indexCount].rowSpan = 0
} else {
count = indexCount
}
indexCount++
}
}
changeData(data, field) //处理数据
return (
<div>
<Table
columns={columns}
dataSource={data}
pagination={false}
bordered
></Table>
</div>
)
}
export default Demo1