vue post请求返回arraybuffer文件流下载文件

思路

        返回的结果处理:

        1.成功:返回arraybuffer文件流,前端获取文件流转码下载

        2.失败:返回json,前端获取jsob转中文提示框失败原因

判断条件

        后端返回的请求头header,根据content-type判断是成功还是失败,成功返回application/octet-stream;失败返回application/jso

代码实现

        需要注意axios请求,一般公共封装好的请求,都会在请求拦截那里将请求头拦截,我直接用的axios请求

/* 导出表格  post方式 */
onExport() {
    let params = {
      body: { ...this.QueryData },
        page: this.pagination.current,
        pageSize: 10,
        sortName: "sid",
        sortOrder: "desc"
    }
      axios({
        url: url,
        method: 'POST',
        data: params,
        headers: 'application/json',
        responseType: 'arraybuffer'
       }).then( res => {
        if( res.headers['content-type'].includes('application/octet-stream') ) {
          /* 截取头部获取文件名 utf8转中文 */
          let str = res.headers['content-disposition']
          let fileName = decodeURI(str.split('=')[1].split('.xls')[0])
          /* 下载文件 */
          this.downloadFile(res, fileName)
        } else if(res.headers['content-type'].includes('application/json')) {
          let enc = new TextDecoder('utf-8')
          this.$message.error(enc.decode(new Uint8Array(res.data)))
        }
      }).catch( err => {
        this.$message.error('系统异常')
      })
}

文件流的处理方式1:a标签模拟点击事件下载 

    /* 导出文件 bold文件流方式导出 */
    downloadFile(res, fileName) {
      var blob = new Blob([res.data])
      const reader = new FileReader()
      reader.readAsDataURL(blob)
      reader.onload = (e) => {
        const a = document.createElement('a')
        a.download = `${fileName}.xls`
        a.href = e.target.result
        document.body.appendChild(a)
        a.click()
        document.body.removeChild(a)
        this.$message.success('导出成功')
      }
    },

文件流的处理方式2:使用插件下载 file-saver  [npm i 就能用]

import { saveAs } from 'file-saver'
 /* 导出文件 bold文件流方式导出 */
downloadFile(res, fileName) {
   fileName = `${fileName}.xls`
   var blob = new Blob([res.data])
   saveAs(blob, fileName)
},

注意:文件命这里是后端放在请求头的content-disposition,为避免乱码,后端进行了转码,前端需要截取filename=后边的编码进行转码,再拼接。

代码如下 

/* 截取头部获取文件名 utf8转中文 */
let str = res.headers['content-disposition']
let fileName = decodeURI(str.split('=')[1].split('.xls')[0])

 导出失败的情况,需要将接口返回的提示转码为中文

/* 文件导出失败 utf8转中文 */
let enc = new TextDecoder('utf-8')
this.$message.error(enc.decode(new Uint8Array(res.data)))

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值