el-table表格得合并行和列
好久没写了,今天记录一下帮别人做得一个小需求。基于element-plus的table。
一、先展示一下效果吧
二、上代码
<el-table :data="data" border :span-method="onSpanMethod" style="width: 100%;" height="100%">
<el-table-column prop="field1" label="field1"></el-table-column>
<el-table-column prop="field2" label="field2"></el-table-column>
<el-table-column prop="field3" label="field3"></el-table-column>
<el-table-column prop="filed4" label="filed4"></el-table-column>
<el-table-column prop="filed5" label="filed5"></el-table-column>
</el-table>
<script setup lang="ts">
import { spanRow } from "@/utils/tableSpan";
const data = [
{ field1: "营业收费系统", field2: "中国农业银行", field3: "2022-03", filed4: '2022-03-04', filed5: '4' },
{ field1: "营业收费系统", field2: "中国农业银行", field3: "2022-03", filed4: '2022-03-05', filed5: '2' },
{ field1: "营业收费系统", field2: "中国农业银行", field3: "2022-03", filed4: '2022-03-06', filed5: '2' },
{ field1: "营业收费系统", field2: "中国农业银行", field3: "2022-03", filed4: '2022-03-07', filed5: '2' },
{ field1: "营业收费系统", field2: "中国农业银行", field3: "小计", filed4: '', filed5: '2' },
{ field1: "营业收费系统", field2: "中国建设银行", field3: "2022-04", filed4: '2022-04-05', filed5: '3' },
{ field1: "营业收费系统", field2: "中国建设银行", field3: "2022-04", filed4: '2022-04-06', filed5: '2' },
{ field1: "营业收费系统", field2: "中国建设银行", field3: "2022-04", filed4: '2022-04-07', filed5: '2' },
{ field1: "营业收费系统", field2: "中国建设银行", field3: "2022-04", filed4: '2022-04-08', filed5: '2' },
{ field1: "营业收费系统", field2: "中国建设银行", field3: "小计", filed4: '', filed5: '2' },
{ field1: "营业收费系统", field2: "小计", field3: "", filed4: '', filed5: '1' },
{ field1: "报装管理系统", field2: "中国农业银行", field3: "2022-03", filed4: '2022-03-04', filed5: '12' },
{ field1: "报装管理系统", field2: "中国农业银行", field3: "2022-03", filed4: '2022-03-05', filed5: '21' },
{ field1: "报装管理系统", field2: "中国农业银行", field3: "2022-03", filed4: '2022-03-06', filed5: '21' },
{ field1: "报装管理系统", field2: "中国农业银行", field3: "2022-03", filed4: '2022-03-07', filed5: '21' },
{ field1: "报装管理系统", field2: "中国农业银行", field3: "小计", filed4: '', filed5: '6' },
{ field1: "报装管理系统", field2: "中国建设银行", field3: "2022-04", filed4: '2022-04-05', filed5: '11' },
{ field1: "报装管理系统", field2: "中国建设银行", field3: "2022-04", filed4: '2022-04-06', filed5: '53' },
{ field1: "报装管理系统", field2: "中国建设银行", field3: "2022-04", filed4: '2022-04-07', filed5: '53' },
{ field1: "报装管理系统", field2: "中国建设银行", field3: "2022-04", filed4: '2022-04-08', filed5: '53' },
{ field1: "报装管理系统", field2: "中国建设银行", field3: "小计", filed4: '', filed5: '32' },
{ field1: "报装管理系统", field2: "小计", field3: "", filed4: '', filed5: '23' },
]
const option = [
{ index: 0, field: "field1" },
{ index: 1, field: "field2" },
{ index: 2, field: 'field3' }
]
const onSpanMethod = ({ row, column, rowIndex, columnIndex }: any) => {
return spanRow(
{ row, column, rowIndex, columnIndex },
data,
option
);
}
</script>
主要逻辑就是用的下面这个方法,你可以用一个ts或者js文件封装一下,类型没有规范自己规范一下。
import { watch, computed, unref } from 'vue';
let rowspanArray: any
function spanRow({ row, column, rowIndex, columnIndex }: any, data: any, option: any) {
if (rowIndex === 0 && columnIndex === 0) {
computeSpanRow(data, option)
}
if ((unref(getCollection(data)) as number[]).includes(rowIndex)) {
if (columnIndex === 1) {
return [1, 2]
} else if (columnIndex > 1 && columnIndex < 3) {
return [0, 0]
}
}
if (is(option, columnIndex)) {
const rowspan = rowspanArray[columnIndex][rowIndex]
const colspan = rowspan > 0 ? 1 : 0
return {
rowspan: rowspan,
colspan: colspan
}
}
return {
rowspan: 1,
colspan: 1
}
}
// 获取分组得个数集合
function getCollection(data: any) {
return computed(() => {
const newData: any = {}
const arr: any = []
data.forEach((items: any) => {
let keys: any = items.field1
if (!newData.hasOwnProperty(items.field1)) {
newData[keys] = [items]
} else {
newData[keys].push(items)
}
});
Object.keys(newData).forEach((res: any, index: number) => {
if (newData[res].length) {
if (!arr.length) {
arr.push(newData[res].length - 1)
} else {
arr.push(newData[res].length + arr[arr.length - 1])
}
}
})
return arr
})
}
function computeSpanRow(data: any, option: any) {
rowspanArray = []
let tempRow = []
for (let i = 0; i < data.length; i++) {
for (let j = 0; j < option.length; j++) {
let index = option[j].index;
let field = option[j].field;
if (i === 0) {
tempRow[index] = 0
rowspanArray[index] = []
rowspanArray[index].push(1)
} else {
if (data[i][field] === data[i - 1][field]) {
rowspanArray[index][tempRow[index]] += 1
rowspanArray[index].push(0)
} else {
rowspanArray[index].push(1)
tempRow[index] = i
}
}
}
}
}
function is(option: any, index: any) {
for (let i = 0; i < option.length; i++) {
if (option[i].index === index) {
return true
}
}
return false
}
export { spanRow }