1. 程式人生 > 其它 >axios下載後臺傳過來的流檔案並設定下載檔名(如excel)

axios下載後臺傳過來的流檔案並設定下載檔名(如excel)

主要介紹兩種方法,使用Blob物件和 使用js-file-download

這兩種方法下載的檔案都不會亂碼,但是不管使用哪種方法,傳送請求時都要設定responseType

方法一:使用Blob物件

Blob物件表示一個不可變、原始資料的類檔案物件。Blob 表示的不一定是JavaScript原生格式的資料。File介面基於Blob,繼承了blob的功能並將其擴充套件使其支援使用者系統上的檔案。

一、Blob()建構函式

摘自:Blob()建構函式

語法

var aBlob = new Blob( array, options );

引數

  • array是一個由ArrayBuffer,ArrayBufferView
    ,Blob,DOMString等物件構成的Array,或者其他類似物件的混合體,它將會被放進Blob。DOMStrings會被編碼為UTF-8。
  • options是可選的,它可能會指定如下兩個屬性:

    • type,預設值為"",它代表了將會被放入到blob中的陣列內容的MIME型別。也就是設定檔案型別。
    • endings,預設值為"transparent",用於指定包含行結束符\n的字串如何被寫入。 它是以下兩個值中的一個:"native",代表行結束符會被更改為適合宿主作業系統檔案系統的換行符,或者"transparent",代表會保持blob中儲存的結束符不變。

二、URL物件

通過建立URL物件指定檔案的下載連結。

// 建立新的URL表示指定的File物件或者Blob物件
const href = window.URL.createObjectURL(blob)
window.URL.revokeObjectURL(href) // 釋放掉blob物件
在每次呼叫createObjectURL()方法時,都會建立一個新的 URL 物件,即使你已經用相同的物件作為引數建立過。當不再需要這些 URL 物件時,每個物件必須通過呼叫 URL.revokeObjectURL()方法來釋放。瀏覽器會在文件退出的時候自動釋放它們,但是為了獲得最佳效能和記憶體使用狀況,你應該在安全的時機主動釋放掉它們。

三、利用a標籤自定義檔名

const downloadElement = document.createElement('a')
const href = window.URL.createObjectURL(blob)
const contentDisposition = response.headers['content-disposition'] // 從response的headers中獲取filename, 後端response.setHeader("Content-disposition", "attachment; filename=xxxx.docx") 設定的檔名;
const patt = new RegExp('filename=([^;]+\\.[^\\.;]+);*')
const result = patt.exec(contentDisposition)
const filename = decodeURI(escape(result[1])) // 處理檔名,解決中文亂碼問題
downloadElement.style.display = 'none'
downloadElement.href = href
downloadElement.download = filename // 下載後文件名
document.body.appendChild(downloadElement)
downloadElement.click() // 點選下載
document.body.removeChild(downloadElement) // 下載完成移除元素
download 屬性設定檔名時,可以直接設定副檔名。如果沒有設定,則瀏覽器將自動檢測正確的副檔名並新增到檔案 。

四:主要完整程式碼

  • 普通下載

  axios.post(postUrl, params, { responseType: 'arraybuffer' }).then(response => {
    const fileType = [
      'application/vnd.ms-excel;charset=utf-8', // xls
      'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8' // xlsx
    ]
    const blob = new Blob([response.data], { type: fileType })
    const downloadElement = document.createElement('a')
    const href = window.URL.createObjectURL(blob)
    const contentDisposition = response.headers['content-disposition'] // 從response的headers中獲取filename, 後端response.setHeader("Content-disposition", "attachment; filename=xxxx.docx") 設定的檔名;
    const patt = new RegExp('filename=([^;]+\\.[^\\.;]+);*')
    const result = patt.exec(contentDisposition)
    const filename = decodeURI(escape(result[1])) // 處理檔名,解決中文亂碼問題
    downloadElement.style.display = 'none'
    downloadElement.href = href
    downloadElement.download = filename // 下載後文件名
    document.body.appendChild(downloadElement)
    downloadElement.click() // 點選下載
    document.body.removeChild(downloadElement) // 下載完成移除元素
    window.URL.revokeObjectURL(href) // 釋放掉blob物件
  })
注:下載指定副檔名的檔案只需要對照MIME 參考手冊設定type即可。

方法二:使用js-file-download

  • 安裝

    npm install js-file-download --save
  • 使用

    import fileDownload from 'js-file-download'
    
    axios.post(postUrl, params, {responseType: 'arraybuffer'}).then(response => {
        const contentDisposition = response.headers['content-disposition'] // 從response的headers中獲取filename, 後端response.setHeader("Content-disposition", "attachment; filename=xxxx.docx") 設定的檔名;
        const patt = new RegExp('filename=([^;]+\\.[^\\.;]+);*')
        const result = patt.exec(contentDisposition)
        const filename = decodeURI(escape(result[1])) // 處理檔名,解決中文亂碼問題
        fileDownload(response.data, filename)
    })