標籤:序列 數組參數 屬性 ring gpo 需要 作用 而在 div
前端可以使用JavaScript在用戶端下載包含頁面資料的檔案,這裡以下載CSV格式檔案為例,代碼如下:
function downloadData(data, filename, type) { var file = new Blob(["\ufeff" + data], { type: type }); if (window.navigator.msSaveOrOpenBlob) // IE10+ window.navigator.msSaveOrOpenBlob(file, filename); else { // Others var a = document.createElement("a"), url = URL.createObjectURL(file); a.href = url; a.download = filename; document.body.appendChild(a); a.click(); setTimeout(function() { document.body.removeChild(a); window.URL.revokeObjectURL(url); }, 0); } }
讓我們解釋一下這段代碼:
(一)downloadData 函數
首先,downloadData
函數接收三個參數:
data
:需要下載的資料(注意資料格式需要符合csv格式規範);
filename
:需要下載的檔案名稱,注意需要添加符合資料格式的檔案名稱的尾碼,這提示了作業系統應該以何種方式開啟;
type
:代表了將會被放入到Blob
對象中的數組內容的MIME類型;
(二)Blob 建構函式
接著,我們來解析下面這條語句:
var file = new Blob(["\ufeff" + data], { type: type });
可以看到,我們使用了Blob
建構函式,建立了一個Blob執行個體對象file
。Blob
建構函式有什麼用呢?它接收的兩個參數是什嗎?讓我們在下面一一作答:
① Blob 建構函式的作用
Blob建構函式會根據傳入的數組參數構造出一個新的Blob對象執行個體,該對象執行個體的值由以下兩步產生:
- Blob建構函式會將第一個參數,即一個數組內的所有值串聯起來;
- Blob會將被串聯的值轉換為二進位編碼的資料然後返回;
注意,Blob對象執行個體的值是不可變的,它只有兩個唯讀屬性:size
:表示對象中所包含資料的大小(單位是位元組),以及type
:值是一個字串,表示該對象執行個體所包含資料的MIME類型(即我們傳入Blob建構函式的第二個參數中指定的type
值,預設為""
)。
② Blob 建構函式接收的參數
Blob建構函式接收的第一個參數為數群組類型,數組內的所有值會在執行個體化時被串聯。若傳入數組的值中有DOMString
類型的值,則會被編碼為UTF-8
格式。而為了讓匯出的CSV格式檔案在Excel中開啟時,中文不出現亂碼,需要在數組的首位添加一個BOM(Byte Order Mark “位元組次序標記”)頭\ufeff
。
BOM是一個不可見的字元,它是ES5新增的空白符,在Unicode3.2之前,\uFEFF
表示“零寬不換行空格(Zero Width No-Break Space)”,但在Unicode3.2之後,新增了\u2060
表示零寬不換行空格,\uFEFF
就只用來表示位元組次序的標記了。而在Microsoft中,其記事本程式發明了一種UTF-8變體(Python 2.5稱為“utf-8-sig”)以提高可檢測到UTF-8編碼的可靠性,該編碼要求在任何Unicode字元被寫入之前都需要編寫一個UTF-8編碼的BOM(看起來像是一個位元組序列:0xef,0xbb,0xbf)。
Blob建構函式接收的第二個參數是一個對象,該對象有以下兩個屬性:
type
:預設值為""
,它表示第一個參數內,數組內容的MIME類型;
options
:這個屬性目前還沒有被很好的支援,所以不用管它;
總之,我們通過new Blob()
獲得了一個Blob類型的二進位檔案。
(三)下載檔案
接著我們要做的便是下載我們產生好的檔案了,有兩種方式,第一種方式最簡單,因為IE瀏覽器直接提供了下載檔案的介面window.navigator.msSaveOrOpenBlob(file, filename);
,正如函數簽名所示,我們只需要向函數中傳入我們產生好的二進位檔案,以及檔案名稱就可以讓瀏覽器自動下載檔案了。
拋下IE瀏覽器,要實現檔案下載就稍微麻煩些,我們需要通過建立一個a標籤,並類比點擊這個a標籤實現檔案下載,讓我們將與之相關的代碼貼在下面:
var a = document.createElement("a"), url = URL.createObjectURL(file);a.href = url;a.download = filename;document.body.appendChild(a);a.click();setTimeout(function() { document.body.removeChild(a); window.URL.revokeObjectURL(url);}, 0);
注意這段代碼的第二行,我們會發現一個新的API:URL.createObjectURL()
函數,這個函數接收一個參數,一個Blob對象,並為該對象產生一個指向該對象的URL對象,需要注意的是只要當下文檔沒有被關閉,該URL對象就會一直儲存在記憶體中不會被回收,因此一旦確定不再需要該URL對象,一定要及時使用URL.revokeObjectURL()
清理。
以上,我們就解釋了在前端以CSV格式下載資料的方法和原理,需要注意的是,該段代碼只適用於IE10及以上的現代瀏覽器,因為無論是Blob建構函式還是URL.createObjectURL()
API都只有這些瀏覽器提供支援。
使用JavaScript下載csv檔案