单元格合并

设计思路

  1. 接管 Table.Column 的 render 事件,通过设置 rowSpan 来合并单元格
  2. 在数据刷新后事件中,遍历数据并计算列的合并数,记录在 spanCount 计算列中,用于设置列的 rowSpan

运行效果如下

1. 在 table 对应的 data 组件中增加一个计算列 spanCount(数据类型:文本)

2. 在 .w 页面的 js 中加入以下代码,并修改 initSpanCount 函数的 spanCols 数组,指定要合并的列名

    // 初始化计算列 spanCount,在 data 的 onAfterRefresh 事件中调用
    initSpanCount(data) {
        // spanCols 指定要合并的列,支持多列,列的合并数会记录在计算列 spanCount
        let spanCols = ["fDescription"];
        /*  firstRow 在数据遍历计算时记录合并的首行、值、合并数
            firstRow = {
                col1: {
                    firstRow:
                    value:
                    count: 
                }
            }
        */
        let firstRow = {}; 
        // 解析并写入计算列 spanCount = "{col1:2,col2:0}"
        function setSpanCount(row, col, count) {
            let spanCount = {};
            if (row.spanCount) {
                spanCount = JSON.parse(row.spanCount);
            }
            spanCount[col] = count;
            data.setValue("spanCount", JSON.stringify(spanCount), row);
        }
        // 遍历数据
        data.each(function(params){
            let row = params.row;
            for (let i = 0; i < spanCols.length; i++) {
                let spanCol = spanCols[i];
                let value = row[spanCol];
                if (firstRow[spanCol] && (value == firstRow[spanCol].value)) {
                    // 如果当前列的值在 firstRow 已存在,首行的合并数 + 1,当前行的合并数 = 0
                    firstRow[spanCol].count = firstRow[spanCol].count + 1;
                    setSpanCount(row, spanCol, 0);
                } else {
                    // 如果当前列的值在 firstRow 不存在
                    if (firstRow[spanCol]) {
                        // 记录前一个值的首行合并数
                        setSpanCount(firstRow[spanCol].firstRow, spanCol, firstRow[spanCol].count)
                    }
                    // 开始记录下一个值的首行
                    firstRow[spanCol] = {
                        "firstRow": row,
                        "value": value,
                        "count": 1
                    }
                }
            }
        })
        // 遍历后记录最后的首行
        for (let i = 0; i < spanCols.length; i++) {
            let spanCol = spanCols[i];
            setSpanCount(firstRow[spanCol].firstRow, spanCol, firstRow[spanCol].count)
        }
    }

    // 获取指定行列的合并数
    getRowSpan(data, row, col) {
        let spanCount = data.getValue("spanCount", row);
        let rowSpan = 1;
        if (spanCount) {
            rowSpan = JSON.parse(spanCount)[col];
        }
        return rowSpan; 
    }

    columnRender(text, record, index, dataID, col) {
        let data = this.comp(dataID);
        return {
            children: text,
            props: {
                rowSpan: this.getRowSpan(data, record, col)
            }
        };
    }

3. 在 data 的刷新后事件中调用 initSpanCount 初始化 spanCount

如果数据有增删改查变动会影响合并计算,需要在对应事件中再次调用 initSpanCount,这个函数只会遍历数据并重新计算 spanCount,没有其他副作用

    onRestData0AfterRefresh(event){
        let data = event.source;
        this.initSpanCount(data);
    }

4. 进入.w页面源码,找到需要合并的column,增加如下的render属性

render="{$page.columnRender(text,record,index,'restData0','fDescription')}"

将restData0和fDescription改为自己的数据组件ID和列名,增加render属性后的XML大致如下

<antdpro:Table.Column xmlns:attr="http://www.wex5.com/attr" class="column" dataIndex="fDescription" id="tableColumn4" render="{$page.columnRender(text,record,index,'restData4','fDescription')}" width="120px">
    <attr:title id="default31">
        <antdpro:Typography.Text id="typographyText17" text="说明"/>
    </attr:title>
    <attr:render id="render4" />
</antdpro:Table.Column>

**注意:这个列中不能放置其他组件,即


<attr:render id="render4" />

里面必须是空的**

到这里列已经可以自动按内容合并了,如果需要垂直居中,继续下面的操作

5. 进入.w页面源码,找到需要合并的column,在class属性上添加c-columnMiddle

    class="column c-columnMiddle" 


接下来进入css页,增加如下样式  


.c-columnMiddle {
    vertical-align:middle;
}

完成

results matching ""

    No results matching ""

    results matching ""

      No results matching ""