工作中遇到这样的需求,前端请求下载接口,返回一个Excel的二进制文件流,将文件流解析并下载。
在vue中, 接收并下载文件流可以通过将其转成blob对象或者arraybuffer,添加到a标签或者iframe标签中来模拟下载(或者pdf预览)
文末有通用下载方法可供参考

1.首先需要设置responseType对象格式为 blob

在项目request.js文件中 添加请求头的相关配置 如header responseType 等

config.headers['Authorization'] = getToken()
      if(config.responseType){
        config.responseType = 'blob'
      }

在api.js文件中,添加参数 responseType:‘blob’

export function downloadcode(queryParam) {
  return request({
    url: '/authCode/download',
    method: 'get',
    params: queryParam,
    responseType:'blob'
  })
}

在页面中添加下载方法

//下载方法
    handleDown(row) {
      const data = {id:row.id}
      downloadExcel(data).then(res => {
        console.log("要下载的文件流",res)
        const link=document.createElement('a');//创建a标签
        try{
	          // let blob = new Blob([res.data],{type: 'application/vnd.ms-excel'});    //如果后台返回的不是blob对象类型,先定义成blob对象格式,该type导出为xls格式,
	          let blob =  res.data    //如果后台返回的直接是blob对象类型,直接获取数据
	          let _fileName = res.headers['content-disposition'].split(';')[1].split('=')[1]; //拆解获取文件名,如果后端有给返回文件名的话
	          link.style.display='none';//隐藏
	          
	         方式一:
	          // 兼容不同浏览器的URL对象
	          const url = window.URL || window.webkitURL || window.moxURL;
	          link.href=url.createObjectURL(blob);
	          link.download = _fileName;   //下载的文件名称
	          link.click();//触发click
	          window.URL.revokeObjectURL(url);  //  URL.revokeObjectURL()方法会释放一个通过URL.createObjectURL()创建的对象URL. 当你要已经用过了这个对象URL,然后要让浏览器知道这个URL已经不再需要指向对应的文件的时候,就需要调用这个方法.

			方法二:
			   // 兼容不同浏览器的URL对象
	          const url = window.URL || window.webkitURL || window.moxURL;
	          link.href=url.createObjectURL(blob);
	          link.setAttribute('download'_fileName.substring(_fileName.lastIndexOf('_')+1)));
              document.body.appendChild(link);
              link.click();
              document.body.removeChild(link);
              url.revokeObjectURL(link.href);//移除url对象
        }catch (e) {
          console.log('下载的文件出错',e)
        }
      })
    },

如果不想改变js文件,可以直接发送get请求进行下载

axios.get(`/dev-api/authCode/download?id=`+row.id,
    { //请求头需要的一些配置
      headers:{
          "Authorization":getToken()
        },
      responseType: 'blob',//设置返回类型
    }
 ).then((res)=>{
    console.log('下载的文件',res)
    const link=document.createElement('a');
    try{
          let blob =  res.data
          let _fileName = res.headers['content-disposition'].split(';')[1].split('=')[1];//文件名,中文无法解析的时候会显示 _(下划线),生产环境获取不到
          link.style.display='none';
          // 兼容不同浏览器的URL对象
          const url = window.URL || window.webkitURL || window.moxURL;
          link.href=url.createObjectURL(blob);
          link.download = _fileName;
          link.click();
          window.URL.revokeObjectURL(url);
    }catch (e) {
      console.log('下载的文件出错',e)
    }
  }).catch(()=>{
    console.log('下载的文件出错')
  })  

也可以调用通用下载方法,需导入相关js文件

// 通用下载方法
export function download(url, params, filename) {
  downloadLoadingInstance = Loading.service({ text: "正在下载数据,请稍候", spinner: "el-icon-loading", background: "rgba(0, 0, 0, 0.7)", })
  return service.post(url, params, {
    transformRequest: [(params) => { return tansParams(params) }],
    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
    responseType: 'blob'
  }).then(async (data) => {
    console.log(140,typeof data);
    const isLogin = await blobValidate(data);
    if (isLogin) {
      const blob = new Blob([data])
      saveAs(blob, filename)
    } else {
      const resText = await data.text();
      const rspObj = JSON.parse(resText);
      const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default']
      Message.error(errMsg);
    }
    downloadLoadingInstance.close();
  }).catch((r) => {
    console.error(r)
    Message.error('下载文件出现错误,请联系管理员!')
    downloadLoadingInstance.close();
  })
}

核心代码

const blob = new Blob([res], { type: 'application/vnd.ms-excel'});// 构造一个blob对象来处理数据,并设置文件类型
if (window.navigator.msSaveOrOpenBlob) { //兼容IE10
    navigator.msSaveBlob(blob, 'test')
} else {
    const href = URL.createObjectURL(blob) //创建新的URL表示指定的blob对象
    const a = document.createElement('a') //创建a标签
    a.style.display = 'none'//隐藏
    a.href = href // 指定下载链接
    a.download = '下载的文件名称' //指定下载文件名
    a.click() //触发下载
    URL.revokeObjectURL(a.href) //释放URL对象
}
Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐