一、公司项目需求要求导出表格数据,以excel文件导出,后端python处理已经可以直接将数据导出并生成Excel文件,但是前后台传输是不可能直接传输文件的,是以二进制文件流进行传输的,此时呢就会遇到一个问题,最后上网差对比总结,下面这个成熟且处理简单。(导出文件同方法)
二、代码:

/**
 * vue从后台获取数据,并导出EXCEL文件
 * @param value
 * @returns {*}
 * @constructor cuishao 2020.4.15
 */

export function Upexcele(value) {
  const url = window.URL.createObjectURL(value)
  const a = document.createElement('a')
  a.href = url
  a.download = 'xx信息.xls'
  document.body.appendChild(a)
  a.click()
  window.URL.revokeObjectURL(url)
  document.body.removeChild(a)
}

这里是封装了一个公用函数,Upexcele函数中的参数value是成功请求后,后端的返回值。对应下面的res

<template>
...
...
...
  <div class="tradition-meeting-detail">
    <div class="tradition-meeting-back">
      <button class="normal-btn export" @click="onExport()" style="float:right">导出</button>
    </div>
  </div>
</template>

<script>
...
...
...
import {Upexcele}  from '../../../globle/commonFunction'

export default {
  components: {
    NmsPagerTable,
  },
  name: "terminaldetail",
  data() {
    return {
      ...
      ...
      ...

    };
  },
  methods: {
   ...
   ...
   ...
    onExport: function() {
      api.downloadInspect({params:{taskid:this.taskid},responseType: 'blob'})
      .then((res) => {
        Upexcele(res)
      }).catch(error => {
        console.log(error)
      });
    }
  },
</script>

<style scoped>

</style>

请求参数在这里一定要加上 responseType: ‘blob’,否则不会生效。这个blob是js的内置对象 就是将其转化为文件blob
三、api接口

export const downloadInspect = params => {
  return axios.get('/nms/inspect/download/', params).then(res => res.data)
};

这里我使用了vue中使用axios处理get方法导出excel表格
四、后端处理细节(后端语言Python):
1.读的字节流方式:

class DownloadWarning(APIView):
    def get(self, request, *args, **kwargs):

        ......
        ......
        ......

        f = open('/opt/data/nms_webserver/inspect/aa.xls' , 'rb')
        response = FileResponse(f)
        response['Content-Type'] = 'application/octet-stream'
        response['Content-Disposition'] = 'attachment;filename=inspect_result.xls'
        return response

2.第三方requests.get方式:

class DownloadCaptureFile(APIView):
    def get(self, request):
    ......
    ......
    ......
        download_url = "http://"+ip+":"+port+"/api/xxx/xxx/v1"
        headers = {
            'path': 'xxx',
            'type': 'xxxx',
            'home': 'xxxx'
        }
        
        file = requests.get(download_url, headers=headers)
        response = FileResponse(file)
        response['Content-Type'] = 'application/octet-stream'
        response['Content-Disposition'] = 'attachment;filename="%s"' % (fileName)

        return response

注意点两部分:
一个是使用Django实现文件下载-FileResponse:FileResponse是StreamingHttpResponse的衍生类(子类),为二进制文件做了优化。如果 wsgi server 来提供,则使用了wsgi.file_wrapper ,否则将会流式化一个文件为一些小块。
FileResponse 需要通过二进制模式打开文件,如下:

>>> from django.http import FileResponse
>>> response = FileResponse(open('myfile.png', 'rb'))

二是用通用通用的MIME类型:application/octet-stream,它的文件扩展名是.*( 二进制流,不知道下载文件类型),这样做的好处是只要是返回二进制文件,都支持下载。相关知识:HTTP Content-type 对照表
参考:小混蛋&闯江湖 李大玄

Logo

前往低代码交流专区

更多推荐