<template>
<div>
<el-button size="small" type="primary" icon="el-icon-tickets" @click="exportExcel">导出</el-button>
<el-table id="excelTable" ref="excelTable" :data="tableData" :span-method="spanMethod" border style="width: 100%"
:header-cell-style="handerMethod">
<el-table-column prop="title" label="集群" width="180" align="center">
</el-table-column>
<el-table-column prop="benlonetame" label="团队" width="180" align="center">
</el-table-column>
<el-table-column prop="total" label="总数" align="center" />
<el-table-column label="修复中" align="center">
<el-table-column prop="repairingCnt" label="修复中" align="center">
</el-table-column>
<el-table-column prop="isrepairingCnt" label="修复中占比" align="center">
<template slot-scope="scope">
{{ getisrepairingCnt(scope.row) + '%' }}
</template>
</el-table-column>
</el-table-column>
<el-table-column label="已修复" align="center">
<el-table-column prop="RepairedCnt" label="已修复" align="center"></el-table-column>
<el-table-column prop="isRepairedCnt" label="已修复占比" align="center">
<template slot-scope="scope">
{{ getisRepairedCnt(scope.row) + '%' }}
</template>
</el-table-column>
</el-table-column>
<el-table-column prop="repairDate" label="最晚修复时间" align="center"></el-table-column>
</el-table>
</div>
</template>
<script>
import { spanMethod, getExcel } from "../utils/index";
export default {
name: "",
components: {},
props: {},
data() {
return {
tableData: [
{
benlonetame: "统筹协调室",
id: 0,
repairDate: '2024-037-31',
RepairedCnt: 42,
repairingCnt: 2,
title: '统筹管理室',
total: 44
},
{
benlonetame: "核心与支付研发团队",
id: 1,
repairDate: '2024-038-31',
RepairedCnt: 2817,
repairingCnt: 210,
title: '基础服务研发集群',
total: 3027
},
{
benlonetame: "平台架构研发团队",
id: 1,
repairDate: '2024-039-31',
RepairedCnt: 4221,
repairingCnt: 462,
title: '基础服务研发集群',
total: 2788
},
{
benlonetame: "零售基础与渠道研发团队",
id: 2,
repairDate: '2024-031-31',
RepairedCnt: 4752,
repairingCnt: 222,
title: '零售应用研发集群',
total: 8160
},
{
benlonetame: "零售信贷研发团队",
id: 2,
repairDate: '2024-033-31',
RepairedCnt: 4222,
repairingCnt: 211,
title: '零售应用研发集群',
total: 442
},
{
benlonetame: "零售客户经营研发",
id: 2,
repairDate: '2024-032-31',
RepairedCnt: 42,
repairingCnt: 2,
title: '零售应用研发集群',
total: 44
},
{
benlonetame: "普惠信贷研发",
id: 3,
repairDate: '2024-034-31',
RepairedCnt: 42,
repairingCnt: 2,
title: '批发应用研发集群',
total: 44
},
{
benlonetame: "金融市场研发团队",
id: 3,
repairDate: '2024-0355-31',
RepairedCnt: 42,
repairingCnt: 2,
title: '批发应用研发集群',
total: 44
},
{
benlonetame: "对公基础",
id: 3,
repairDate: '2024-0366-31',
RepairedCnt: 42,
repairingCnt: 2,
title: '批发应用研发集群',
total: 44
},
{
benlonetame: "风险管理研发",
id: 4,
repairDate: '2024-0377-31',
RepairedCnt: 42,
repairingCnt: 2,
title: '中台服务研发集群',
total: 44
},
{
benlonetame: "协同帮呵呵",
id: 4,
repairDate: '2024-0388-31',
RepairedCnt: 42,
repairingCnt: 2,
title: '中台服务研发集群',
total: 44
},
{
benlonetame: "统筹协调室111",
id: 4,
repairDate: '2024-0399-31',
RepairedCnt: 42,
repairingCnt: 2,
title: '中台服务研发集群',
total: 44
}
],
dataArr: [],
};
},
filters: {},
computed: {},
watch: {},
created() { },
beforeDestroy() { },
methods: {
exportExcel() {
// getExcel(this.$refs.excelTable, "销售全景");
getExcel('#excelTable', '销售全景')
},
spanMethod({ row, column, rowIndex, columnIndex }) {
return spanMethod({ row, column, rowIndex, columnIndex }, this.tableData)
},
// 隐藏表头
handerMethod({ row, column, rowIndex, columnIndex }) {
// if (columnIndex === 4 || columnIndex === 6) {
// return { display: 'none' }
// }
// if (rowIndex === 0 && columnIndex === 3 || rowIndex === 0 && columnIndex === 5) {
// this.$nextTick(() => {
// document.querySelector(`.${column.id}`).setAttribute('colspan', '2')
// })
// }
},
getisrepairingCnt(obj) {
let num = 0
num = (obj.repairingCnt / obj.total) * 100
return num.toFixed(2)
},
getisRepairedCnt(obj) {
let num = 0
num = (obj.RepairedCnt / obj.total) * 100
return num.toFixed(2)
}
},
};
</script>
<style scoped lang="less">
::v-deep {
.total {
background: #f5f7fa;
}
}
</style>
//完整的导出代码
import FileSaver from "file-saver";
import * as XLSX from "xlsx";
export function getExcel(dom, title = "默认标题") {
var xlsxParam = { raw: true }; //转换成excel时,使用原始的格式
var excelTitle = title;
let tables = document.querySelector(dom).cloneNode(true);
// tables.removeChild(tables.querySelector(".el-table__fixed"));
// //反向删除函数,不能正向。否则会引起index索引错乱删除不了
// let limit = tables.querySelector(".has-gutter").children[0].childNodes;
// for (let index = limit.length - 1; index >= 0; index--) {
// const element = limit[index];
// if (element.style.display) {
// element.parentNode.removeChild(element);
// }
// }
let wb = XLSX.utils.table_to_book(tables, xlsxParam);
/* 获取二进制字符串作为输出 */
var wbout = XLSX.write(wb, {
bookType: "xlsx",
bookSST: true,
type: "array",
});
try {
FileSaver.saveAs(
new Blob([wbout], { type: "application/octet-stream" }),
excelTitle + ".xlsx"
);
} catch (e) {
if (typeof console !== "undefined") console.log(e, wbout);
}
return wbout;
}
//合并单元格
//合并的方法,里面row,colomn是这一行这一列的对象,rowIndex和colIndex就是行列的index 从0-n rowspan表示合并的行 大于1表示要往下合并了,然后下方被合并的rowspan就是0,0代表被合并了,1代表正常情况
export function spanMethod(
{ row, column, rowIndex, columnIndex },
arrList = []
) {
//columnIndex代表哪几列需要合并,后面会用
let columnArr = [0];
let jobArr = []; //所有职业id 从第一个数据到最后一个
for (let k in arrList) {
jobArr.push(arrList[k].id);
}
let obj = {};
for (let i = 0; i < jobArr.length; i++) {
if (obj[jobArr[i]] == undefined) {
obj[jobArr[i]] = 1;
} else {
obj[jobArr[i]]++;
}
}
// console.log("obj", obj); //包含每个id以及其出现的次数,为后面合并做铺垫
let spanArr = []; //每一行就是一条数据,该数组每一个值就是当前行的rowspan数
let doneArr = []; //保存被合并了的id,如果再出现,表示被合并
for (let i = 0; i < jobArr.length; i++) {
//看看个数
if (doneArr.includes(jobArr[i])) {
//如果这个id被合并过了,说明刚刚上方有一样的id,这一项就是被合并的
spanArr.push(0);
} else {
//如果没合并,就往下合并,spanArr里推入这个id的个数,在obj中就有
spanArr.push(obj[jobArr[i]]);
//别忘了合并完把id放进doneArr中
doneArr.push(jobArr[i]);
}
}
//如果是第0列和第3列
if (columnArr.includes(columnIndex)) {
//遍历合并个数的数组
for (let i = 0; i < spanArr.length; i++) {
//如果是该行,行合并个数就是这一项的值,列不合并,所以是1
if (rowIndex == i) {
return {
rowspan: spanArr[i],
colspan: 1,
};
}
}
}
}
效果图,页面显示---多级表头的导出合并
导出的表格
下面的是单级表头,合并表头的代码和导出1
//完整的导出代码
import FileSaver from "file-saver";
import * as XLSX from "xlsx";
export function getExcel(dom, title = "默认标题") {
var xlsxParam = { raw: true }; //转换成excel时,使用原始的格式
var excelTitle = title;
let tables = document.querySelector(dom).cloneNode(true);
// tables.removeChild(tables.querySelector(".el-table__fixed"));
//反向删除函数,不能正向。否则会引起index索引错乱删除不了
let limit = tables.querySelector(".has-gutter").children[0].childNodes;
for (let index = limit.length - 1; index >= 0; index--) {
const element = limit[index];
if (element.style.display) {
element.parentNode.removeChild(element);
}
}
let wb = XLSX.utils.table_to_book(tables, xlsxParam);
/* 获取二进制字符串作为输出 */
var wbout = XLSX.write(wb, {
bookType: "xlsx",
bookSST: true,
type: "array",
});
try {
FileSaver.saveAs(
new Blob([wbout], { type: "application/octet-stream" }),
excelTitle + ".xlsx"
);
} catch (e) {
if (typeof console !== "undefined") console.log(e, wbout);
}
return wbout;
}
//合并单元格
//合并的方法,里面row,colomn是这一行这一列的对象,rowIndex和colIndex就是行列的index 从0-n rowspan表示合并的行 大于1表示要往下合并了,然后下方被合并的rowspan就是0,0代表被合并了,1代表正常情况
export function spanMethod(
{ row, column, rowIndex, columnIndex },
arrList = []
) {
//columnIndex代表哪几列需要合并,后面会用
let columnArr = [0];
let jobArr = []; //所有职业id 从第一个数据到最后一个
for (let k in arrList) {
jobArr.push(arrList[k].id);
}
let obj = {};
for (let i = 0; i < jobArr.length; i++) {
if (obj[jobArr[i]] == undefined) {
obj[jobArr[i]] = 1;
} else {
obj[jobArr[i]]++;
}
}
// console.log("obj", obj); //包含每个id以及其出现的次数,为后面合并做铺垫
let spanArr = []; //每一行就是一条数据,该数组每一个值就是当前行的rowspan数
let doneArr = []; //保存被合并了的id,如果再出现,表示被合并
for (let i = 0; i < jobArr.length; i++) {
//看看个数
if (doneArr.includes(jobArr[i])) {
//如果这个id被合并过了,说明刚刚上方有一样的id,这一项就是被合并的
spanArr.push(0);
} else {
//如果没合并,就往下合并,spanArr里推入这个id的个数,在obj中就有
spanArr.push(obj[jobArr[i]]);
//别忘了合并完把id放进doneArr中
doneArr.push(jobArr[i]);
}
}
//如果是第0列和第3列
if (columnArr.includes(columnIndex)) {
//遍历合并个数的数组
for (let i = 0; i < spanArr.length; i++) {
//如果是该行,行合并个数就是这一项的值,列不合并,所以是1
if (rowIndex == i) {
return {
rowspan: spanArr[i],
colspan: 1,
};
}
}
}
}
<template>
<div>
<el-button size="small" type="primary" icon="el-icon-tickets" @click="exportExcel">导出</el-button>
<el-table id="excelTable" ref="excelTable" :data="tableData" :span-method="spanMethod" border style="width: 100%"
:header-cell-style="handerMethod">
<el-table-column prop="title" label="集群" width="180" align="center">
</el-table-column>
<el-table-column prop="benlonetame" label="团队" width="180" align="center">
</el-table-column>
<el-table-column prop="total" label="总数" align="center" />
<el-table-column prop="repairingCnt" label="修复中" align="center">
</el-table-column>
<el-table-column prop="isrepairingCnt" label="修复中占比" align="center">
<template slot-scope="scope">
{{ getisrepairingCnt(scope.row) + '%' }}
</template>
</el-table-column>
<el-table-column prop="RepairedCnt" label="已修复" align="center">
</el-table-column>
<el-table-column prop="isRepairedCnt" label="已修复占比" align="center">
<template slot-scope="scope">
{{ getisRepairedCnt(scope.row) + '%' }}
</template>
</el-table-column>
<el-table-column prop="repairDate" label="最晚修复时间" align="center"></el-table-column>
</el-table>
</div>
</template>
<script>
import { spanMethod, getExcel } from "../utils/index";
export default {
name: "",
components: {},
props: {},
data() {
return {
tableData: [
{
benlonetame: "统筹协调室",
id: 0,
repairDate: '2024-037-31',
RepairedCnt: 42,
repairingCnt: 2,
title: '统筹管理室',
total: 44
},
{
benlonetame: "核心与支付研发团队",
id: 1,
repairDate: '2024-038-31',
RepairedCnt: 2817,
repairingCnt: 210,
title: '基础服务研发集群',
total: 3027
},
{
benlonetame: "平台架构研发团队",
id: 1,
repairDate: '2024-039-31',
RepairedCnt: 4221,
repairingCnt: 462,
title: '基础服务研发集群',
total: 2788
},
{
benlonetame: "零售基础与渠道研发团队",
id: 2,
repairDate: '2024-031-31',
RepairedCnt: 4752,
repairingCnt: 222,
title: '零售应用研发集群',
total: 8160
},
{
benlonetame: "零售信贷研发团队",
id: 2,
repairDate: '2024-033-31',
RepairedCnt: 4222,
repairingCnt: 211,
title: '零售应用研发集群',
total: 442
},
{
benlonetame: "零售客户经营研发",
id: 2,
repairDate: '2024-032-31',
RepairedCnt: 42,
repairingCnt: 2,
title: '零售应用研发集群',
total: 44
},
{
benlonetame: "普惠信贷研发",
id: 3,
repairDate: '2024-034-31',
RepairedCnt: 42,
repairingCnt: 2,
title: '批发应用研发集群',
total: 44
},
{
benlonetame: "金融市场研发团队",
id: 3,
repairDate: '2024-0355-31',
RepairedCnt: 42,
repairingCnt: 2,
title: '批发应用研发集群',
total: 44
},
{
benlonetame: "对公基础",
id: 3,
repairDate: '2024-0366-31',
RepairedCnt: 42,
repairingCnt: 2,
title: '批发应用研发集群',
total: 44
},
{
benlonetame: "风险管理研发",
id: 4,
repairDate: '2024-0377-31',
RepairedCnt: 42,
repairingCnt: 2,
title: '中台服务研发集群',
total: 44
},
{
benlonetame: "协同帮呵呵",
id: 4,
repairDate: '2024-0388-31',
RepairedCnt: 42,
repairingCnt: 2,
title: '中台服务研发集群',
total: 44
},
{
benlonetame: "统筹协调室111",
id: 4,
repairDate: '2024-0399-31',
RepairedCnt: 42,
repairingCnt: 2,
title: '中台服务研发集群',
total: 44
}
],
dataArr: [],
};
},
filters: {},
computed: {},
watch: {},
created() { },
beforeDestroy() { },
methods: {
exportExcel() {
getExcel('#excelTable', '销售全景')
},
spanMethod({ row, column, rowIndex, columnIndex }) {
return spanMethod({ row, column, rowIndex, columnIndex }, this.tableData)
},
// 隐藏表头
handerMethod({ row, column, rowIndex, columnIndex }) {
if (columnIndex === 4 || columnIndex === 6) {
return { display: 'none' }
}
if (rowIndex === 0 && columnIndex === 3 || rowIndex === 0 && columnIndex === 5) {
this.$nextTick(() => {
document.querySelector(`.${column.id}`).setAttribute('colspan', '2')
})
}
},
getisrepairingCnt(obj) {
let num = 0
num = (obj.repairingCnt / obj.total) * 100
return num.toFixed(2)
},
getisRepairedCnt(obj) {
let num = 0
num = (obj.RepairedCnt / obj.total) * 100
return num.toFixed(2)
}
},
};
</script>
<style scoped lang="less">
::v-deep {
.total {
background: #f5f7fa;
}
}
</style>
效果图