antd 5.x 实现表格行自动动态合并

858 阅读1分钟

前言

目前技术栈是基于react + antd,有一个需求是表格列连续几行数据相同时需要表格自动进行合并! 去官网查了一圈发现并没有自动合并的功能,遂自己实现。

DEMO

codesandbox-demo

iShot_2023-03-03_22.53.01.png

实现

import React from "react";
import { Table, Button } from "antd";

/**
 * 用 row_span_map 来存储对应 key 的 rowSpan
 */
const convertDataToRowSpan = (data = [], columns = []) => {
    const keys = columns.map((item) => item.dataIndex);
    for (const key of keys) {
        for (let i = 0; i < data.length; i++) {
            let count = 1;
            let r = i;
            for (let j = i + 1; j < data.length; j++) {
                if (data[i][key] === data[j][key]) {
                    count++;
                    i = j;
                    if (!data[j].row_span_map) {
                        data[j].row_span_map = {};
                    }
                    data[j].row_span_map[key] = 0;
                } else {
                    break;
                }
            }
            if (!data[r].row_span_map) {
                data[r].row_span_map = {};
            }
            data[r].row_span_map[key] = count;
        }
    }
    return data;
};

const data = [
    { name: 1, age: 19, sex: 1 },
    { name: 1, age: 17, sex: 2 },
    { name: 2, age: 18, sex: 3 },
    { name: 2, age: 18, sex: 4 },
    { name: 2, age: 19, sex: 5 },
    { name: 2, age: 18, sex: 5 },
    { name: 1, age: 19, sex: 7 },
    { name: 2, age: 19, sex: 8 },
    { name: 1, age: 19, sex: 1 },
    { name: 1, age: 19, sex: 2 }
];

const columns = [
    {
        title: "name",
        dataIndex: "name"
    },
    {
        title: "age",
        dataIndex: "age"
    },
    {
        title: "sex",
        dataIndex: "sex"
    },
    {
        title: "操作",
        dataIndex: "op",
        ignoreMerge: true,
        render: () => <Button type="link">操作</Button>
    }
];

const ProTable = (props) => {
    const {
        columns = [],
        dataSource = [],
        autoMerge = false,
        ...restProps
    } = props;

    const proColumns = autoMerge
        ? columns.map(({ dataIndex, ignoreMerge, ...restCol }) => ({
            dataIndex,
            onCell: ignoreMerge
            ? undefined
            : (record) => ({ rowSpan: record.row_span_map[dataIndex] }),
            ...restCol
        }))
        : columns;

    const proData = autoMerge
    ? convertDataToRowSpan(dataSource, columns)
    : dataSource;

    console.log("---- covertDataToRowSpan(data) ----", proData);
    return <Table columns={proColumns} dataSource={proData} {...restProps} />;
};

const App: React.FC = () => (
    <>
        <h2>merged</h2>
        <ProTable columns={columns} dataSource={data} autoMerge={true} bordered />

        <h2>not merged</h2>
        <ProTable columns={columns} dataSource={data} autoMerge={false} bordered />
    </>
);

export default App;

总结

至此,antd5.x 表格自动合并功能就实现了。要想自动合并传autoMerge为true就可以了;如果有某列不需要自动合并(比如操作列),column 添加 ignoreMerge为true即可。功能虽然实现了,但计算合并那里复杂度有点高,有没有大佬有更好的算法来优化一下!