表格導出分爲靜態導出與動態導出。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。 app
以上導出的四種方式,能夠到組件源碼進行查看。