antd Table组件合并单元格

7,151 阅读1分钟

效果图: 常见后台接口数据: 第一步,我们需要把数据处理成平铺:

// 数据处理成平铺
handleDataSource = (arr) => {
  const list = [];
  arr.forEach((j) => {
    if (j.persons && j.persons.length) {
      j.persons.forEach((k) => {
        list.push({ ...k, ...j });
      });
    } else {
      list.push({ ...j });
    }
  });
  return list;
};

第二步,合并单元格

// 表头只支持列合并,使用 column 里的 colSpan 进行设置。
// 表格支持行/列合并,使用 render 里的单元格属性 colSpan 或者 rowSpan 设值为 0 时,设置的表格不会渲染。
// 合并数组单元格
createNewArr = (data, key) => {
  // data 需要处理的表格数据 key 就是需要合并单元格的唯一主键,我这里是projectId
  return data
    .reduce((result, item) => {
      //首先将key字段作为新数组result取出
      if (result.indexOf(item[key]) < 0) {
        result.push(item[key]);
      }
      return result;
    }, [])
    .reduce((result, value, rownum) => {
      //将key相同的数据作为新数组取出,并在其内部添加新字段**rowSpan**
      const children = data.filter((item) => item[key] === value);
      result = result.concat(
        children.map((item, index) => ({
          ...item,
          rowSpan: index === 0 ? children.length : 0, //将第一行数据添加rowSpan字段
          rownum: rownum + 1
        }))
      );
      return result;
    }, []);
};

这样数据就处理好了,直接Table组件渲染数据就好了。

// 表头
const columns = [
  {
    title: '序号',
    dataIndex: 'rownum',
    key: 'rownum',
    width: 60,
    render: (text, record, index) => {
      return {
        children: text,
        props: {
          rowSpan: record.rowSpan
        }
      };
    }
  },
  {
    title: '项目名称',
    dataIndex: 'projectName',
    key: 'projectName',
    width: 200,
    render: (text, record) => {
      return {
        children: text,
        props: {
          rowSpan: record.rowSpan
        }
      };
    }
  },
  {
    title: '人员信息',
    dataIndex: 'persons',
    key: 'persons',
    children: [
      {
        title: '姓名',
        dataIndex: 'personName',
        key: 'personName',
        width: 100
      },
      {
        title: '年龄',
        dataIndex: 'age',
        key: 'age',
        width: 100
      }
    ]
  },
  {
    title: '操作',
    dataIndex: 'action',
    key: 'action',
    width: 200,
    render: (text, record) => (
      <span>
        <a>编辑</a>
        <Divider type="vertical" />
        <Popconfirm
          placement="left"
          icon={<Icon type="question-circle" theme="filled" style={{ color: '#F63A43' }} />}
          title="确定要删除吗?"
          onConfirm={() => this.props.handleDelete(record)}
          okText="确定"
          cancelText="取消"
        >
          <a>删除</a>
        </Popconfirm>
      </span>
    )
  }
];
// dataSource 后台接口数据
 <Table
    bordered
    dataSource={this.createNewArr(this.handleDataSource(dataSource), 'projectId')}
    columns={columns}
    rowKey="projectId"
    pagination={false}
 />

结束啦。