如何从后端接口导出execl文件

313 阅读1分钟

method get

xxxapi.com/api/getFileExecl?orderId=123

这种情况一般直接交给浏览器处理

window.open('xxxapi.com/api/getFileExecl?orderId=123')

location.href = 'xxxapi.com/api/getFileExecl?orderId=123'

method post

xxxapi.com/api/getFileExecl

request payload { orderId: 123, type: 1 }

case1

接口返回一个 file url,直接以 get的形式去请求这个url就行了

case2

接口返回 Blob 数据,这时候需要前端去下载

post 请求,假设使用 axios 作为请求类库

将 blob 转移到 a 标签的 href 属性里,触发点击,变相以 get 方式交由浏览器下载

  axios.post(url, data, {
        responseType: 'blob',
        params,
      })
      .then((response) => {
        const { data } = response
        // 这是判断接口是否正常返回数据(与后端约定的字段)
        const { errorCode } = data
        if (errorCode) return reject(data)
        else {
            // application/vnd.openxmlformats-officedocument.spreadsheetml.sheet这里表示xlsx类型
            const blob = new Blob([data], {
              type:
                'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8',
            })
            // 根据响应头里的文件名设置下载的文件名
            const { headers = {} } = response
            const contentDisposition = headers['content-disposition'] || ''
            const regexp = /filename="?(.*?)"?((?=$)|(?=;))/
            const matchResult = contentDisposition.match(regexp)
            const downLoadName =
              matchResult && matchResult[1]
                ? decodeURIComponent(matchResult[1])
                : 'excel.xls'
            if ('download' in document.createElement('a')) {
              const downloadElement = document.createElement('a')
              let href = ''
              if (window.URL) href = window.URL.createObjectURL(blob)
              else href = window.webkitURL.createObjectURL(blob)
              downloadElement.href = href
              downloadElement.download = downLoadName
              document.body.appendChild(downloadElement)
              downloadElement.click()
              if (window.URL) window.URL.revokeObjectURL(href)
              else window.webkitURL.revokeObjectURL(href)
              document.body.removeChild(downloadElement)
            } else {
              navigator.msSaveBlob(blob, downLoadName)
            }
            resolve(data)
          
        }
      })

其他文件

其他文件也一样,只需要改变为对应的 MIME TYPE 就行了,只要是 a 标签支持的都可以

safari

// Safari doesn't allow downloading of blob URLs
const isChromeIOS = /CriOS\/[\d]+/.test(navigator.userAgent)
const reader = new FileReader()
reader.onloadend = function () {
  var url = reader.result
  url = isChromeIOS ? url : url.replace(/^data:[^;]*;/, 'data:attachment/file;')
  window.location = url
}
reader.readAsDataURL(blob)