js實現txt/excel文件下載

出於安全考慮,JS沒法直接調用FileAPI寫文件到磁盤,可是卻能夠經過下載來變相實現保存功能。
JS要實現下載功能,通常都是這麼幾個過程:生成下載的URL,動態建立一個A標籤,並將其href指向生成的URL,而後觸發A標籤的單擊事件,這樣就會彈出下載對話框,從而實現了一個下載的功能。

HTML5的download屬性

這個屬性很重要,它能夠指定下載文件名,而且能夠告訴瀏覽器目標連接是一個下載連接,不是一個普通連接,咱們看下面代碼就能看出區別了:瀏覽器

<a href="data:text/txt;charset=utf-8,測試下載純文本" rel="external nofollow" rel="external nofollow" rel="external nofollow" download="測試.txt" >下載1</a>
<a href="data:text/txt;charset=utf-8,測試下載純文本" rel="external nofollow" rel="external nofollow" rel="external nofollow" >下載2</a>

能夠發現,下載1按鈕可以實現下載,點擊下載2連接時直接在瀏覽器打開文件內容了。安全

JS生成CSV文件並下載

csv是一種逗號分隔的表格文件格式,能夠很好的被Excel支持,因爲其文件格式簡單,因此常常用在簡單的表格上面。最重要的是它是一種純文本格式,能夠很輕鬆地用JS來生成而不借助第三方庫。編輯器

不考慮兼容性的保存CSV方法:

/**
 * 保存CSV文件
 * @params csv csv文件內容
 * @params saveName 保存的文件名
 */
function saveCSV(csv, saveName){
 var a = document.createElement('a');
 a.href = 'data:text/csv;charset=utf-8,\ufeff' + encodeURIComponent(csv);
 a.download = saveName;
 a.click();
}
雖然咱們用的是UTF-8編碼,下載後你會發現,用文本編輯器打開沒問題,可是用Excel打開亂碼:
緣由就是少了一個ufeffBOM頭,因此在data裏面添加一個 \ufeff解決了

文字換行問題

文字換csv的最大問題就是如何處理換行,很簡單,使用`\n`,`\r`後再用encodeURIComponent編碼一下就能夠了。

大部分瀏覽器可能都沒啥問題,可是一些比較老的Chrome可能下載的時候指定的download就是不生效,此時能夠用blob來解決:(測試此方法測試在微軟Edge瀏覽器和IE11下都沒法下載)函數

考慮兼容性的保存CSV方法:

/**
 * 保存CSV文件
 * @params csv csv文件內容
 * @params saveName 保存的文件名
 */
function saveCSV(csv, saveName)
{
 var blob = new Blob(['\ufeff' + csv], {type: 'text/csv,charset=UTF-8'});
 openDownloadDialog(blob, saveName);
}

此方法測試在微軟Edge瀏覽器能夠實現下載,可是在IE11下仍是沒法下載測試

封裝下載函數

const openDownloadDialog = (url, saveName) => {
  if (typeof url === 'object' && url instanceof Blob) {
    url = URL.createObjectURL(url); // 建立blob地址
  }
  const aLink = document.createElement('a');
  aLink.href = url;
  aLink.download = saveName;
  aLink.click();
};

txt文件

下載text文件只須要修改一下文件類型就好了編碼

function saveTXT(csv, saveName)
{
 var blob = new Blob(['\ufeff' + csv], {type: 'text/txt,charset=UTF-8'});
 openDownloadDialog(blob, saveName);
}

注意事項

保存文件的文件名後綴會影響打開方式,若是是.csv的文件名,默認打開爲excel,.txt文件結尾的默認打開方式爲text文件。因此這點須要注意url

參考代碼

我本身在項目中的封裝excel

downLoadTools.jscode

const openDownloadDialog = (url, saveName) => {
  if (typeof url === 'object' && url instanceof Blob) {
    url = URL.createObjectURL(url); // 建立blob地址
  }
  const aLink = document.createElement('a');
  aLink.href = url;
  aLink.download = saveName;
  aLink.click();
};
export default {
  /**
   * 保存CSV文件
   * @params csv csv文件內容
   * @params saveName 保存的文件名
   */
  saveCSV: (csv, saveName) => {
    const blob = new Blob(['\ufeff' + csv], {type: 'text/csv,charset=UTF-8'});
    openDownloadDialog(blob, `${saveName}.csv`);
  },
  saveTXT: (csv, saveName) => {
    // const href = 'data:text/txt;charset=utf-8,\ufeff' + encodeURIComponent(csv); // ie瀏覽器不支持
    const blob = new Blob(['\ufeff' + csv], {type: 'text/tet,charset=UTF-8'});
    openDownloadDialog(blob, `${saveName}.txt`);
  }
};

頁面引用事件

import downLoadTools from '@/utils/downLoadTools';  // 引入

downLoadTools.saveTXT(csv, '文件名');               // csv是一個字符串, 最終會下載一個 文件名.txt 的文件
相關文章
相關標籤/搜索