因为项目中涉及到excel导出,以前的开发方式是请求接口,后端返回一个流,前端把流转化为excel,并下载,现在不是这套流程,是纯前端自己做的,实现的思路是,假如一共有500条数据,每次请求50次,一共请求10次,第10次请求结束后,生成excel,并导出(前端所用框架是vue,写法是按照vue的写法实现的),加上promise去实现。
1.安装插件
npm install XLSX
npm install FileSaver
因为多个页面都会用到导出excel功能,所以把封装一下方法,实现复用
import XLSX from "xlsx";
import FileSaver from 'file-saver'
export function excelData (id,name) {
let xlsxParam = { raw: true }
let wb = XLSX.utils.table_to_book(document.querySelector(`#${id}`), xlsxParam)
/* get binary string as output */
let wbout = XLSX.write(wb, { bookType: 'xlsx', bookSST: true, type: 'array' })
try {
FileSaver.saveAs(new Blob([wbout], { type: 'application/octet-stream' }), `${name}.xlsx`)
} catch (e) {
if (typeof console !== 'undefined') {
console.log(e, wbout)
}
}
return wbout
}
在组件中使用
import { excelData } from "@/excel.js"
在template里
:data="tableDataAll" id="exportId" style="display:none;" > ...省去表格的内容
data里定义数据
tableDataAll :[],//表格数据
tableDateTotal :[],//表格数据总条数
queryData :{ //查询条件
page:1,
size:10
}
这里面el-table不展示在页面,只作为导出excel使用,具体可以网上查看FileSaver这个的具体实现
exportData(){
this.tableDataAll = [];
let p = new Promise((resolve, reject)=> {
resolve();
});
//这个是获取一共有多少条,每次请求50条数据,一共请求多少次
let { tableDateTotal } = this.$data;
let num = 1;
if (tableDateTotal % 50 == 0) {
num = parseInt(tableDateTotal / 50)
}else{
num = parseInt(tableDateTotal / 50) + 1;
}
for (let i = 1; i <= num; i++) {
//i是每次请求的第几页
p = p.then(this.get_request_sth_func(i));
}
p.then(()=> {
//第一个参数,通过id去找到表格,相当去把table内容挪到excel里,第二个参数表示导出后excel的名称
excelData("exportId","课程观看数据")
setTimeout(()=>{
//导出完excel后清空这个表格,避免页面dom结构过大,毕竟也是几百条,几千条数据呢,换算成dom不少呢
this.tableDataAll=[];
},200)
});
}
get_request_sth_func(i) {
return () => {
return new Promise((resolve, reject) => {
let { queryData } = this.$data;
queryData.page = i;
delete queryData.size;
this.$axios.get("接口请求地址", { ...queryData, size: 50 }).then(res => {
this.tableDataAll.push(...res.list);
resolve();
});
});
};
},
注意一下,XLSX和FileSaver导出原理,是把页面上的table转成excel的,所以这个重点就是利用promise实现把所有的数据下完成后在页面渲染成完整的table,再去实现导出。