后端返回二进制流,前端处理下载表格

最近在搞一个导出的功能
方法1:

 window.open(url+'?sheetId=' + this.state.sheetId2 + '&exportType=' + this.state.exportType, '_self');

该方法只能是get请求,如果是post请求,就需要改造

  /**
   * window.open()方法以post请求方式打开新窗口
   * @param url 请求地址
   * @param postParams 请求参数
   */
  windowOpenPost(url, postParams) {
    var newWin = window.open();
    var host = window.location.host;
    var protos = document.location.protocol;
    url = protos + '//' + host + url;
    var formStr = '<form style="visibility:hidden;"   method="post"  action="' + url + '">';
    for (var key in postParams) {
      formStr += "<input type='text' name='" + key + "' value='" + postParams[key] + "' style='display: none'>";
    }
    formStr += "</form>";
    newWin.document.body.innerHTML = formStr;
    newWin.document.forms[0].submit();
  }

**因为post是form表单格式提交,所以后端也得改一下参数的接收类型**,这样写,是可以实现需求的,
但是业务希望可以在本页面打开,这个代码本页面打开就有问题,所以就有了方法二

方法二

  pageDownload(url, params, name) {
    let host = window.location.host;
    let protos = document.location.protocol;
    axios({
      method: 'post',
      url: protos + '//' + host + url,
      data: {
        ...params
      },
      headers: {},
      responseType: 'arraybuffer',
    }).then((res) => {
      let blob = new Blob([res.data], { type: 'application/vnd.ms-excel;charset=utf-8' })
      var href = window.URL.createObjectURL(blob); //创建下载的链接
      var downloadElement = document.createElement('a');
      downloadElement.href = href;
      downloadElement.download = `${name}.xlsx`; //下载后文件
      document.body.appendChild(downloadElement);
      downloadElement.click(); //点击下载
      document.body.removeChild(downloadElement); //下载完成移除元素
      window.URL.revokeObjectURL(href); //释放掉blob对象
    });
  }

因为这个地方,后台的返回结果取错了,然后表格打开里面就是一个object,找了好久好久
错误截图
好在最终解决了问题

最近有一个新的想法,原来我之前的理解一直有问题(上述代码没有问题),每次遇到导出的功能,后端就跟我说直接调用get请求就行了,然后我就试了直接调用get请求,然后页面纹丝不动,我上网查了其他的资料,跟我上面写的如出一辙,我的疑问就是文件名,我该从哪获取,我打印了我的返回结果是没有这个的,原来的响应的时候,统一处理掉了,所以返回的结果是没有响应的头部信息,恍然大悟

  let dis= res.headers['content-disposition']
  let fileName=dis.split('attachment;filename=')[1]

用了上面的代码,我感觉我已经成功了 ,然后一执行代码,发现文件名乱码,真的是处处都是坑啊,
敲黑板了
需要说明的是,content-disposition 取值是res.headers[‘content-disposition’],res.headers[‘content-disposition’] 的值是如下类型字符串 attachment;filename=xxx.xlsx,需要自己切分。另外,如果文件名是中文,则需要后端配合转码,后端在发送文件时,组要将文件名进行java.net.URLEncoder.encode(fileName, “UTF8”) 转码,否则前端接收到的 res.headers[‘content-disposition’] 的中文信息是乱码的。后端转码后,前端通过decodeURIComponent 解码即可

终于登顶了,成功了

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值