Web 端 js 導出csv文件(使用a標籤)

前言

導出文件,使用最多的方式還是服務器端來處理。比如jsp 中使用response 的方式。

但是,有時候可能就想使用web 前端是否也可以把頁面上的內容導出來呢? 比如說,導出頁面的一個表格。

這個需求肯定是有答案的,只是對於各瀏覽器處理會稍微不一樣。(主要是IE 和其他瀏覽器的區別)。

在IE中使用ActiveXObject 實現,在firefox 和Chrome 中使用  a 標籤(或者js)就可以實現了。 這裏主要講一下其他瀏覽器中的實現。


使用 a 標籤實現方式

直接上例子:

[html] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  
  2. <html>  
  3.   <head>  
  4.   <meta http-equiv="content-type" content="text/html; charset=utf-8">  
  5.   <meta name="author" content="oscar999">  
  6.   <title></title>  
  7.   </head>  
  8.   <body>  
  9.     <a id="test" download="downlaod.txt" href="data:text/txt;charset=utf-8,download Test Data">download</a>  
  10.   </body>  
  11. </html>  
說明一下:

1. download 設置下載的文件名。

2. href 加上 data:text/txt;charset=utf-8  分別設置點擊link 是下載文件, 編碼是utf-8 . 這個逗號後面的就是保存在文件中的內容了。


以多行,多列導出csv 文件

csv 文件可以用Excel打開, 如果是導出一個table 的話,使用Excel 就方便很多了。

問題是: 如何分行, 分列?

理論上 : 分列使用 , 號分割, 分行用 \n .

可以用以上方式,會發現列可以分開,但是不換行。 看上去不認識 \n.

解決方式是使用 encodeURIComponent 進行編碼/

[html] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1.   <head>  
  2.   <meta http-equiv="content-type" content="text/html; charset=utf-8">  
  3.   <meta name="author" content="oscar999">  
  4.   <title>  
  5.   </title>  
  6.   <script>  
  7.     function clickDownload(aLink)  
  8.     {  
  9.          var str = "col1,col2,col3\nvalue1,value2,value3";  
  10.          str =  encodeURIComponent(str);  
  11.          aLink.href = "data:text/csv;charset=utf-8,"+str;  
  12.          aLink.click();  
  13.     }  
  14.   </script>   
  15.   </head>  
  16.   <body>  
  17.     <a id="test" onclick="clickDownload(this)" download="downlaod.csv" href="#">download</a>  
  18.   </body>  
  19. </html>  


帶中文問題的csv 導出

以上使用的都是utf-8 編碼,理論上導出中文應該不是問題。

但是導出csv 格式的話, 使用Excel 打開會發現中文是亂碼,但是用其他文本程序打開確是正常的。

原因就是少了一個 BOM頭 。  \ufeff。

加上一切都正常了,

[html] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1.    <head>  
  2.   <meta http-equiv="content-type" content="text/html; charset=gb2312">  
  3.   <meta name="author" content="oscar999">  
  4.   <title>  
  5.   </title>  
  6.   <script>  
  7.     function clickDownload(aLink)  
  8.     {  
  9.          var str = "欄位1,欄位2,欄位3\n值1,值2,值3";  
  10.          str =  encodeURIComponent(str);  
  11.          aLink.href = "data:text/csv;charset=utf-8,\ufeff"+str;  
  12.          aLink.click();  
  13.     }  
  14.   </script>   
  15.   </head>  
  16.   <body>  
  17.     <a id="test" onclick="clickDownload(this)" download="downlaod.csv" href="#">download</a>      
  18.   </body>  
  19. </html>  

這裏有兩個改變

1. 頁面的charset 需設置成gb2312

2. 加上 \ufeff BOM 頭


Chrome下載的文件名

以上使用 a 的download 屬性可以指定下載的文件名及後綴。 但是在Chrome 執行的時候會發現, Chrome 壓根不理會這個。

下載名是 "下載" 或是 "download".

上網搜索一下, 有說是Chrome 的 bug.

參見 stackoverflow 中的兩篇文章:

http://stackoverflow.com/questions/23962284/download-attribute-on-a-tag-doesnt-work-in-chrome
http://stackoverflow.com/questions/23816005/anchor-tag-download-attribute-not-working-bug-in-chrome-35-0-1916-114

以上兩篇文章可以不去關注, 需要關注的是這個問題是否可以解決, 以及解決的方法是什麼?

直接貼解決方案:

[html] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. var blob = new Blob([data], { type: 'text/csv' }); //new way  
  2. var csvUrl = URL.createObjectURL(blob);  
  3. document.getElementById("mylink").href = csvUrl;   

使用Blob 和URL 來封裝和轉換. 問題解決。

這裏如遇中文問題, 和上面的處理方式是一樣的:

1. 頁面的charset 需設置成gb2312 (設成UTF-8 也可以)

2. 加上 \ufeff BOM 頭

具體的代碼類似:

[html] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. data = "\ufeff"+data;  
  2. var blob = new Blob([data], { type: 'text/csv,charset=UTF-8'}); 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章