antdvue实现Table末尾增加合计行

前言:

本文主要解决在Ant Design Vue中的table组件末尾增加合计行的需求。

遇到的问题点有如下几个:

  1. table中的合计行如何添加?
  2. table中不是所有列都需要合计,如何处理?
  3. 有的是 “时分秒(hh:mm:ss)” 的合计,有的是数量的合计,有的是百分数的合计,需要前端自行计算,如何处理?
  4. 合计行的数据如何居中?

一、背景

最近后台管理系统的项目中有个新需求,在统计列表中,需要在末尾展示有些数据列的合计。原型图如下:

image.png

二、table中的合计行如何添加?

官网的Table表格中给出了“总结栏”的案例参考:

image.png

按照官网的示例,可以按照如下步骤实现:

在table中加入下图这部分代码,即#summary设置合计栏,a-table-summary-rowa-table-summary-cell代码行列:

image.png

1
2
3
4
5
6
7
8
9
js复制代码<template #summary v-if="dataSource && dataSource.length">
<a-table-summary-row align="center">
<a-table-summary-cell>合计</a-table-summary-cell>
<a-table-summary-cell>-</a-table-summary-cell>
<a-table-summary-cell v-for="(item, index) in columns.slice(2)" :key="index">
<a-typography-text>{{ combinedNums(item.dataIndex, item.type) }}</a-typography-text>
</a-table-summary-cell>
</a-table-summary-row>
</template>

三、table中不是所有列都需要合计,如何处理?

如我这边的原型图所示:

  1. 第一列是“合计”的文案,第二列是“姓名”的文案,处理方式如下图:

image.png

  1. 其余列用for循环统一处理:
1
2
3
4
5
js复制代码// columns.slice(2):前两列不参与循环

<a-table-summary-cell v-for="(item, index) in columns.slice(2)" :key="index">
<a-typography-text>{{ combinedNums(item.dataIndex, item.type) }}</a-typography-text>
</a-table-summary-cell>

四、进行合计的数据类型不只是number

如原型图所示,我这边需要进行合计的有:时分秒、百分比、数量,下面分别列举解决方案。

  1. “时分秒(hh:mm:ss)” 的累加合计实现方案:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
js复制代码sumDurations(durations) {
let totalSeconds = durations.reduce((total, duration) => {
// 将时间字符串转换成时间组件
let parts = duration.split(':').map(Number);
// 将小时、分钟和秒转换为总秒数
let seconds = parts[0] * 3600 + parts[1] * 60 + parts[2];
// 累加总秒数
return total + seconds;
}, 0);

// 将总秒数转换回时间格式
let hours = Math.floor(totalSeconds / 3600);
totalSeconds %= 3600;
let minutes = Math.floor(totalSeconds / 60);
let seconds = totalSeconds % 60;

// 格式化为HH:MM:SS字符串
return [hours, minutes, seconds]
.map(num => num.toString().padStart(2, '0'))
.join(':');
}

// 示例使用
let durations = ['01:30:00', '02:15:00', '00:45:00'];
let totalDuration = sumDurations(durations);
console.log(totalDuration); // 输出累加后的时间 "04:30:00"
  1. 百分数的合计实现方案:

接口返回的是纯数字,不带百分号的值,所以需要前端进行手动拼接。

另外看需求限制保留几位小数。

ps:我这边百分数的合计是求的平均数,所以除以了数组的长度。

1
2
3
4
js复制代码const total = this.dataSource.reduce((prev: number, next: { [x: string]: any }) => {
return prev + next[field]
}, 0)
return `${(total / this.dataSource.length).toFixed(2)}%`
  1. 数量的合计实现方案:
1
2
3
js复制代码this.dataSource.reduce((prev: number, next: { [x: string]: any }) => {
return prev + next[field]
}, 0)

五、整理思路,实现结果

  1. 首先在columns数组中用type区分类型:

image.png

  1. combinedNums方法接受两个参数,分别是字段名称type类型:

image.png

具体实现方法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
js复制代码combinedNums(field: string, type: any) {
if (type === 'num') {
return this.dataSource.reduce((prev: number, next: { [x: string]: any }) => {
return prev + next[field]
}, 0)
} else if (type === 'rate') {
const total = this.dataSource.reduce((prev: number, next: { [x: string]: any }) => {
return prev + next[field]
}, 0)
return `${(total / this.dataSource.length).toFixed(2)}%`
} else {
const sumTime = this.dataSource.map((item) => {
return item[field]
})
return this.sumDurations(sumTime)
}
},

六、合计行中的文案如何居中

<a-table-summary-row>标签中加上align="center"即可:

image.png

以上,希望对大家有帮助!

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%