实例如下
首先咱们要实现行合并的问题必须要研究一下官方里面的案例:
会发现行的合并实现于,customerRender里面的参数配置attrs下面的rowSpan,项让该条数据的该项合并几行就rowSpan=number
let obj = {
//item为表的一个字段名
title:"name",
dataIndex: key,
//渲染控制
customRender: (value, row, index) => {
const tempobj = {
children: value,
attrs: {
rowSpan: row[key + "Merge"],
},
};
return tempobj ;
},
};
//这里let obj是组成column的对象
实现的思路是:1、根据后端返回数据,生成合并行的参数,存入对应行数据中。2、根据给的数据遍历出不确定字段的表头。3、给表格新数据渲染生成表格。
1.编写页面提供假数据,引用js表格处理文件
<a-table
:scroll="{ x: 'max-content' }"
:rowKey="
(record, index) => {
return index;
}
"
:columns="columns"
:dataSource="tableData"
size="middle"
class="table-standbook"
:pagination="false"
:loading="loading"
@change="onPageChanged"
bordered
>
</a-table>
data() {
return {
columns: [
{ title: "单位", dataIndex: "danwei" },
{ title: "分类", dataIndex: "fenlei" },
{ title: "用途", dataIndex: "yongtu" },
],
tableData: [
{
danwei: "羊场湾一区",
fenlei: "深度处理",
yongtu: "生产",
11: "22",
22: "123",
33: "123",
44: "123",
55: "123",
66: "123",
77: "123",
88: "123",
99: "123",
10: "123",
13: "454",
12: "123",
},
{
danwei: "羊场湾一区",
fenlei: "深度处理",
yongtu: "绿化",
11: "22",
22: "123",
33: "123",
44: "123",
55: "123",
66: "123",
77: "123",
88: "123",
99: "123",
10: "123",
13: "454",
12: "123",
},
{
danwei: "羊场湾一区",
fenlei: "生活污水",
yongtu: "绿化",
11: "22",
22: "123",
33: "123",
44: "123",
55: "123",
66: "123",
77: "123",
88: "123",
99: "123",
10: "123",
13: "454",
12: "123",
},
{
danwei: "羊场湾一区",
fenlei: "新鲜水",
yongtu: "生活",
11: "22",
22: "123",
33: "123",
44: "123",
55: "123",
66: "123",
77: "123",
88: "123",
99: "123",
10: "123",
13: "454",
12: "123",
},
{
danwei: "羊场湾一区",
fenlei: "新鲜水",
yongtu: "生产",
11: "22",
22: "123",
33: "123",
44: "123",
55: "123",
66: "123",
77: "123",
88: "123",
99: "123",
10: "123",
13: "454",
12: "123",
},
{
danwei: "羊场湾一区",
fenlei: "新鲜水",
yongtu: "绿化",
11: "22",
22: "123",
33: "123",
44: "123",
55: "123",
66: "123",
77: "123",
88: "123",
99: "123",
10: "123",
13: "454",
12: "123",
},
{
danwei: "枣泉",
fenlei: "回用水",
yongtu: "绿化",
11: "22",
22: "123",
33: "123",
44: "123",
55: "123",
66: "123",
77: "123",
88: "123",
99: "123",
10: "123",
13: "454",
12: "123",
},
{
danwei: "枣泉",
fenlei: "生活污水",
yongtu: "绿化",
11: "22",
22: "123",
33: "123",
44: "123",
55: "123",
66: "123",
77: "123",
88: "123",
99: "123",
10: "123",
13: "454",
12: "123",
},
{
danwei: "枣泉",
fenlei: "深度处理",
yongtu: "生产",
11: "22",
22: "123",
33: "123",
44: "123",
55: "123",
66: "123",
77: "123",
88: "123",
99: "123",
10: "123",
13: "454",
12: "123",
},
{
danwei: "枣泉",
fenlei: "深度处理",
yongtu: "绿化",
11: "22",
22: "123",
33: "123",
44: "123",
55: "123",
66: "123",
77: "123",
88: "123",
99: "123",
10: "123",
13: "454",
12: "123",
},
],
exportColumns: [],
form: this.$form.createForm(this),
};
},
mounted() {
//标识哪几列可以做行合并
const tempcol = ["danwei", "fenlei", "yongtu"];
// 表格渲染时候,获得合并参数
this.tableData = getNeedMerge(this.tableData, tempcol);
// 传入cloumns
this.columns = setColumnMerge(this.columns, tempcol, this.tableData);
},
2、在处理js(HandleTable.js)里面编写
/* data为表格数据
mergecol:哪几类列需要进行行处理[]
*/
export function getNeedMerge(list, mergecol) {
let data = addColAtrr(list, mergecol);
// 列循环
mergecol.forEach((key, index) => {
let addattr = key + "Merge";
let pre = index == 0 ? "" : mergecol[index - 1];
console.log(pre);
let flag = data[data.length - 1][pre] + data[data.length - 1][key];
console.log(flag);
let count = 0;
for (let i = data.length - 1; i >= 0; i--) {
if (data[i][pre] + data[i][key] == flag) {
// 开始计数
count = count + 1;
if (i == 0) {
data[i][addattr] = count;
}
} else {
flag = data[i][pre] + data[i][key];
// 处理前面一样的合并数
data[i + 1][addattr] = count;
for (let x = count; x > 1; x--) {
data[i + x][addattr] = 0;
}
count = 1;
if (i == 0) {
data[i][addattr] = 1;
}
}
}
});
console.log(data);
return data;
}
/* 添加新字段*/
function addColAtrr(data, mergecol) {
let obj = {};
let arr = data.concat();
mergecol.forEach((ele) => {
obj[ele + "Merge"] = 0;
});
arr.forEach((element, index) => {
arr.splice(index, 1, Object.assign({}, element, obj));
});
return arr;
}
/* data:表格数据,column表头 传入具体合并值 */
export function setColumnMerge(column, mergecol, tableData) {
// 根据数据内容获得表头
let backarr = [];
mergecol.forEach((key) => {
let obj = {
title: backtitleName(column, key),
dataIndex: key,
customRender: (value, row, index) => {
// 打印可以看出传入当前行的数据
// console.log(row);
const tempobj = {
children: value,
attrs: {
rowSpan: row[key + "Merge"],
},
};
return tempobj;
},
};
backarr.push(obj);
});
// 除了需要做合并的表头外还要添加普通的表头根据获取的表格数据动态添加
let otherTitle = backCommonTitle(tableData[0], mergecol);
// 根据上面数组获得表头
let arr = backarr.concat(backColums(otherTitle));
return arr;
}
/* 返回表头名称 */
function backtitleName(list, key) {
let name = "";
list.forEach((item) => {
if (item.dataIndex == key) {
name = item.title;
}
});
return name;
}
// 返回(需要合并表头之外的普通表头)
function backCommonTitle(obj, usedList) {
usedList.forEach((item) => {
usedList.push(item + "Merge");
});
let temparr = Object.keys(obj);
return temparr.concat(usedList).filter(function (v, i, arr) {
return arr.indexOf(v) === arr.lastIndexOf(v);
});
}
/* 根据数组生成普通column数组 */
function backColums(list) {
let backarr = [];
list.forEach((item) => {
let obj = {
title: item + "月",
dataIndex: item,
};
backarr.push(obj);
});
return backarr;
}
重点:如果想让行的合并更加严谨,不会出现(前一个字段属于不同的单位下,依然合并了)
解决办法第一就是要控住类似的数据不要挨着,第二就是把flag的值描述的更加确切。(目前只是绑定了当前字段和前一个)绑定前面两个譬如“枣泉新鲜水绿化”这样拼接就不会将不同组别的合并了。我项目暂时使用到目前代码的写法就能够满足了。
3、目前还没有对接具体的后端数据,目测还需要对数据排序处理啥的,之后补充一下这一块。
内容原创,如有搬运著名出处。