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>