因為項目中涉及到excel導(dǎo)出酗捌,以前的開發(fā)方式是請求接口呢诬,后端返回一個流,前端把流轉(zhuǎn)化為excel胖缤,并下載馅巷,現(xiàn)在不是這套流程,是純前端自己做的草姻,實現(xiàn)的思路是,假如一共有500條數(shù)據(jù)稍刀,每次請求50次撩独,一共請求10次,第10次請求結(jié)束后账月,生成excel综膀,并導(dǎo)出(前端所用框架是vue,寫法是按照vue的寫法實現(xiàn)的),加上promise去實現(xiàn)局齿。
1.安裝插件
npm install?XLSX
npm install?FileSaver
因為多個頁面都會用到導(dǎo)出excel功能剧劝,所以把封裝一下方法,實現(xiàn)復(fù)用
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里
<el-button?type="primary"? @click="exportData"?size="small">導(dǎo)出數(shù)據(jù)</el-button>
<el-table
??????:data="tableDataAll"
??????id="exportId"
??????style="display:none;"
????>
? ? ...省去表格的內(nèi)容
</el-table>
data里定義數(shù)據(jù)
tableDataAll :[],//表格數(shù)據(jù)
tableDateTotal :[],//表格數(shù)據(jù)總條數(shù)
queryData :{? //查詢條件
? ? page:1,
? ? size:10
}
這里面el-table不展示在頁面抓歼,只作為導(dǎo)出excel使用讥此,具體可以網(wǎng)上查看FileSaver這個的具體實現(xiàn)
?exportData(){
? ??this.tableDataAll?=?[];
? ? ? let p?=?new?Promise((resolve,?reject)=>?{
????????resolve();
??????});
? ? //這個是獲取一共有多少條,每次請求50條數(shù)據(jù)谣妻,一共請求多少次
? ? 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(()=>?{
? ? ? ? ?//第一個參數(shù)萄喳,通過id去找到表格,相當去把table內(nèi)容挪到excel里蹋半,第二個參數(shù)表示導(dǎo)出后excel的名稱
?????????excelData("exportId","課程觀看數(shù)據(jù)")
????????setTimeout(()=>{
? ? ? ? ? ? //導(dǎo)出完excel后清空這個表格他巨,避免頁面dom結(jié)構(gòu)過大,畢竟也是幾百條减江,幾千條數(shù)據(jù)呢染突,換算成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導(dǎo)出原理辈灼,是把頁面上的table轉(zhuǎn)成excel的份企,所以這個重點就是利用promise實現(xiàn)把所有的數(shù)據(jù)下完成后在頁面渲染成完整的table,再去實現(xiàn)導(dǎo)出茵休。