vue前端 下载导出后台二进制文件流get、post

文章介绍了如何在前端通过GET和POST方式下载文件,特别是处理文件流下载时,如何将token等参数放入请求头,并使用Blob对象生成文件进行下载。对于POST请求,文章还展示了如何设置Content-Type和处理响应数据为blob类型。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

参考一:vue前端下载 后台二进制文件流 post、get
参考一:new Blob() 文件流下载文件不同文件类型的 type 值整理

get方式

文件下载没做任何要求可以通过a标签或者window.open直接下载

//写法一

  window.open(item.reportPdfUrl+'?preview=true', "_blank");

//写法二


export const getStaticsExport = '/myboot/pe/stat/Etuoke/exceptionExport';

//参数拼接处理
let par = "";
for(let p in this.listParam){
     if(this.listParam[p] != null && this.listParam[p] != ""){
         par+= '&'+ p + '='+ encodeURIComponent(this.listParam[p])
     }
 }
 window.open(getStaticsExport + "?v=1" + par);

写法三

//=====================================
const toParams = (params) => {
    let par = "";
    for (let p in params) {
        if (params[p] != null && params[p] != "") {
            par += '&' + p + '=' + encodeURIComponent(params[p])
        }
    }
    if (par.length > 0) {
        par = par.substring(1, par.length)
    }
    return par
}
export default {
    //autoHeight,
    toParams,
    //formatTime
}

//=====================================
import {
    getRequset
} from '@/utils/request'
export const getConsentFormHeartSift = process.env.VUE_APP_BASE_API + '/pe/consentForm/heartSift'

//===========
.env
VUE_APP_BASE_API = '/myboot'
vue.config.js
proxy: {
    '/myboot': {
         // target: 'http://10.1.0.52:8122',
         target: 'http://localhost:8122',
         // target: 'http://test.sdboletong.com:8122',
         changeOrigin: true,
         ws: true,
         secure: false
     },
     '/api': {
         target: 'http://10.2.0.79:8888',
         changeOrigin: true,
         ws: true,
         secure: false,
         pathRewrite: {
             '^/api': '/'
         }
     }
 }


//=====================================
import toolUtil from '@/utils/toolUtil'
import {getConsentFormHeartSift} from '@/api/modules/consent-form'
let sForm = { ...this.searchForm }
 window.open(getConsentFormHeartSift + '?' + toolUtil.toParams(sForm))

文件以文件流的形式下载,并要求向后端传递token等参数,放在请求头header中,可以通过blob方式下载

async handelDown() {
    await this.$axios.get(this.$api._api + `/system/downloadDict`, {
        responseType: 'blob',
        headers: {
            token: '',
        }
    }).then(res => {
        this.download(res, '模板文档.xlsx')
    }).catch(err => {
        this.download(err, '模板文档.xlsx')
    })
},

download(result, name) {
  const blob = new Blob([result.data], {
          type: 'application/vnd.ms-excel',
      });
  const url = window.URL.createObjectURL(blob);
  const link = document.createElement('a');
  link.style.display = 'none';
  link.href = url ;
  link.download = `${name}.xlsx`;
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);
}

post方式

方法一:后端返回文件名

下图为后台返回文件格式以及文件名位置
在这里插入图片描述


//封装请求
export const postRequestBlob = (url, params) => {
  // debugger
  return service({
    method: 'post',
    url: url,
    data: params,
    transformRequest: [function (data) {
      let ret = '';
      for (let it in data) {
        ret += encodeURIComponent(it) + '=' + encodeURIComponent(data[it]) + '&';
      }
      ret = ret.substring(0, ret.length - 1);
      return ret;
    }],
    headers: {
      "Content-Type": "application/x-www-form-urlencoded",
      "accessToken": sessionStorage.getItem('userToken')
    },
    responseType: "blob",
  });
};

//后台访问路径
export function getCommonDiseasesExport(params){
    return postRequestBlob('/pe/stat/Etuoke/exceptionCommonDiseasesExport',params)
}

//请求后台并处理后台返回的文件名
 const res = getCommonDiseasesExport(this.listParam);
 let date = this.common.getTimer('date')
  res.then((result) => {
      const blob = new Blob([result.data], {
          type: 'application/vnd.ms-excel',
      });
       // 从response的headers中获取filename, 后端response.setHeader("Content-disposition", "attachment; filename=xxxx.docx") 设置的文件名;
       //从请求中查看响应头里查看content-disposition是否存在
      let patt = new RegExp('filename=([^;]+\\.[^\\.;]+);*')
      let contentDisposition = decodeURI(res.headers['content-disposition'])
      let result = patt.exec(contentDisposition)
      let fileName = result[1]
      const url = window.URL.createObjectURL(blob);
      this.common.download(url, fileName);
  })

// 公共下载方法
export function download(blobUrl, name) {
  const link = document.createElement('a');
  link.style.display = 'none';
  link.href = blobUrl;
  link.download = `${name}.xlsx`;
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);
}

页面自用(自定义文件名)

 const ress = getStaticsExport(this.listParam);
 let resData = '';
  let date = this.common.getTimer('date')
  ress.then((result) => {
    resData = result
    const blob = new Blob([resData.data], {
      type: 'application/vnd.ms-excel',
    });
    const url = window.URL.createObjectURL(blob);
    this.common.download(url, '贫血状况统计表' + date);
  })
  
  //封装公共下载方法
export function download(blobUrl, name, type) {
  const link = document.createElement('a');
  link.style.display = 'none';
  link.href = blobUrl;
  if (type) {
    if (type == 'fileName') {
      link.download = `${name}`;
    } else {
      link.download = `${name}.${type}`;
    }
  } else {
    link.download = `${name}.xlsx`;
  }
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);
}

写法三

download (data) {
   if (!data) {
       return
   }
   window.URL = window.URL || window.webkitURL // 兼容性
   // 创建一个 URL 这个 URL 的生命周期和创建它的窗口中的 document 绑定。这个新的URL 对象表示指定的 File 对象或 Blob 对象。
   let url = window.URL.createObjectURL(new Blob([data]))
   let link = document.createElement('a') // 创建一个a元素
   link.style.display = 'none' // 让a元素在页面中隐藏
   link.href = url // 绑定 a 元素的 href 为当前的url
   let exportName = this.type == 1 ? this.dayTime : this.belongMonth
   link.setAttribute('download', `${exportName}.xlsx`) // 设置 a 元素 download属性,属性名为后面的值
   document.body.appendChild(link) // 添加到页面中
   link.click() // 点击a元素 下载excel文件
   window.URL.revokeObjectURL(url) //卸载url,释放内存
},

如果需要判断下载文件是否有数据需要显示后台返回错误值

if(res.type !== 'application/json'){
    let link = document.createElement('a');
    link.style.display = 'none';
    let blob = new Blob([res], {
      type: 'application/pdf;charset=utf-8',
      //Content-Disposition: inline;filename=<pdf的文件名>
      //Content-Type: application/pdf;charset=UTF-8
      //attachment表示下载文件,inline表示内嵌显示;
    });
    link.href = URL.createObjectURL(blob);
    // 获取文件名
    link.download = '会员入会申请表.pdf';
    document.body.appendChild(link);
    link.click(); //触发
    link.remove(); // 一次性的,用完就删除a标签
  }else{
  //重点处理后台返回json 而不是文件流的情况
  //因为发起请求时responseType: "blob",所以获取返回值为blob需要处理才能展示后台返回msg信息
    let reader = new FileReader()
    reader.onload=(event)=>{
      let jsonData = JSON.parse(event.target.result)
      if(jsonData && jsonData.msg) {
        this.$message.warning(jsonData.msg)
      }
    }
    reader.readAsText(res)
  }

访问获取到的数据
在这里插入图片描述
前端打印后端返回值
前端打印后端返回值
可见数据在res.data中,应该取值res.data。

const blob = new Blob([res.data], {
   type: 'application/vnd.ms-excel',
 });

当返回值res为一个Promise对象时

 let res= that.selectValidEvent();
    console.log( res);

在这里插入图片描述

res.then((result) => {
 console.log("result", result);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值