表格導出分爲靜態導出與動態導出。javascript
不管用哪一種方式進行導出,前端都須要準備一下觸發器。
咱們一般使用a標籤的download標籤來實現,十分簡易。html
// 而後經過a標籤的download進行下載 var dispatchDownload = (fileName, href) => { var a = document.createElement('a'); a.addEventListener('click', () => { a.download = fileName; a.href = href; }); var e = document.createEvent('MouseEvents'); e.initEvent('click', false, false); a.dispatchEvent(e); };
靜態導出本質上是拼接字符串,只不過特別的是這些字符串符合了.xls, .cvs文件的解析規則。
什麼格式的字符串會被解析爲正確的文件?我在GridManager中前後嘗試了兩種方式。前端
// 經過當前表格展現數據生成一組相似於下面的html string var exportHTML = ` <html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns="http://www.w3.org/TR/REC-html40"> <head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head> <body> <table> <thead> <tr> <th>姓名</th> <th>性別</th> <th>年齡</th> </tr> </thead> <tbody> <tr><td>張三</td><td>男</td><td>22</td></tr> <tr><td>李四</td><td>男</td><td>23</td></tr> <tr><td>王五</td><td>女</td><td>24</td></tr> <tr><td>趙六</td><td>女</td><td>22</td></tr> </tbody> </table> </body> </html>`; var href = `data:application/vnd.ms-excel;base64,${window.btoa(unescape(encodeURIComponent(exportHTML || '')))}`; // 經過事先聲明的dispatchDownload()函數進行下載 dispatchDownload('花名冊.xls', href);
使用這種方式存在導出文件無單元格分割線的問題,因此在GridManager v2.10.5版本中已經將該方式用 以逗號分割的字符串
方式替換。java
// 須要經過當前表格展現數據生成一組以逗號分割的字符串。 var exportStr = `姓名,性別,年齡\r\n張三,男,22\r\n李四,男,23\r\n王五,女,24\r\n趙六,女,22`; // .cvs: data:text/csv, .xls: application/vnd.ms-excel var href = `data:application/vnd.ms-excel;charset=utf-8,\ufeff${encodeURIComponent(exportStr)}`; // 經過事先聲明的dispatchDownload()函數進行下載 dispatchDownload('花名冊.xls', href);
注意: 以上兩種方式都屬於純前端操做,所導出的文件並不是真實文件,在打開時會要求進行來源確認。git
動態導出須要後端提供接口,並根據接口返回不一樣的數據進行導出。github
var getHref = () => { // 咱們假設如今有一個/download接口,該接口返回了文件地址 // http.get('/download'); // 僞裝調了下接口 return 'http://develop.lovejavascript.com/test.xlsx'; }; dispatchDownload('花名冊', getHref());
這種方式對前端來言最爲簡易,只需調用接口並將接口返回的url經過a標籤進行下載便可。
可是使用這種方式,後端須要在服務器上生成真實的文件。
前端是簡單了,但後端不只須要提供文件服務,還須要對生成的文件進行按期清理。
因此,後端小哥通常不會喜歡這種方式。
那麼,後端小哥喜歡什麼?
固然是文件流了。後端
對於後端返回的文件流,前端使用Blob方式進行導出。在調用後端接口時,須要指定request headers: {responseType: 'blob'}
var getBlog = () => { // 咱們假設如今有一個/download接口,該接口返回了文件流 // http.get('/download', headers: {responseType: 'blob'}); // 僞裝調了下接口 return blob; } // 爲防止返回數據不可用,驗證一下 var blog = getBlog(); if (Object.getPrototypeOf(blob) === Blob.prototype) { // 經過URL.createObjectURL()將Blob轉換爲URL。這個新的URL對象表示指定的File對象或Blob對象。 var url = URL.createObjectURL(blob); // 進行下載 dispatchDownload('花名冊', url); }
使用這種方式,對於前端來講也沒有什麼工做量。
並且對於後端也無需建立物理文件,僅需生成文件流並將流返回。
在發送請求時所指定的headers: {responseType: 'blob'},僅是告訴瀏覽器前端所指望獲取到的返回格式,對於後端來講無需特殊處理。瀏覽器
最後,推薦一個表格組件GridManager。以上導出的四種方式,能夠到組件源碼進行查看。服務器