使用JavaScript下載csv文件


前端可以使用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函數接收三個參數:

  1. data:需要下載的數據(注意數據格式需要符合csv格式規范);
  2. filename:需要下載的文件名,注意需要添加符合數據格式的文件名的后綴,這提示了操作系統應該以何種方式打開;
  3. type:代表了將會被放入到Blob對象中的數組內容的MIME類型;

(二)Blob 構造函數

接着,我們來解析下面這條語句:

var file = new Blob(["\ufeff" + data], { type: type });

可以看到,我們使用了Blob構造函數,創建了一個Blob實例對象fileBlob構造函數有什么用呢?它接收的兩個參數是什么?讓我們在下面一一作答:

① Blob 構造函數的作用

Blob構造函數會根據傳入的數組參數構造出一個新的Blob對象實例,該對象實例的值由以下兩步生成:

  1. Blob構造函數會將第一個參數,即一個數組內的所有值串聯起來;
  2. 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構造函數接收的第二個參數是一個對象,該對象有以下兩個屬性:

  1. type:默認值為"",它表示第一個參數內,數組內容的MIME類型;
  2. 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都只有這些瀏覽器提供支持。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM