当前位置:   article > 正文

前端实现流文件下载、导出功能解决方案_前端文件流下载

前端文件流下载

一、自定义下载文件名

1、封装下载方法(可以通过挂载在vue实例上成为全局函数)

import requset from 'axios'
// 经过请求拦截器、响应拦截器处理
onloadFileName(url,method,params,fileName){
	request({
		url:url,
		method:method,
		// get 方法传参为例
		data:{
		...params
		},
		// 添加响应数据类型
		responseType: 'blob',
		// 添加文件下载特定请求头
	    headers: {
	       'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
	     },
	}).then(res =>{
		// res 为响应拦截器返回的内容,大家可以对比自己的响应拦截器修改下面方法的判断
		if (!data) {
	     this.$message.warning("文件下载失败");
	      return;
	    }
	    // web Api种操作流文件的方法
	     if (typeof window.navigator.msSaveBlob !== "undefined") {
	     // msSaveBlob:只提供一个保存按钮
	     // window.navigator.msSaveBlob(new Blob([data]),`${fileName}.txt`);
	     
	     // msSaveOrOpenBlob:提供保存和打开按钮	
	     //window.navigator.msSaveOrOpenBlob(newBlob([data]),`${fileName}.txt`);
		     window.navigator.msSaveBlob(
		        new Blob([data]),
		        filename + ".xls"
		      );
	    } else {
	    // 自定义实现流文件下载
		      let url = window.URL.createObjectURL(new Blob([data]));
		      let link = document.createElement("a");
		      link.style.display = "none";
		      link.href = url;
		      link.setAttribute("download", fileName + ".xls");
		      document.body.appendChild(link);
		      link.click();
		      document.body.removeChild(link); //下载完成移除元素
		      window.URL.revokeObjectURL(url); //释放掉blob对象
	    }
	})
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47

t经过响应拦截器后返回的有效数据,所以直接使用new Blob([data])
2、调用下载方法

this.onloadFileName('xxx/xxx/xx','get',{id:'xxxxxxx'},'文件一')
  • 1

二、文件名称从后端响应头数据中获取

相应拦截器处理之前的数据,文件名在content-disposition字段中存放
·1、处理响应拦截器返回的数据,将文件名暴露暴露出去

// 设置请求接受拦截器 响应拦截器中兼容处理流数据
serves.interceptors.response.use(response => {
	  // 设置接受数据之后,做什么处理
    const res = response.data
     if (!res.code && res.code === 200) {
     // 数据是流
        if(response.headers['content-disposition']){
            return {
                blobData:res,
                contentDisposition:response.headers['content-disposition']
            }
        }
        // 正常情况下
        else{
            return res
        }
       
    }
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

相应拦截器过滤后的数据描述
2、封装下载方法

onloadFileName(url,method,params){
	request({
		url:url,
		method:method,
		// get 方法传参为例
		data:{
		...params
		},
		// 添加响应数据类型
		responseType: 'blob',
		// 添加文件下载特定请求头
	    headers: {
	       'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
	     },
	}).then(res =>{
		 if (!res.blobData) {
            this.$message.warning("文件下载失败");
              return;
          }
          // web Api种操作流文件的方法
	     if (typeof window.navigator.msSaveBlob !== "undefined") {
		     // msSaveBlob:只提供一个保存按钮
		     // window.navigator.msSaveBlob(new Blob([data]),`${fileName}.txt`);
		     
		     // msSaveOrOpenBlob:提供保存和打开按钮	
		     //window.navigator.msSaveOrOpenBlob(newBlob([data]),`${fileName}.txt`);
             window.navigator.msSaveBlob(
                  new Blob([res.blobData]),
                  res.contentDisposition+ ".xls"
              );
           	} else {
               let url = window.URL.createObjectURL(new Blob([res.blobData],
                   { 
                    type:
                        ".xlsx"
                   } 
                ));
                let link = document.createElement("a");
                link.style.display = "none";
                link.href = url;
                // decodeURIComponent()解码文件名称
                // data.contentDisposition.split('=')[1] 分割文件名称
                const fileName = decodeURIComponent(data.contentDisposition.split('=')[1])
                link.setAttribute("download",fileName);
                document.body.appendChild(link);
                link.click();
                document.body.removeChild(link); //下载完成移除元素
                window.URL.revokeObjectURL(url); //释放掉blob对象
          }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50

3、调用下载方法

this.onloadFileName('xxx/xxx/xx','get',{id:'xxxxxxx'})
  • 1

问题一:后端返回的数据无法解析
在请求函数中添加响应类型以及响应头
在这里插入图片描述
问题二、后端返回的文件名经过相应拦截器后无法暴露出来导致无法获取文件名报错。
后端返回二进制流数据时设置请求头,添加可暴露出的字段

 response.setHeader("Access-Control-Expose-Headers", "Content-Disposition")
 response.setHeader("Content-Disposition", ...)
  • 1
  • 2
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/325958
推荐阅读
  

闽ICP备14008679号