文件导出(下载)时添加loading

1,411 阅读1分钟

常见的文件下载方式

服务器的静态目录有可提供的下载资源,后台人员告知路径,直接a标签下载即可。例

export function derive(baseUrl, data) {
  let url = baseUrl + '?'
  for (const name in data) {
    url += name + '=' + data[name] + '&'
  }
  url += 'token=' + localStorage.getItem('MY-Admin-Token')
  let aDom = document.createElement('a')
  aDom.setAttribute('download', url)
  aDom.setAttribute('href', url)
  aDom.click()
  aDom = null // 改成在当前页下载
  // window.open(url, 'left=0,meunbar=no,toolbar=no,scrollbar=yes,status=yes')
}

这时,返回的文件名字则默认。 然而,当资源后端需要处理时,如上传入参数后端需要查询数据库时,则返回较慢,此时需要告知用户一个信息。

后台返回文件流的下载方式

该方式需要前端特殊处理请求。需要设置请求响应头responseType: 'blob'responseType: 'arraybuffer',该参数表示返回的是二进制数据流。返回二进制流之后则可以用a标签保存。例

// 请求下载 有return信息的
function downloadAjax(url, data) {
  data.token = localStorage.getItem('MY-Admin-Token')
  // for (const name in data) {
  //   url += name + '=' + data[name] + '&'
  // }
  return axios({
    method: 'get',
    url,
    params: data,
    time: 100000,
    // headers: { 'Content-Type': 'application/x-download' },
    responseType: 'arraybuffer',
    responseEncoding: 'utf8'
  })
}

// 处理下载
export function downloadBlob(url, data) {
  return downloadAjax(url, data).then((res) => {
    console.log(res)
    // console.dir(res.headers['content-disposition']) // 这里可以处理出文件名字
    // 获取heads中的filename文件名
    const temp = res.headers['content-disposition'].split(';')[1].split('filename=')[1]
    // console.log('fileName_', fileName)
    const name = decodeURIComponent(temp)
    if (res.status === 200 && res.statusText === 'OK') {
      saveFile(res.data, name)
      return Promise.resolve()
    } else {
      return Promise.reject()
    }
  })
}

function saveFile(data, fileName) {
  console.log('fileName', fileName)
  const file = new Blob([data], { type: 'application/vnd.ms-excel' })
  const url = window.URL || window.webkitURL
  const fileURL = url.createObjectURL(file)
  const a = document.createElement('a')
  a.href = fileURL
  a.download = fileName
  a.target = '_self'
  a.click()
  url.revokeObjectURL(fileURL)
}

由于文件名字有中文回来的时候是乱码,则需要decodeURIComponent()解码一下。点击下载按钮可以调用downloadBlob()方法。如果返回成功则自动下载,失败则不下载,修改按钮状态。 至此,如上。 谢谢拨冗浏览。