vue处理blob二进制流进行文件下载

5,816 阅读2分钟

blob文件流下载普通用法

首先,使用axios请求接口时,添加responeType:'blob',将后端返回的二进制流处理为blob对象,如: axios.post('xxx(接口路径)', data(参数), { responseType: 'blob' }),然后便可以带入以下公共流程(这里将这些步骤封装为一个函数):

/**
 * @description: 文件下载
 * @param {Blob} blob 参数1:blob对象
 * @param {string} name 参数2:文件名称,包含文件后缀
 * @return {*}
 */
const download = (blob, name) => {
  const link = document.createElement('a'); //创建一个a标签
  const url = URL.createObjectURL(blob); //将blob文件对象通过URL.createObjectURL()方法转为为url
  link.href = url; //为a标签设置href属性,并赋值为url
  link.download = name; //定义下载的文件名,文件名要包含后缀哟!如'导出EXCEL.xlsx'
  document.body.appendChild(link); //把a标签放在body上
  link.click(); //出发a标签点击下载
  document.body.removeChild(link); //在body中移除这个a标签
  URL.revokeObjectURL(url); //释放blob对象
}

有了这个函数后,将后端返回的blob对象带入即可,用法如:

const exportData = async() => {
  const { data } = await axios.post('接口地址',data(参数),{ responseType: 'blob' })
  //调用下载方法
  download(data,'导出.xlsx') //文件名的格式,一般是确定的,如果是excel的话就 .xls 或者 .xlsx 其中一个
}

文件流下载的进阶用法:(使用 FileReader 文件对象在进行下载前做判断!)

因为上边那种方式,在请求接口返回时就已经是一个文件流了。如果这时候有需求是需要根据接口返回的数据来判断能不能下载的话,上边这种就不太行了。因此我们有一些方法处理,也就是使用 FileReader来先对返回的数据进行判断。根据上边的案例进行稍微的修改:

const exportData = async() => {
  const { data } = await axios.post('接口地址',data(参数),{ responseType: 'blob' })
  //在下载前先读取
  const f = new FileReader()  //创建一个文件对象
  f.readAsText(data)  // 以文本的方式读取 文件
  //执行 onload方法
  f.onload = () => {
    // 这里使用 try catch 方式捕获异常
    try {
      const result = JSON.parse(f.result) // f.result为读取结果,如果 JSON.parse()报错,说明后端返回的数据是 正常的 文件流  在catch中进行下载
      ElMessage.error(lang(result.msg || '导出失败!'))  // 没有报错,说明返回的不是文件流,需要提醒用户,弹出提示 此时的 result 为后端返回的数据,msg为后端返回的提示内容
    } catch (error) {
      download(data, '导出.xlsx')
    }
  }
}

这样就大功告成啦!