排序代码参考博主:https://blog.csdn.net/yijiupingfan0914/article/details/84304371
按第一列、第二列进行合并,要先将表格数据进行重新排序,再进行数据的合并。先按照第一行进行合并,再在第一行的基础上进行第二行的合并,合并效果如下图。
完整代码如下:
<!DOCTYPE html>
<!-- <html xmlns="http://www.w3.org/1999/xhtml"> -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>表格相同行数据合并</title>
<link rel="stylesheet" href="thirdParty/element-ui@2.15.0/theme-chalk/index.css">
<script src="./thirdParty/jquery@3.4.1/jquery.js"></script>
<script src="./thirdParty/vue@2.6.12/vue.js"></script>
<script src="./thirdParty/element-ui@2.15.0/index.js"></script>
</head>
<body>
<el-table id="tableVue" :data="dataSource" border stripe :span-method="objectSpanMethods" style="width:80%">
<el-table-column v-for="col in columns" :prop="col.id" :key="col.id" :label="col.label" :min-width="col.width">
</el-table-column>
</el-table>
<script>
// 获取到要比较的具体数值,option为要进行比较的每项数据,propName为要比较的具体属性
function getValue(option, propName) {
if (!propName) {
return option;
}
var data = option;
propName.split('.').filter(function (item) {
data = data[item];
})
return data + '';
}
// 将内容按某个字段排序(中文排序),此时先比较第一列,做合并之后再在当前的基础上依次比较剩余列,arr为要进行比较的数组,propArr为要比较的所有属性的集合
function sortChinese(arr, propArr) {
propArr.map((prop, index) => {
if (index == 0) {
arr.sort(function (item1, item2) {
return getValue(item1, prop).localeCompare(getValue(item2, prop), 'zh-CN');
})
} else {
arr.sort(function (item1, item2) {
if (item1[propArr[index - 1]] == item2[propArr[index - 1]]) {
return getValue(item1, prop).localeCompare(getValue(item2, prop), 'zh-CN');
}
})
}
})
}
// 合并表格相同的行,table为要进行比较的数组,columnCollections为要比较的所有属性的集合
function mergeTheSameRow(table, columnCollections) {
sortChinese(table, columnCollections);
let firstColArr = [], secondColArr = [];
let firstPos = 0, secondPos = 0;
for (var i = 0; i < table.length; i++) {
if (i === 0) {
firstColArr.push(1);
firstPos = 0;
secondColArr.push(1);
secondPos = 0;
} else {
if (table[i][columnCollections[0]] === table[i - 1][columnCollections[0]]) {
firstColArr[firstPos] += 1;
firstColArr.push(0);
} else {
firstColArr.push(1);
firstPos = i;
}
if (table[i][columnCollections[1]] === table[i - 1][columnCollections[1]]) {
secondColArr[secondPos] += 1;
secondColArr.push(0);
} else {
secondColArr.push(1);
secondPos = i;
}
}
}
return [firstColArr, secondColArr];
}
var vm = new Vue({
el: '#tableVue',
data: {
dataSource: [{
area: '东区',
type: 'C类',
name: '杀破狼',
code: '4628558584729885',
description: '经年痴心妄想,一时走火入魔。 --priest'
}, {
area: '西区',
type: 'B类',
name: '大哥',
code: '4625857298884585',
description: '修你一世喜乐安稳。 --priest'
}, {
area: '东区',
type: 'A类',
name: '天涯客',
code: '4285585847298685',
description: '一眼万年轻,唯此心如旧。 --priest'
}, {
area: '西区',
type: 'B类',
name: '镇魂',
code: '7298854628558584',
description: '邓林之阴,初见昆仑君,惊鸿一瞥,乱我心曲。 --priest'
}, {
area: '西区',
type: 'A类',
name: '默读',
code: '5585847462829885',
description: '未经允许,擅自特别喜欢你,不好意思了。 --priest'
}],
columns: [{
id: 'area',
label: '区域',
width: '10%'
}, {
id: 'type',
label: '类别',
width: '10%'
}, {
id: 'name',
label: '书名',
width: '10%'
}, {
id: 'code',
label: '编号',
width: '20%'
}, {
id: 'description',
label: '描述',
width: '50%'
}],
spanObj: { firstCol: [], secondCol: [] }
},
methods: {
// 合并相邻两行同类型的数据(只对第一列、第二列生效)
objectSpanMethods({ row, column, rowIndex, columnIndex }) {
if (columnIndex === 0) {
const _row1 = this.spanObj.firstCol[rowIndex];
const _col1 = _row1 > 0 ? 1 : 0;
return {
rowspan: _row1,
colspan: _col1
}
}
if (columnIndex === 1) {
const _row2 = this.spanObj.secondCol[rowIndex];
const _col2 = _row2 > 0 ? 1 : 0;
return {
rowspan: _row2,
colspan: _col2
}
}
}
},
mounted() {
let returnTableResult = mergeTheSameRow(this.dataSource, ['area', 'type']);
this.spanObj.firstCol = returnTableResult[0];
this.spanObj.secondCol = returnTableResult[1];
}
})
</script>
</body>
</html>