公司在後臺管理系統開發中用到了 vue+element-ui 組合的框架,但隨着需求的愈來愈複雜,前端的工做難度也呈幾何倍數遞增,工做量隨之增大。這不,在項目中增長一個將列表數據導出爲excel的需求就緊跟着來了。html
不光將數據導出,還得支持單筆導出或多筆批量導出。前端
前端:前端招誰惹誰了?vue
產品:入了前端門,生是前端人,死是前端鬼!git
前端: npm
產品: element-ui
爲了生活,咱們已經殫精竭慮;爲了工做,咱們已經不遺餘力!json
有需求,哭着也得實現啊。因而上網搜了一通,果真讓我發現瞭解決之道:xlsx、file-saver和script-loader。canvas
接下來就說說具體的實現方法:數組
上邊提到了三個插件:xlsx、file-saver和script-loader,對,你沒看錯,就是三個插件,實現一個功能,須要三個插件,沒辦法啊。就像你的銀行卡要用六位數的密碼來保護兩位數的餘額同樣,你有什麼辦法呢?誰讓你敗家呢?框架
1、 安裝三個依賴項
npm install -S file-saver npm install -S xlsx npm install -D script-loader
2、在項目中新建一個文件夾(通常在src下新建,文件名自取,在這裏命名爲excel),在文件夾中放入Blob.js 和 export2Excel.js (這兩個文件可在gitup上進行下載)
3、vue組件調用(因爲項目中不少頁面都會用到,因此我就封裝成了公共的方法)
import html2Canvas from 'html2canvas' import JsPDF from 'jspdf' /* * 導出excel * @param { Array } params.excelHeader 導出excel的表頭 * @param { Array } params.excelFilterVal 導出數據所需的字段(multipleSelection或defaultList對象的屬性) * @param { Array } params.multipleSelection 導出勾選的單筆或多筆數據 * @param { Array } params.defaultList 默認導出列表全部數據 * @param { Array } params.fileName 導出excel的文件名 */ export function export2Excel(params){ let excelHeader = params.excelHeader || ['類型', '合同號', '帳戶名', '幣種', '金額'] let excelFilterVal = params.excelFilterVal || ['type', 'contractCode', 'accountName', 'currency', 'amount'] require.ensure([], () => { let { export_json_to_excel } = require('@/excel/Export2Excel'); //默認爲導出所有列表,也能夠單筆導出或勾選多筆批量導出 let listArr = params.multipleSelection.length > 0 ? JSON.parse(JSON.stringify(params.multipleSelection)) : JSON.parse(JSON.stringify(params.defaultList)); let formatData = formatJson(excelFilterVal, listArr); export_json_to_excel(excelHeader, formatData, params.fileName); }) } function formatJson(excelFilterVal, listArr) { return listArr.map(v => { switch(v.type){ case '01': v.type = '小貸'; break; case '02': v.type = '租賃'; break; case '03': v.type = '電商'; break; } return excelFilterVal.map(j => v[j]); }) }
說明: 一、以上代碼在文件路徑上用到了「@」符號,不懂的同窗可自行查閱資料;
二、以上代碼用到了JSON.stringify
和JSON.parse
,主要是由於對象的引用的問題。咱們都知道,在將一個對象賦值給另外一個對象時,若是其中一個對象的某個屬性值被修改了也會影響到另外一個對象的某個屬性值的改變,這是由於他們在內存中其實是指向了同一個引用地址,因此我就先用JSON.stringify
將目標對象(這裏是一個數組,數組也是Object對象,沒毛病)轉變成一個字符串,讓其在內存中開闢一個新的地址,這樣就切斷了引用對象的指針聯繫,而後再用JSON.parse
將字符串轉變爲一個數組,就解決了引用對象之間互相影響的問題。導出excel方法中調用的formatJson函數中的type字段映射的文字跟頁面中映射的文字稍微不一樣(formatJson函數修改的是listArr數組,而listArr數組是經過頁面展現的默認數組defaultList或用戶選擇的數據數組multipleSelection賦值得來的),就會出現一個對象對另外一個對象的影響,所以不得不使用了JSON.stringify
和JSON.parse
。
三、關於multipleSelection,這個是用了element-ui中el-table的多選功能。正是這個功能纔是能實現單筆導出或多筆批量導出的關鍵,當選擇了單筆或多筆時,multipleSelection存儲的就是你選擇的數據(詳見<a href="http://element-cn.eleme.io/#/zh-CN/component/table" target="_blank">element-ui的表格組件API</a>),而後判斷該數組是否爲空,若爲空,則默認導出列表的全部數據,若不爲空,則導出選擇的列表數據: let listArr = params.multipleSelection.length > 0 ? JSON.parse(JSON.stringify(params.multipleSelection)) : JSON.parse(JSON.stringify(params.defaultList));
四、網上還有其餘解決方案,詳見<a href="https://www.jianshu.com/p/6edf74f65fc1" target="_blank">vue2.0 + element UI 中 el-table 數據導出Excel</a>等等,此類方案倒沒有本文的解決方案那麼麻煩,但有一個問題就是沒法自行選擇具體導出表格哪些列的數據,它是一股腦將表格的全部數據都導出了,包括對錶格數據的一些按鈕操做如修改按鈕、刪除按鈕等,甚至將表格第一列的checkbox複選框也導出了,雖然插件xlsx 有一個參數display爲true時能夠將隱藏的行和單元格的數組不被解析(具體使用方法沒有用過,不甚瞭解),但若是將表格的行或單元格設置爲隱藏,那咱們還在頁面中展現數據幹嗎?顯然,這種解決方案雖然簡單,但靈活度不夠,適用於比較簡單的只展現數據的表格的導出。
本文參考: https://blog.csdn.net/xiaoshihoukediaole/article/details/81296327 https://www.jianshu.com/p/6edf74f65fc1
原文出處:https://www.cnblogs.com/tnnyang/p/10339214.html