Bootstrap

基于iview.viewUI实现行合并(无限制/有限制合并)【已验证可正常运行】

1.基于iview.viewUI实现行合并(列之间没有所属对应关系,正常合并)

在这里插入图片描述

注:以下代码来自于GPT4o:国内直连GPT4o

只需要修改以下要合并的列字段,就可以方便使用啦

mergeFields: ['majorNo', 'devNam', 'overhaulAdvice', 'level']
<template>
    <div style="margin-top:200px">
        <Table :columns="columns14" :data="data5" border :span-method="handleSpan"></Table>
    </div>
</template>

<script>
export default {
    data() {
        return {
            columns14: [
                {
                    title: '序号',
                    key: 'index'
                },
                {
                    title: '专业名称',
                    key: 'majorNo'
                },
                {
                    title: '设备名称',
                    key: 'devNam'
                },
                {
                    title: '检修建议',
                    key: 'overhaulAdvice'
                },
                {
                    title: '综合评价等级',
                    key: 'level'
                }
            ],
            resData: [
                {
                    id: '1',
                    devNam: 'CVS设备',
                    overhaulAdvice: "异常说明",
                    level: '未见异常',
                    majorNo: '风电',
                    index: 1
                },
                {
                    id: '2',
                    devNam: 'CVS设备',
                    overhaulAdvice: "异常说明",
                    level: '未见异常',
                    majorNo: '风电',
                    index: 2
                },
                {
                    id: '3',
                    devNam: '设备1',
                    overhaulAdvice: "异常说明",
                    level: '未见异常',
                    majorNo: '锅炉、风电',
                    index: 3
                },
                {
                    id: '4',
                    devNam: '设备1',
                    overhaulAdvice: "异常说明",
                    level: '未见异常',
                    majorNo: '锅炉、风电',
                    index: 4
                },
                {
                    id: '5',
                    devNam: 'CVS设备1',
                    overhaulAdvice: "异常说明",
                    level: '未见异常',
                    majorNo: '锅炉',
                    index: 5
                },
            ],
            data5: [],
            mergeFields: ['majorNo', 'devNam', 'overhaulAdvice', 'level']
        };
    },
    methods: {
        // 合并单元格的处理方法
        handleSpan({ row, column, rowIndex, columnIndex }) {
            const mergeField = this.columns14[columnIndex].key;
            const mergeKey = `merge${mergeField.charAt(0).toUpperCase() + mergeField.slice(1)}`;
            if (this.mergeFields.includes(mergeField)) {
                return [row[mergeKey], row[mergeKey] ? 1 : 0];
            }
        },
        // 组装数据以便处理合并单元格
        assembleData(data) {
            const mergeData = {};

            this.mergeFields.forEach(field => {
                mergeData[field] = {};
                data.forEach(row => {
                    const fieldValue = row[field];
                    if (!mergeData[field][fieldValue]) {
                        mergeData[field][fieldValue] = [];
                    }
                    mergeData[field][fieldValue].push(row);
                });
            });

            const mergeCounts = {};
            Object.keys(mergeData).forEach(field => {
                mergeCounts[field] = {};
                Object.keys(mergeData[field]).forEach(key => {
                    mergeCounts[field][key] = mergeData[field][key].length;
                });
            });

            const fieldIndex = {};
            data.forEach(row => {
                this.mergeFields.forEach(field => {
                    const mergeKey = `merge${field.charAt(0).toUpperCase() + field.slice(1)}`;
                    if (!fieldIndex[field]) {
                        fieldIndex[field] = {};
                    }
                    if (!fieldIndex[field][row[field]]) {
                        fieldIndex[field][row[field]] = 0;
                    }
                    if (fieldIndex[field][row[field]] === 0) {
                        row[mergeKey] = mergeCounts[field][row[field]];
                    } else {
                        row[mergeKey] = 0;
                    }
                    fieldIndex[field][row[field]]++;
                });
            });

            this.data5 = data;
        }
    },
    mounted() {
        // 模拟后台返回的数据
        this.assembleData(this.resData);
    }
};
</script>


2.基于iview.viewUI实现行合并(列之间有对应关系,只合并属于前一列值所属的内容)

在这里插入图片描述

<template>
    <div style="margin-top:200px">
        <Table :columns="columns14" :data="data5" border :span-method="handleSpan"></Table>
    </div>
</template>

<script>
export default {
    data() {
        return {
            columns14: [
                {
                    title: '序号',
                    key: 'index'
                },
                {
                    title: '专业名称',
                    key: 'majorNo'
                },
                {
                    title: '设备名称',
                    key: 'devNam'
                },
                {
                    title: '检修建议',
                    key: 'overhaulAdvice'
                },
                {
                    title: '综合评价等级',
                    key: 'level'
                }
            ],
            resData: [
                {
                    id: '1',
                    devNam: 'CVS设备',
                    overhaulAdvice: "异常说明",
                    level: '未见异常',
                    majorNo: '风电',
                    index: 1
                },
                {
                    id: '2',
                    devNam: 'CVS设备',
                    overhaulAdvice: "异常说明",
                    level: '未见异常',
                    majorNo: '风电',
                    index: 2
                },
                {
                    id: '3',
                    devNam: '设备1',
                    overhaulAdvice: "异常说明",
                    level: '未见异常',
                    majorNo: '锅炉、风电',
                    index: 3
                },
                {
                    id: '4',
                    devNam: '设备1',
                    overhaulAdvice: "异常说明",
                    level: '未见异常',
                    majorNo: '锅炉、风电',
                    index: 4
                },
                {
                    id: '5',
                    devNam: 'CVS设备1',
                    overhaulAdvice: "异常说明",
                    level: '未见异常',
                    majorNo: '锅炉',
                    index: 5
                },
            ],
            data5: [],
        };
    },
    methods: {
        // 合并单元格的处理方法
        handleSpan({ row, column, rowIndex, columnIndex }) {
            if (columnIndex === 1) {
                return [row.mergeMajorNo, row.mergeMajorNo ? 1 : 0];
            }
            if (columnIndex === 2) {
                return [row.mergeDevNam, row.mergeDevNam ? 1 : 0];
            }
            if (columnIndex === 3) {
                return [row.mergeOverhaulAdvice, row.mergeOverhaulAdvice ? 1 : 0];
            }
            if (columnIndex === 4) {
                return [row.mergeLevel, row.mergeLevel ? 1 : 0];
            }
        },
        // 组装数据以便处理合并单元格
        assembleData(data) {
            let majorNos = [];
            let devNamesByMajorNo = {};
            let overhaulAdviceByDevName = {};
            let levelByDevName = {};

            // 获取所有唯一的专业名称,并初始化每个专业名称对应的设备名称列表
            data.forEach(e => {
                if (!majorNos.includes(e.majorNo)) {
                    majorNos.push(e.majorNo);//q:这句代码的作用是什么? a:获取所有唯一的专业名称
                    devNamesByMajorNo[e.majorNo] = [];//q:这句代码的作用是什么? a:初始化每个专业名称对应的设备名称列表
                }
                if (!devNamesByMajorNo[e.majorNo].includes(e.devNam)) {//q:这句代码的作用是什么? a:获取每个专业名称对应的设备名称列表
                    devNamesByMajorNo[e.majorNo].push(e.devNam);
                }

                if (!overhaulAdviceByDevName[e.devNam]) { //q:这句代码的作用是什么? a:初始化每个设备名称对应的检修建议列表
                    overhaulAdviceByDevName[e.devNam] = [];
                }
                if (!overhaulAdviceByDevName[e.devNam].includes(e.overhaulAdvice)) { //q:这句代码的作用是什么? a:获取每个设备名称对应的检修建议列表
                    overhaulAdviceByDevName[e.devNam].push(e.overhaulAdvice);
                }

                if (!levelByDevName[e.devNam]) {  //q:这句代码的作用是什么? a:初始化每个设备名称对应的综合评价等级列表
                    levelByDevName[e.devNam] = [];
                }
                if (!levelByDevName[e.devNam].includes(e.level)) {  //q:这句代码的作用是什么? a:获取每个设备名称对应的综合评价等级列表
                    levelByDevName[e.devNam].push(e.level);
                }
            });

            let majorNoNums = []; // 专业名称的合并单元格数
            let devNameNumsByMajorNo = {};  // 设备名称的合并单元格数 //q:为什么专业名称的合并单元格数是数组,这里是对象? a:因为专业名称是唯一的,设备名称是不唯一的
            let overhaulAdviceNumsByDevName = {}; // 检修建议的合并单元格数
            let levelNumsByDevName = {};  // 综合评价等级的合并单元格数

            // 初始化每个专业名称和设备名称的合并单元格数
            majorNos.forEach(e => {
                majorNoNums.push({ majorNo: e, num: 0 });
                devNameNumsByMajorNo[e] = [];
                devNamesByMajorNo[e].forEach(devNam => {
                    devNameNumsByMajorNo[e].push({ devNam: devNam, num: 0 });
                });
            });

            // 初始化每个设备名称下的检修建议和综合评价等级的合并单元格数
            for (let devNam in overhaulAdviceByDevName) {
                overhaulAdviceNumsByDevName[devNam] = [];
                overhaulAdviceByDevName[devNam].forEach(overhaulAdvice => {
                    overhaulAdviceNumsByDevName[devNam].push({ overhaulAdvice: overhaulAdvice, num: 0 });
                });

                levelNumsByDevName[devNam] = [];
                levelByDevName[devNam].forEach(level => {
                    levelNumsByDevName[devNam].push({ level: level, num: 0 });
                });
            }

            // 计算每个专业名称和设备名称需要合并的单元格数
            data.forEach(e => {
                majorNoNums.forEach(d => {
                    if (e.majorNo === d.majorNo) {
                        d.num++;
                    }
                });
                devNameNumsByMajorNo[e.majorNo].forEach(n => {
                    if (e.devNam === n.devNam) {
                        n.num++;
                    }
                });

                overhaulAdviceNumsByDevName[e.devNam].forEach(n => {
                    if (e.overhaulAdvice === n.overhaulAdvice) {
                        n.num++;
                    }
                });

                levelNumsByDevName[e.devNam].forEach(n => {
                    if (e.level === n.level) {
                        n.num++;
                    }
                });
            });

            // 更新数据中的合并单元格数
            data.forEach(e => {
                majorNoNums.forEach(d => {
                    if (e.majorNo === d.majorNo) {
                        if (majorNos.includes(e.majorNo)) {
                            e.mergeMajorNo = d.num;
                            majorNos.splice(majorNos.indexOf(d.majorNo), 1);
                        } else {
                            e.mergeMajorNo = 0;
                        }
                    }
                });
                devNameNumsByMajorNo[e.majorNo].forEach(n => {
                    if (e.devNam === n.devNam) {
                        if (devNamesByMajorNo[e.majorNo].includes(e.devNam)) {
                            e.mergeDevNam = n.num;
                            devNamesByMajorNo[e.majorNo].splice(devNamesByMajorNo[e.majorNo].indexOf(e.devNam), 1);
                        } else {
                            e.mergeDevNam = 0;
                        }
                    }
                });

                overhaulAdviceNumsByDevName[e.devNam].forEach(n => {
                    if (e.overhaulAdvice === n.overhaulAdvice) {
                        if (overhaulAdviceByDevName[e.devNam].includes(e.overhaulAdvice)) {
                            e.mergeOverhaulAdvice = n.num;
                            overhaulAdviceByDevName[e.devNam].splice(overhaulAdviceByDevName[e.devNam].indexOf(e.overhaulAdvice), 1);
                        } else {
                            e.mergeOverhaulAdvice = 0;
                        }
                    }
                });

                levelNumsByDevName[e.devNam].forEach(n => {
                    if (e.level === n.level) {
                        if (levelByDevName[e.devNam].includes(e.level)) {
                            e.mergeLevel = n.num;
                            levelByDevName[e.devNam].splice(levelByDevName[e.devNam].indexOf(e.level), 1);
                        } else {
                            e.mergeLevel = 0;
                        }
                    }
                });
            });

            // 将整理后的数据交给表格渲染
            this.data5 = data;
        }
    },
    mounted() {
        // 模拟后台返回的数据
        this.assembleData(this.resData);
    }
};
</script>


;