需求背景

我们项目总会遇到这种导出表格数据功能,如勾选到表格哪一个,点击导出,导出excel数据时只导出勾选中的数据,不勾选时则导出全部数据,我们按照正常的逻辑来说,是需要调后端的接口,如当需要调勾选数据时,我们可能向后端传个参数如ids=['11','22'],导出全部则传空之类的。但通过我这个封装的工具类,表格上有的数据前端都可以自己导出来,接下来让我们进入正题
需求工具类封装实现
vue项目中,使用file-saver导出文件,下载Excel文件、下载图片、下载文本,关于file-saver小伙伴感兴趣的可以自行搜索功能,以及我们使用到vue中XLSX导出表格xlsx文件插件,我们项目先自行安装npm一下
npm install file-saver --save
npm install --save xlsx
代码如下
import * as XLSX from "xlsx";
import { saveAs } from 'file-saver'
/**
* @Copyright 导出工具类
* @Description: 将接口返回的数组数据导出为Excel
* @param list
* @param columns_list
* @param tabData 接口返回的列表数据 Array
* @param sheetName 待导出的excel中sheet名称 String or Array
* @param tableName 待导出的excel名称 String
* @author Chensina
* @date 2023年03月22日
* @update [序号][日期YYYY-MM-DD][更改人姓名][变更描述]
*/
export function exportAuto(list, columns_list, sheetName, tableName) {
var reData = [];
list.map((item, index) => {
var reObj = {};
columns_list
// .filter((item) => item.isShowCol)
.forEach((value, key) => {
if (value.label != undefined) {
for (let i = 0; i < Object.keys(item).length; i++) {
if (value.prop == Object.keys(item)[i]) {
if (value.prop == "num") {
reObj[value.label] = index + 1;
} else {
reObj[value.label] = Object.values(item)[i];
}
}
}
}
});
reData.push(reObj);
});
exportExcel(reData, sheetName, tableName);
}
/**
* @Copyright 导出工具类
* @Description: 将接口返回的数组数据导出为Excel
* @param tabData 接口返回的列表数据 Array
* @param sheetName 待导出的excel中sheet名称 String or Array
* @param tableName 待导出的excel名称 String
* @author Chensina
* @date 2023年03月22日
* @update [序号][日期YYYY-MM-DD][更改人姓名][变更描述]
*/
export function exportExcel(tabData, sheetName, tableName) {
let isArrayData = Array.isArray(tabData),
isArraySheet = Array.isArray(sheetName);
/* create a new blank workbook */
let wb = XLSX.utils.book_new();
if (isArrayData && isArraySheet) {
tabData.forEach((item, index) => {
XLSX.utils.book_append_sheet(
wb,
XLSX.utils.json_to_sheet(item),
sheetName[index]
);
});
} else {
let sheet = XLSX.utils.json_to_sheet(tabData);
let colWidths = [];
let colNames = Object.keys(tabData[0]); // 所有列的名称数组
// 计算每一列的所有单元格宽度
// 先遍历行
tabData.forEach((row) => {
// 列序号
let index = 0;
// 遍历列
for (const key in row) {
if (colWidths[index] == null) colWidths[index] = [];
switch (typeof row[key]) {
case "string":
case "number":
case "boolean":
colWidths[index].push(getCellWidth(row[key]));
break;
case "object":
case "function":
colWidths[index].push(0);
break;
}
index++;
}
});
let wi = [];
colWidths.forEach((widths, index) => {
// 计算列头的宽度
widths.push(getCellWidth(colNames[index]));
// 设置最大值为列宽
//wi.push({ wpx: Math.max(...widths) * 5.5 })
wi.push({ wch: Math.max(...widths) });
});
sheet["!cols"] = wi;
XLSX.utils.book_append_sheet(wb, sheet, sheetName);
}
let wbout = XLSX.write(wb, {
bookType: "xlsx",
bookSST: true,
type: "array",
});
try {
//保存文件
saveAs(
new Blob([wbout], {
type: "application/octet-stream;charset=utf-8",
}),
//`${tableName}_${new Date().Format('yyyy-MM-dd hh:mm:ss')}.xlsx`
`${tableName}.xlsx`
);
} catch (e) {
if (typeof console !== "undefined") console.log(e, wbout);
}
}
function getCellWidth(value) {
// 判断是否为null或undefined
if (value == null) {
return 10;
} else if (/.*[\u4e00-\u9fa5]+.*$/.test(value)) {
// 判断是否包含中文
return value.toString().length * 2.1;
} else {
return value.toString().length * 1.1;
/* 另一种方案
value = value.toString()
return value.replace(/[\u0391-\uFFE5]/g, 'aa').length
*/
}
}
需求实践
页面引用
<template>
<div>
<el-button type="primary" @click="exportExcel">导出</el-button>
</div>
</template>
//自己根据自己需求定义要导出的字段,如有一些状态是Y,N的,要导出中文可以自己先处理
exportcolumns: [
{ label: '序号', type: 'index' },
{
label: '销售件编码',
prop: 'setPrdCode',
width: '180',
sortable: true,
},
{
label: '销售件名称',
prop: 'setProductName',
width: '180',
sortable: true,
},
{
label: '销售件名称2',
prop: 'setProductName2',
width: '180',
sortable: true,
},
{
label: '销售件状态',
prop: 'setProductStatusName',
width: '180',
},
{
label: '营销组织',
prop: 'salesOrgName',
width: '180',
},
{
label: '产品线',
prop: 'productLineName',
width: '180',
},
],
import { exportAuto } from "@/utils/export.js";
// 导出
exportExcel() {
this.currentTime = this.getCurrentTime(); //获取当前时间
//当页面上选择数据时导出选中数据
//this.multipleSelection表格当前勾选中的数据
//exportcolumns你需要导出的字段
if (this.multipleSelection && this.multipleSelection.length > 0) {
//导出勾选数据
exportAuto(
this.multipleSelection, //勾选中的数据
this.exportcolumns, //要导出的字段
"制造码与销售码列表", //excel中sheet名称
"销售码与制造码查询结果-" + this.currentTime //导出的excel名称
);
} else {
//导出全部
if (!!this.list) {
exportAuto(
this.list,
this.exportcolumns,
"制造码与销售码列表",
"销售码与制造码查询结果-" + this.currentTime
);
}
}
},
需求效果截图
当有勾选数据时



2.当无勾选数据直接点击导出时



好的小伙伴们就在这里演示完毕,有问题的欢迎随时咨询