后端接口返回文件流格式、前端如何实现文件下载导出呢?

在项目开发过程中,难免会需要实现文件下载功能,记录下自己实际开发过程过程中遇到两种实现的方式。一种:后端直接返回加密url ,前端解密后直接使用 a标签下载就可以,这种方法相等比较简单,另一种:后端接口直接返回文件流,这种方式前端就需要单独封装对应的请求方法进行处理,因为这种方式使用不多,为了方便后续使用加深印象,将解决方法记录下来方便后续查阅。

完整代码

post请求
function postDownload(url, data, fileName) {
  return axios({
    // 用axios发送post请求
    url: preUrl + url, // 请求地址
    data, // 参数
    method: 'post',
    responseType: 'blob',
    headers: {
      'Content-Type': 'application/json',
    },
  })
    .then((res) => {
      // 处理返回的文件流
      // 获取http头部的文件名信息,若无需重命名文件,将下面这行删去
      if (!fileName) fileName = window.decodeURI(res.headers['content-disposition'].split('=')[1])

      /* 兼容ie内核,360浏览器的兼容模式 */
      const blob = new Blob([res.data], { type: 'application/vnd.ms-excel;charset=utf-8' })
      /* 兼容ie内核,360浏览器的兼容模式 */
      if (window.navigator && window.navigator.msSaveOrOpenBlob) {
        window.navigator.msSaveOrOpenBlob(blob, fileName)
      } else {
        /* 火狐谷歌的文件下载方式 */
        let url1 = window.URL.createObjectURL(blob)
        let link = document.createElement('a')
        link.style.display = 'none'
        link.href = url1

        link.setAttribute('download', fileName)
        document.body.appendChild(link)
        link.click()
      }
      Message({
        message: '导出成功',
        type: 'success',
      })
      return Promise.resolve(res.data)
    })
    .catch((err) => {
      Message({
        message: err,
        type: 'error',
      })
      return Promise.resolve(err)
    })
}

get 请求
function getDownload(url, data, fileName) {
  return axios({
    // 用axios发送get请求
    url:url, // 请求地址
    params: data, // 参数
    method: 'get',
    responseType: 'blob',
    headers: {
      'Content-Type': 'application/json',
    },
  })
    .then((res) => {
      // 处理返回的文件流
      // 获取http头部的文件名信息,若无需重命名文件,将下面这行删去
      if (!fileName) fileName = window.decodeURI(res.headers['content-disposition'].split('=')[1])

      /* 兼容ie内核,360浏览器的兼容模式 */
      const blob = new Blob([res.data], { type: 'application/vnd.ms-excel;charset=utf-8' })
      /* 兼容ie内核,360浏览器的兼容模式 */
      if (window.navigator && window.navigator.msSaveOrOpenBlob) {
        window.navigator.msSaveOrOpenBlob(blob, fileName)
      } else {
        /* 火狐谷歌的文件下载方式 */
        let url1 = window.URL.createObjectURL(blob)
        let link = document.createElement('a')
        link.style.display = 'none'
        link.href = url1
        link.setAttribute('download', fileName)
        document.body.appendChild(link)
        link.click()
      }
      Message({
        message: '导出成功',
        type: 'success',
      })
      return Promise.resolve(res.data)
    })
    .catch((err) => {
      Message({
        message: err,
        type: 'error',
      })
      return Promise.resolve(err)
    })
}
responseType: ‘blob’ 说明

后端接收返回的二进制文件流,axios 本身不回去处理,但是接口返回的内容浏览器会接收对应的内容,但是接收到的内容是这样的:
二进制文件流
这样的文件无法看懂,因为axios 本身是不做二进制文件流处理的;

这里就需要给 axios 添加 responseType: ‘blob’,

 return axios({
    // 用axios发送get请求
    url:url, // 请求地址
    params: data, // 参数
    method: 'get',
    responseType: 'blob',
    headers: {
      'Content-Type': 'application/json',
    },
  })
获取保存文件名称
// 获取http头部的文件名信息,若无需重命名文件,将下面这行删去
if (!fileName) fileName = window.decodeURI(res.headers['content-disposition'].split('=')[1])

可以传入要保存的文件名称,也可以直接获取接口返回的文件名称;

处理下载文件
 /* 兼容ie内核,360浏览器的兼容模式 */
      const blob = new Blob([res.data], { type: 'application/vnd.ms-excel;charset=utf-8' })
      /* 兼容ie内核,360浏览器的兼容模式 */
      if (window.navigator && window.navigator.msSaveOrOpenBlob) {
        window.navigator.msSaveOrOpenBlob(blob, fileName)
      } else {
        /* 火狐谷歌的文件下载方式 */
        let url1 = window.URL.createObjectURL(blob)
        let link = document.createElement('a')
        link.style.display = 'none'
        link.href = url1
        link.setAttribute('download', fileName)
        document.body.appendChild(link)
        link.click()

因为在测试过程种发现不同浏览从下载有问题,这里做了 ie 内核浏览器和 谷歌、 火狐、浏览器下载处理,实现方式其实也就是使用a 标签的下载数据, 给a标签设置 属性 download
自动执行点击下载,就实现了调用接口后将文件下载导出了!!!!!!!!!!!!!!

假设你使用axios库来发送请求,后端接口为/export,后端返回文件为Excel文件,可以按照以下步骤来实现: 1. 在Vue组件中定义一个方法,用于触发导出操作,并接收表单参数: ``` exportTable() { const params = { // 表单参数 } // 发送请求 axios({ url: '/export', method: 'POST', responseType: 'blob', data: params }).then(res => { // 处理返回文件 const content = res.data const blob = new Blob([content]) const fileName = 'export.xlsx' // 下载文件 const link = document.createElement('a') link.href = window.URL.createObjectURL(blob) link.download = fileName link.click() }).catch(error => { // 处理错误 }) } ``` 2. 在后端接口中,接收表单参数,生成Excel文件返回文件: ```python import io from flask import make_response import xlsxwriter @app.route('/export', methods=['POST']) def export(): # 接收表单参数 form_data = request.form # 生成Excel文件 output = io.BytesIO() workbook = xlsxwriter.Workbook(output) worksheet = workbook.add_worksheet() # 写入数据 workbook.close() output.seek(0) # 返回文件 response = make_response(output.read()) response.headers.set('Content-Type', 'application/vnd.ms-excel') response.headers.set('Content-Disposition', 'attachment', filename='export.xlsx') return response ``` 这样,当用户点击导出按钮时,前端会发送一个POST请求到后端的/export接口后端会接收表单参数,生成Excel文件返回文件前端会处理文件下载Excel文件
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值