vue前端調后台接口下載excel文件


后台提供下載接口,可傳參數

使用get方法

  • window.location.href = '/api/xxx/xxx?params'
    
  • window.open('/api/xxx/xxx?params')
    
  • <a href="/api/xxx/xxx?params" download="excel.xls">export</a>
    
get方法參數拼接
  • // 拆分數據
    splitData: function (data) {
        let url = ''
        for (let k in data) {
            if (data.hasOwnProperty(k)) {
                let value = data[k] || ''
                url = url + '&' + k + '=' + encodeURIComponent(value)
            }
        }
        return url ? url.substring(1) : ''
    },
    
    // 拼接參數
    contractUrl: function (url, data) {
        return url + (url.indexOf('?') < 0 ? '?' : '&') + this.splitData(data)
    },
    

使用post方法

直接調用接口是返回表格流文件格式的,可以使用 Blob 對象指定要讀取的文件或數據,然后創建a標簽下載。

  • /**
     *  導出excel文件
     * @param url 下載地址
     * @param data 下載參數
     * @param name 下載文件名
     */
    export const $export = (url, data, name) => {
        let opt = {
            url: url,
            method: 'post',
            responseType: 'blob',
            data: data
        }
    
        axios.request(opt).then(res => {
            // Blob 對象表示一個不可變、原始數據的類文件對象(File 接口都是基於Blob)
            const BLOB = res.data
    
            // blob轉json,打印后端返回錯誤信息
            if (BLOB.type == 'application/json') {
                  const reader = new FileReader()
                  reader.readAsText(BLOB, 'utf-8')
                  reader.onload = function(e) {
                    const readerRes = reader.result
                    try {
                      const res = JSON.parse(readerRes)
                      error(res.message)
                    } catch (e) {
                      error('暫無數據!')
                    }
                  }
             } else {
              const fileName = decodeURI( // 獲取文件名
                res.headers['content-disposition'].split('=')[1]
              )
    
                // FileReader 對象允許Web應用程序異步讀取存儲在用戶計算機上的文件的內容
                const fileReader = new FileReader()
                // 開始讀取指定的Blob中的內容。讀取完成result屬性中將包含一個data: URL格式的Base64字符串以表示所讀取文件的內容
    
                if(BLOB){ // 此處判斷是否有數據,也可以在此判斷文件類型是否符合
                  fileReader.readAsDataURL(BLOB)
                }
    
              // 處理load事件,該事件在讀取操作完成時觸發
              fileReader.onload = (event) => {
                  let a = document.createElement('a')
                  // a.download = `${name}.xls` // 自定義文件名
                  a.download = fileName // 使用默認的文件名
                  a.href = event.target.result
                  document.body.appendChild(a)
                  a.click()
                  document.body.removeChild(a)
              }
            }
        })
    }
    

備注

異常問題1:Uncaught TypeError: Failed to execute 'readAsDataURL' on 'FileReader': parameter 1 is not of type 'Blob'
問題分析:后台返回了數據流,點擊下載后報異常無法下載,嘗試將后台返回的數據流強制轉換為blob類型發現能下載,但是轉化后文件損壞無法打開

 const BLOB = new Blob([res.data], "application/vnd.ms-excel;charset=utf-8")

此時可以判斷是數據的問題,項目中開啟mock后會對原生的ajax請求的數據產生影響,可能導致文件流異常,因此生產環境禁用mock就解決問題了。

 // vue 項目中在main.js中增加判斷,生產環境禁用mock
import Mock from '../mock'
if (process.env.NODE_ENV === 'development') {
  // Mock.init()
   Mock.saleMockOpen();
}


免責聲明!

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



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