一、前言
在项目开发中,有时候会遇到一下特殊的表格数据,需要进行单元格合并、自定义表格的合计类等! 通过element table实现一下效果: 注意:累计(合计)栏也需要进行单元格的合并,并且完成率的合计是所有完成率相加并除以个数
二、实现效果
1. 表格(模拟)数据
data() {
return {
isLoading: false,
tableData: [],
templateData: [
{
company: '乌鲁木齐分公司',
companyId: 1,
centerId: 10,
centerName: '乌鲁木齐ETC客服中心',
name: '古丽米热.玉素普',
toatlAccept: 9,
toatlEnd: 9,
finish: 100,
totalDisposing: 0,
todayAccept:0,
todayEnd: 0,
postpone: 0
},
{
company: '乌鲁木齐分公司',
companyId: 1,
centerId: 10,
centerName: '乌鲁木齐ETC客服中心',
name: '安妮卡.阿迪力',
toatlAccept: 12,
toatlEnd: 11,
finish: 91.67,
totalDisposing: 1,
todayAccept:6,
todayEnd: 6,
postpone: 0
},
{
company: '乌鲁木齐分公司',
companyId: 1,
centerId: 11,
centerName: '吉昌ETC客服中心',
name: '张雨薇',
toatlAccept: 23,
toatlEnd: 23,
finish: 100,
totalDisposing: 0,
todayAccept:5,
todayEnd: 5,
postpone: 2
},
{
company: '乌鲁木齐分公司',
companyId: 1,
centerId: 11,
centerName: '吉昌ETC客服中心',
name: '地里那拉.地里下提',
toatlAccept: 1,
toatlEnd: 1,
finish: 100,
totalDisposing: 0,
todayAccept:0,
todayEnd: 0,
postpone: 0
},
{
company: '博乐分公司',
companyId: 2,
centerId: 12,
centerName: '伊犁ETC客服中心',
name: '王楠',
toatlAccept: 4,
toatlEnd: 4,
finish: 100,
totalDisposing: 0,
todayAccept:0,
todayEnd: 0,
postpone: 0
},
{
company: '博乐分公司',
companyId: 2,
centerId: 12,
centerName: '伊犁ETC客服中心',
name: '蒋世杰',
toatlAccept: 13,
toatlEnd: 13,
finish: 100,
totalDisposing: 0,
todayAccept:5,
todayEnd: 5,
postpone: 0
},
{
company: '博乐分公司',
companyId: 2,
centerId: 13,
centerName: '博乐ETC客服中心',
name: '哈力亚.普拉提',
toatlAccept: 19,
toatlEnd: 19,
finish: 100,
totalDisposing: 0,
todayAccept:4,
todayEnd: 4,
postpone: 2
}
],
}
}
2. vue template实现
<div class="table-box">
<el-table ref="tableRef" :data="tableData" row-key="id" v-loading="isLoading" border
show-summary :summary-method="getSummaries" :span-method="tableSpanMethod">
<el-table-column type="index" label="序号" width="50"></el-table-column>
<el-table-column prop="company" label="分公司" width="140"></el-table-column>
<el-table-column prop="centerName" label="ETC客服中心"></el-table-column>
<el-table-column prop="name" label="处置人员"></el-table-column>
<el-table-column prop="toatlAccept" label="累计受理" width="120"></el-table-column>
<el-table-column prop="toatlEnd" label="累计办结" width="120"></el-table-column>
<el-table-column prop="finish" label="完成率" width="120">
<template slot-scope="scope">
<span>{{ scope.row.finish }}%</span>
</template>
</el-table-column>
<el-table-column prop="totalDisposing" label="累计待处置" width="120"></el-table-column>
<el-table-column prop="todayAccept" label="当日受理" width="120"></el-table-column>
<el-table-column prop="todayEnd" label="当日办结" width="120"></el-table-column>
<el-table-column prop="postpone" label="申请延期" width="120"></el-table-column>
</el-table>
</div>
3. 单元格合并
getTableList() {
this.isLoading = true;
setTimeout(() => {
this.isLoading = false
let companyList = [], centerList = [];
let companyMerge = {},centerMerge = {};
this.templateData.forEach(item => {
const ixExist = companyList.find(em => item.companyId === em);
const centerExist = centerList.find(em => item.centerId === em);
if (!ixExist) {
companyList.push(item.companyId);
companyMerge[item.companyId] = 1;
} else {
companyMerge[item.companyId]++;
}
if(!centerExist) {
centerList.push(item.centerId);
centerMerge[item.centerId] = 1;
} else {
centerMerge[item.centerId]++
}
});
this.templateData.forEach((item, index) => {
if (index === 0) {
if (companyMerge[item.companyId] && companyMerge[item.companyId] > 0) {
item.companySpan = [companyMerge[item.companyId], 1];
}
if (centerMerge[item.centerId] && centerMerge[item.centerId] > 0) {
item.centerSpan = [centerMerge[item.centerId], 1];
}
} else {
if (companyMerge[item.companyId] && this.templateData[index].companyId === this.templateData[index-1].companyId) {
item.companySpan = [0, 0];
} else {
item.companySpan = [companyMerge[item.companyId], 1];
}
if (centerMerge[item.centerId] && this.templateData[index].centerId === this.templateData[index-1].centerId) {
item.centerSpan = [0, 0];
} else {
item.centerSpan = [centerMerge[item.centerId], 1];
}
}
})
this.tableData = this.templateData
}, 2000);
},
tableSpanMethod({ row, column, rowIndex, columnIndex }) {
if (columnIndex === 1) {
return row.companySpan
} else if (columnIndex === 2) {
return row.centerSpan
}
},
4. 自定义合计栏(自定义每一个单元格的合计数据、合并单元格)
getSummaries(param) {
const { columns, data } = param;
let sums = [];
columns.forEach((column, index) => {
if (index === 0 || index === 1 || index === 2 || index === 3) {
sums[index] = '累计'
} else {
const values = data.map(item => Number(item[column.property]));
if (!values.every(value => isNaN(value))) {
sums[index] = values.reduce((prev, curr) => {
const value = Number(curr);
if (!isNaN(value)) {
return prev + curr;
} else {
return prev;
}
}, 0);
}
}
if (index === 6) {
sums[index] = (sums[index] / this.tableData.length).toFixed(2) + '%'
}
})
this.timer = setTimeout(() => {
if (this.$refs.tableRef.$el) {
let current = this.$refs.tableRef.$el .querySelector('.el-table__footer-wrapper') .querySelector('.el-table__footer');
let cell = current.rows[0].cells;
cell[0].colSpan = '4';
cell[0].style.textAlign = 'center';
cell[1].style.display = 'none';
cell[2].style.display = 'none';
cell[3].style.display = 'none';
}
}, 50);
return sums;
}
::v-deep .table-box{
.el-table {
overflow: auto;
.el-table__body-wrapper,.el-table__header-wrapper,.el-table__footer-wrapper{
overflow: visible;
}
}
}
三、完整代码
<template>
<div class="container">
<div class="btn-box">
<el-button v-if="permissions.export_traffic_servie_workload" class="custom-icon-btn" type="primary" @click="handleExport">
<img class="btn-icon" src="@/assets/images/icon_btn_download.png" alt="" />
导出内容
</el-button>
</div>
<div class="workload">
<div class="filter-box">
<el-form ref="form" :inline="true" :model="formData">
<el-form-item label="日期:" prop="date">
<el-date-picker v-model="formData.date" type="daterange" range-separator="至" start-placeholder="开始日期"
style="width: 280px;" end-placeholder="结束日期" :clearable="false" value-format="yyyy-MM-dd"></el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleSubmit">查询</el-button>
<el-button @click="handleReset">重置</el-button>
</el-form-item>
</el-form>
</div>
<div class="table-box">
<el-table ref="tableRef" :data="tableData" row-key="id" v-loading="isLoading" border
show-summary :summary-method="getSummaries" :span-method="tableSpanMethod">
<el-table-column type="index" label="序号" width="50"></el-table-column>
<el-table-column prop="company" label="分公司" width="140"></el-table-column>
<el-table-column prop="centerName" label="ETC客服中心"></el-table-column>
<el-table-column prop="name" label="处置人员"></el-table-column>
<el-table-column prop="toatlAccept" label="累计受理" width="120"></el-table-column>
<el-table-column prop="toatlEnd" label="累计办结" width="120"></el-table-column>
<el-table-column prop="finish" label="完成率" width="120">
<template slot-scope="scope">
<span>{{ scope.row.finish }}%</span>
</template>
</el-table-column>
<el-table-column prop="totalDisposing" label="累计待处置" width="120"></el-table-column>
<el-table-column prop="todayAccept" label="当日受理" width="120"></el-table-column>
<el-table-column prop="todayEnd" label="当日办结" width="120"></el-table-column>
<el-table-column prop="postpone" label="申请延期" width="120"></el-table-column>
</el-table>
</div>
</div>
</div>
</template>
<script>
import { mapGetters } from 'vuex';
export default {
name: 'ServiceWorkoad',
computed: {
...mapGetters(['permissions']),
},
data() {
return {
formData: {
date: ''
},
isLoading: false,
tableData: [],
templateData: [
{
company: '乌鲁木齐分公司',
companyId: 1,
centerId: 10,
centerName: '乌鲁木齐ETC客服中心',
name: '古丽米热.玉素普',
toatlAccept: 9,
toatlEnd: 9,
finish: 100,
totalDisposing: 0,
todayAccept:0,
todayEnd: 0,
postpone: 0
},
{
company: '乌鲁木齐分公司',
companyId: 1,
centerId: 10,
centerName: '乌鲁木齐ETC客服中心',
name: '安妮卡.阿迪力',
toatlAccept: 12,
toatlEnd: 11,
finish: 91.67,
totalDisposing: 1,
todayAccept:6,
todayEnd: 6,
postpone: 0
},
{
company: '乌鲁木齐分公司',
companyId: 1,
centerId: 11,
centerName: '吉昌ETC客服中心',
name: '张雨薇',
toatlAccept: 23,
toatlEnd: 23,
finish: 100,
totalDisposing: 0,
todayAccept:5,
todayEnd: 5,
postpone: 2
},
{
company: '乌鲁木齐分公司',
companyId: 1,
centerId: 11,
centerName: '吉昌ETC客服中心',
name: '地里那拉.地里下提',
toatlAccept: 1,
toatlEnd: 1,
finish: 100,
totalDisposing: 0,
todayAccept:0,
todayEnd: 0,
postpone: 0
},
{
company: '博乐分公司',
companyId: 2,
centerId: 12,
centerName: '伊犁ETC客服中心',
name: '王楠',
toatlAccept: 4,
toatlEnd: 4,
finish: 100,
totalDisposing: 0,
todayAccept:0,
todayEnd: 0,
postpone: 0
},
{
company: '博乐分公司',
companyId: 2,
centerId: 12,
centerName: '伊犁ETC客服中心',
name: '蒋世杰',
toatlAccept: 13,
toatlEnd: 13,
finish: 100,
totalDisposing: 0,
todayAccept:5,
todayEnd: 5,
postpone: 0
},
{
company: '博乐分公司',
companyId: 2,
centerId: 13,
centerName: '博乐ETC客服中心',
name: '哈力亚.普拉提',
toatlAccept: 19,
toatlEnd: 19,
finish: 100,
totalDisposing: 0,
todayAccept:4,
todayEnd: 4,
postpone: 2
}
],
}
},
beforeDestroy() {
clearTimeout(this.timer);
},
mounted() {
this.getTableList();
},
methods: {
handleExport() {
},
handleSubmit() {
},
handleReset() {
this.formData = {
date: ''
}
},
getTableList() {
this.isLoading = true;
setTimeout(() => {
this.isLoading = false
let companyList = [], centerList = [];
let companyMerge = {},centerMerge = {};
this.templateData.forEach(item => {
const ixExist = companyList.find(em => item.companyId === em);
const centerExist = centerList.find(em => item.centerId === em);
if (!ixExist) {
companyList.push(item.companyId);
companyMerge[item.companyId] = 1;
} else {
companyMerge[item.companyId]++;
}
if(!centerExist) {
centerList.push(item.centerId);
centerMerge[item.centerId] = 1;
} else {
centerMerge[item.centerId]++
}
});
this.templateData.forEach((item, index) => {
if (index === 0) {
if (companyMerge[item.companyId] && companyMerge[item.companyId] > 0) {
item.companySpan = [companyMerge[item.companyId], 1];
}
if (centerMerge[item.centerId] && centerMerge[item.centerId] > 0) {
item.centerSpan = [centerMerge[item.centerId], 1];
}
} else {
if (companyMerge[item.companyId] && this.templateData[index].companyId === this.templateData[index-1].companyId) {
item.companySpan = [0, 0];
} else {
item.companySpan = [companyMerge[item.companyId], 1];
}
if (centerMerge[item.centerId] && this.templateData[index].centerId === this.templateData[index-1].centerId) {
item.centerSpan = [0, 0];
} else {
item.centerSpan = [centerMerge[item.centerId], 1];
}
}
})
this.tableData = this.templateData
}, 2000);
},
tableSpanMethod({ row, column, rowIndex, columnIndex }) {
if (columnIndex === 1) {
return row.companySpan
} else if (columnIndex === 2) {
return row.centerSpan
}
},
getSummaries(param) {
const { columns, data } = param;
let sums = [];
columns.forEach((column, index) => {
if (index === 0 || index === 1 || index === 2 || index === 3) {
sums[index] = '累计'
} else {
const values = data.map(item => Number(item[column.property]));
if (!values.every(value => isNaN(value))) {
sums[index] = values.reduce((prev, curr) => {
const value = Number(curr);
if (!isNaN(value)) {
return prev + curr;
} else {
return prev;
}
}, 0);
}
}
if (index === 6) {
sums[index] = (sums[index] / this.tableData.length).toFixed(2) + '%'
}
})
this.timer = setTimeout(() => {
if (this.$refs.tableRef.$el) {
let current = this.$refs.tableRef.$el .querySelector('.el-table__footer-wrapper') .querySelector('.el-table__footer');
let cell = current.rows[0].cells;
cell[0].colSpan = '4';
cell[0].style.textAlign = 'center';
cell[1].style.display = 'none';
cell[2].style.display = 'none';
cell[3].style.display = 'none';
}
}, 50);
return sums;
}
}
}
</script>
<style lang='scss' scoped>
.btn-box {
display: flex;
justify-content: flex-end;
.custom-icon-btn {
background: #3883ff;
}
}
.workload {
background: #fff;
margin-top: 16px;
padding: 16px;
.filter-box {
.el-form {
display: flex;
justify-content: space-between;
}
}
::v-deep .table-box{
.el-table { // 在表格上添加滚动条
overflow: auto;
// 表格内容区域的滚动条不要,都在改滚动条将处于合计栏上方
.el-table__body-wrapper,.el-table__header-wrapper,.el-table__footer-wrapper{
overflow: visible;
}
}
}
}
</style>
文章仅为本人学习过程的一个记录,仅供参考,如有问题,欢迎指出!
|