使用場景
后台統計經常要展示各種各樣的表格數據,幾乎每個表格展示都會伴隨着數據的導出。
之前的解決方案都是通過發起一個相同查詢參數(querystring)的導出請求(action=export),由服務器導出表格。這種方式的缺點是顯而易見的:服務器額外做了一次查詢。
JS前端直接導出
曾經我想過把當前表格數據封裝直接發給服務器然后節省查詢,總覺得太別扭了。直到前幾天偶然發現JS可以直接導出csv文件。導出的原理如下:
- a標簽的datasource功能
<a href="data:..."></a>
直接下載文件 - a標簽的
download
屬性,用以聲明下載的文件名 - csv文件的BOM頭,
data:text/csv;charset=utf-8,\ufeff
,特別指出\ufeff
是BOM頭,可以讓excel等識別出csv文件的編碼。 - encodeURIComponent() ,對csv文件的換行符
\n
進行轉碼
一個簡單的示例
js_csv = {
export_csv: function(data, name) {
// “\ufeff” BOM頭
var uri = 'data:text/csv;charset=utf-8,\ufeff' + encodeURIComponent(data);
var downloadLink = document.createElement("a");
downloadLink.href = uri;
downloadLink.download = (name+".csv")||"temp.csv";
document.body.appendChild(downloadLink);
downloadLink.click();
document.body.removeChild(downloadLink);
},
export_table: function(selector, name) {
var self = this;
if (document.querySelectorAll(selector).length == 0) {
alert('Selector "'+selector+'" not exists!');
return false;
}
self.export_csv(self.get_table_data(selector), name);
},
get_table_data: function(selector) {
var data = "";
document.querySelectorAll(selector+' tr').forEach(function(t) {
var tmp = [];
t.querySelectorAll('th,td').forEach(function(e){
tmp.push(e.innerText.replace("\n", "")); // 單元格里含有多個html元素可能會獲取到換行符
});
data += tmp.join(",") + "\n";
});
return data;
}
}
// 直接導出數據
js_csv.export_csv("dapianzi,卡夫卡,真理君,宿敵", "王路飛");
// 導出表格
js_csv.export_table("#table_id", "Some table data");