vue 按列合并单元格
要求
使用vue对每页表格进行单元格合并,每列纵向一致的内容合并,但要参照第一列合并情况,后面的列不能跨列合并,第二列和最后一列不合并。
思路
将首列进行合并单元格计算,然后依次将后面列按照首列合并结果进行分组,然后依次给每个分组进行合并单元格计算,最后依次将该列的多个分组内容合并。
完整的html代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vue Table with Merged Cells</title>
<link
rel="stylesheet"
href="https://unpkg.com/element-ui/lib/theme-chalk/index.css"
/>
</head>
<body>
<div id="app">
<template>
<div>
<el-table
:data="billList" border style="width: 100%; margin-top: 20px" :span-method="objectSpanMethod">
<el-table-column prop="packNo" label="票据包号"> </el-table-column>
<el-table-column prop="range" label="该列无需合并">
</el-table-column>
<el-table-column prop="TNo" label="编号(都一致)">
</el-table-column>
<el-table-column prop="company" label="公司名称">
</el-table-column>
<el-table-column prop="DateA" label="日期">
</el-table-column>
<el-table-column prop="dscntAmt" label="金额">
</el-table-column>
<el-table-column prop="dscntBkAreaNm" label="贴现机构">
</el-table-column>
<el-table-column prop="relaType" label="关联人类型">
</el-table-column>
<el-table-column prop="relaName" label="关联人名称">
</el-table-column>
<el-table-column prop="relaAcc" label="账号(不合并)">
</el-table-column>
</el-table>
</div>
</template>
</div>
</body>
<script src="https://unpkg.com/vue@2.6.14/dist/vue.js"></script>
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<script>
var Main = {
data() {
return {
billList: [
{
alarmId: "6304fcd-ythy-7689-5678",
dscntAmt: "3,068.00",
dscntBkAreaNm: "xx机构",
TNo: "1234567",
DateA: "2021-12-28",
company: "一二三有限公司",
packNo: "10477",
range: "-",
relaAcc: "1",
relaName: "衣",
relaType: "类型A",
},
{
alarmId: "6304fcd-ythy-7689-5678",
dscntAmt: "515,123.89",
dscntBkAreaNm: "xx机构",
TNo: "1234567",
DateA: "2021-12-28",
company: "一二三有限公司",
packNo: "68083",
range: "-",
relaAcc: "2",
relaName: "小儿",
relaType: "类型A",
},
{
alarmId: "6304fcd-ythy-7689-5678",
dscntAmt: "3,111.00",
dscntBkAreaNm: "xx机构",
TNo: "1234567",
DateA: "2021-12-28",
company: "一二三有限公司",
packNo: "10477",
range: "-",
relaAcc: "3",
relaName: "小三年",
relaType: "类型B",
},
{
alarmId: "6304fcd-ythy-7689-5678",
dscntAmt: "3,000.00",
dscntBkAreaNm: "xx机构",
TNo: "1234567",
DateA: "2021-12-28",
company: "一二三有限公司",
packNo: "10477",
range: "-",
relaAcc: "4",
relaName: "小似",
relaType: "类型C",
},
{
alarmId: "6304fcd-ythy-7689-5678",
dscntAmt: "3,000.00",
dscntBkAreaNm: "xx机构",
TNo: "1234567",
DateA: "2021-12-28",
company: "一二三有限公司",
packNo: "10477",
range: "-",
relaAcc: "5",
relaName: "无",
relaType: "类型C",
},
{
alarmId: "6304fcd-ythy-7689-5678",
dscntAmt: "515,456.89",
dscntBkAreaNm: "xx机构",
TNo: "1234567",
DateA: "2021-12-28",
company: "一二三有限公司",
packNo: "68083",
range: "-",
relaAcc: "6",
relaName: "流",
relaType: "类型B",
},
{
alarmId: "6304fcd-ythy-7689-5678",
dscntAmt: "515,456.89",
dscntBkAreaNm: "xx机构",
TNo: "1234567",
DateA: "2021-12-28",
company: "一二三有限公司",
packNo: "68083",
range: "-",
relaAcc: "7",
relaName: "其",
relaType: "类型C",
},
{
alarmId: "6304fcd-ythy-7689-5678",
dscntAmt: "316,133.33",
dscntBkAreaNm: "xx机构",
TNo: "1234567",
DateA: "2023-2-31",
company: "一二三有限公司",
packNo: "07536",
range: "-",
relaAcc: "8",
relaName: "八",
relaType: "类型A",
},
{
alarmId: "6304fcd-ythy-7689-5678",
dscntAmt: "2,070,658.92",
dscntBkAreaNm: "xx机构",
TNo: "1234567",
DateA: "2023-2-31",
company: "一二三有限公司",
packNo: "07536",
range: "-",
relaAcc: "9",
relaName: "旧9",
relaType: "类型A",
},
{
alarmId: "6304fcd-ythy-7689-5678",
dscntAmt: "316,133.33",
dscntBkAreaNm: "xx机构",
TNo: "1234567",
DateA: "2023-2-31",
company: "一二三有限公司",
packNo: "07536",
range: "-",
relaAcc: "10",
relaName: "市",
relaType: "类型B",
},
],
//spanArr用于存放每一行记录的合并数
all: [],
packNoList: [],
};
},
mounted() {
let packNoDot = 0;
this.billList.forEach((item, index) => {
if (index === 0) {
this.packNoList.push(1);
} else {
if (item.packNo === this.billList[index - 1].packNo) {
this.packNoList[packNoDot] += 1;
this.packNoList.push(0);
} else {
packNoDot = index;
this.packNoList.push(1);
}
}
});
this.all[0] = this.packNoList;
this.all[1] = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1];
this.all[2] = this.getGroupArray(
this.getblankArray(this.packNoList, "TNo")
);
this.all[3] = this.getGroupArray(
this.getblankArray(this.packNoList, "company")
);
this.all[4] = this.getGroupArray(
this.getblankArray(this.packNoList, "DateA")
);
this.all[5] = this.getGroupArray(
this.getblankArray(this.packNoList, "dscntAmt")
);
this.all[6] = this.getGroupArray(
this.getblankArray(this.packNoList, "dscntBkAreaNm")
);
this.all[7] = this.getGroupArray(
this.getblankArray(this.packNoList, "relaType")
);
this.all[8] = this.getGroupArray(
this.getblankArray(this.packNoList, "relaName")
);
this.all[9] = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1];
for (var key in this.all) {
console.log(key + " : " + this.all[key]);
}
},
methods: {
objectSpanMethod({ row, column, rowIndex, columnIndex }) {
const _row = this.all[columnIndex][rowIndex];
const _col = _row > 0 ? 1 : 0;
//该形式为行合并
return {
rowspan: _row,
colspan: _col,
};
},
//分组计算每组合并,并将结果
getGroupArray(temp) {
var tempSub = [];
for (var key in temp) {
if (temp[key].length === 1) {
tempSub.push(1);
} else {
var tempSubSub = [];
var tempSubSubDot = 0;
temp[key].forEach((item, index) => {
if (index === 0) {
tempSubSub.push(1);
} else {
if (item === temp[key][index - 1]) {
tempSubSub[tempSubSubDot] += 1;
tempSubSub.push(0);
} else {
tempSubSubDot = index;
tempSubSub.push(1);
}
}
});
for (var key in tempSubSub) {
tempSub.push(tempSubSub[key]);
}
}
}
return tempSub;
},
// 获取该列按照第一列分组后的数组
getblankArray(packNoList, columnName) {
var temp = [];
for (var key in this.packNoList) {
var subTemp = [];
for (k = 0; k < this.packNoList[key]; k++) {
subTemp.push("");
}
if (subTemp.length > 0) {
temp.push(subTemp);
}
}
var s1 = 0;
for (var key in temp) {
for (i = 0; i < temp[key].length; i++) {
temp[key][i] = this.billList[s1][columnName];
s1 = s1 + 1;
}
}
return temp;
},
},
};
var Ctor = Vue.extend(Main);
new Ctor().$mount("#app");
</script>
</html>
效果如下: