参考地址:https://blog.csdn.net/hefeng6500/article/details/82778680?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase
实现如图功能:
html: 其中:span-method="dataArraySpanMethod"
是合并列需要的属性
<template>
<div>
<el-table class="crmonepage-hello" ref="tabled" :data="list" style="width: 100%" :span-method="dataArraySpanMethod">
<el-table-column
v-for="(col,index) in cols"
:label="col.label"
:key="index"
:width="col.width || null"
:prop="col.prop"
>
<el-table-column
v-for="(props, propsindex) in col.propsChildren"
:label="props.label"
:key="propsindex"
:width="props.width || null"
:prop="props.prop"
></el-table-column>
</el-table-column>
</el-table>
<button @click="exportExcel"></button>
</div>
</template>
数据格式:
data() {
return {
list: [
{aQty: "1",bQty: "8",cQty: "2",dQty: "-1",eQty: "11",brand: "一点点",brand2: "列合并测试",brand3: "测试"},
{aQty: "3",bQty: "2",cQty: "12",dQty: "-3",eQty: "121",brand: "一点点",brand2: "列合并测试",brand3: "测试"},
{aQty: "13",bQty: "2",cQty: "24",dQty: "-1",eQty: "11",brand: "点点",brand2: "行合并",brand3: "测试"}
], // 数据
cols: [
{prop: "brand",label: "面包店", width: null},
{prop: "brand2",label: "列合并测试",width: null},
{prop: "brand3",label: "测试面包店",width: null},
{prop: "Production",label: "饮料",width: null,propsChildren: [{prop: "aQty",label: "西瓜汁",width: null,}]},
{prop: "market",label: "食物数量",width: null,propsChildren: [
{prop: "bQty",label: "菜包",width: 150},
{prop: "cQty",label: "肉包",width: 150},
{prop: "dQty",label: "苹果",width: 150},
{prop: "eQty",label: "西瓜",width: 150}]
},
], // 网格列
// 合并列数数组
spanArr: [],
spanArr2: [],
pos: 0,
pos2: 0,
dataArraySpanMethod:function(){} // 因为dataArraySpanMethod属性定义的是函数
};
},
mounted() {
this.merge();
},
methods: {
// 判断需要合并的重复项 获得其所在数组下标
getSpanArr(data) {
this.spanArr = [];
this.spanArr2 = [];
for (var i = 0; i < data.length; i++) {
if (i === 0) {
this.spanArr.push(1);
this.spanArr2.push(1);
this.pos = 0;
this.pos2 = 0;
} else {
if (data[i].brand === data[i - 1].brand) { // 判断面包店
this.spanArr[this.pos] += 1;
this.spanArr.push(0);
} else {
this.spanArr.push(1);
this.pos = i;
}
//
if (data[i].brand2 === data[i - 1].brand2) { // 判断列合并测试
this.spanArr2[this.pos2] += 1;
this.spanArr2.push(0);
} else {
this.spanArr2.push(1);
this.pos2 = i;
}
}
}
},
merge() {
const that=this
this.getSpanArr(this.list);
that.dataArraySpanMethod = function({row,column,rowIndex,columnIndex}) {
// 列合并
if (columnIndex === 0) { //表示下标为0的列数
const _row = that.spanArr[rowIndex];
const _col = _row > 0 ? 1 : 0;
// 行合并
if(rowIndex==2){ //表示下标为0的列数,为2的行数 向右合并两格
return{rowspan:1,colspan:2}
}
// 列合并
return {
rowspan: _row,
colspan: _col
};
}
if (columnIndex === 1) { // 表示下标为1的列数
const _row = that.spanArr2[rowIndex];
const _col = _row > 0 ? 1 : 0;
if(rowIndex==2){ //表示下标为1的列数,为2的行数 解决串行问题 !!注意一定要添加,如果不添加则如图一显示
return{rowspan:0,colspan:0}
}
// 合并列
return {
rowspan: _row,
colspan: _col
};
}
};
},
图一:
如果是组件之间使用合并属性 dataArraySpanMethod
则需要在引入的组件中定义ref 例:
that.$refs.tabled.dataArraySpanMethod = function({row,column,rowIndex,columnIndex}) {}
导出:
引入以下依赖
import FileSaver from "file-saver";
import XLSX from "xlsx";
import Vue from "vue";
// 导出
exportExcel() {
let str = "面包店测试.xlsx";//导出文档名称
// 判断要导出的节点中是否有fixed的表格,如果有,转换excel时先将该dom移除,然后append回去 解决重复数据问题
var fix = document.querySelector(".el-table__fixed");
var wb;
if (fix) {
wb = XLSX.utils.table_to_book(
//导出表格类名
document.querySelectorAll(".crmonepage-hello")[0].removeChild(fix)
);
document.querySelectorAll(".crmonepage-hello")[0].appendChild(fix);
} else {
wb = XLSX.utils.table_to_book(
document.querySelectorAll(".crmonepage-hello")[0]
);
}
var wbout = XLSX.write(wb, {
bookType: "xlsx",
bookSST: true,
type: "array"
});
try {
FileSaver.saveAs(
new Blob([wbout], { type: "application/octet-stream" }),
str
);
} catch (e) {
if (typeof console !== "undefined") console.log(e, wbout);
}
return wbout;
}
}