Flask+Vue实现excel文件从服务器端导出至本地

Posted SmallSky1997

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Flask+Vue实现excel文件从服务器端导出至本地相关的知识,希望对你有一定的参考价值。

背景

前端:Vue
后端:Flask-Restful

这里主要实现的功能是将数据库中的数据整理后写入Excel文件,并先将文件存储在服务器端,再在客户端将文件从服务器端下载到本地。
虽然后端主要是用的Flask-Restful,但这里导出的实现还是使用的Flask中的send_from_directory,因为在Flask-Restful中没有找到合适的方法实现

后端

@app.route("/api/v1/Services/Download/<string:product_flag>&&<string:product_version>", methods=[\'POST\'])
def downloader(product, product_version):
    filename = data_output(product, product_version)  # data_output方法实现数据库中的数据写入Excel文件,返回文件名

    dir_path = str(os.path.abspath(os.path.dirname(__file__)))
    dirpath = os.path.join(os.path.join(dir_path, \'downloads\'))  # 获取文件路径

    response = make_response(send_from_directory(dirpath, filename, as_attachment=True))
    response.headers["Access-Control-Expose-Headers"] = "Content-disposition"

    return response

前端

按钮,点击调用方法handleDownload

<el-button v-waves :loading="downloadLoading" class="filter-item" style="margin-left: 10px;" type="primary" icon="el-icon-download" @click="handleDownload">
   导出
</el-button>

js方法实现

handleDownload() {
      axios.post(
        this.downloadUrl + this.listQuery.product + \'&&\' + this.listQuery.product_version,
        { responseType: \'arraybuffer\' }
      ).then(response => {
        if (response.status === 200) {
          const blob = new Blob([response.data], {
            type: response.headers[\'content-type\']
          })

          const fileName = response.headers[\'content-disposition\']
          const title = fileName && (fileName.indexOf(\'filename=\') !== -1) ? fileName.split(\'=\')[1].split(\'; filename\')[0] : \'download\'
          require(\'script-loader!file-saver\')
          saveAs(blob, title)
        }
      }).catch()
    }

问题解决

导出的excel文件打开时报错,但是在服务器端保存的文件打开是正常的
image
尝试了很多方法没有解决。但因为后端实现最初的请求是GET,所以我在想将请求换回GET,重新写前端逻辑是否可行,没想到真的解决了这个问题。先贴代码

handleDownload() {
      axios.get(
        this.downloadUrl + this.listQuery.product + \'&&\' + this.listQuery.product_version,
        { responseType: \'blob\' }
      ).then(response => {
        if (!response) {
          return
        }
        const filename = response.headers[\'content-disposition\'].split(\'filename=\')[1].split(\'; filename\')[0]
        const url = window.URL.createObjectURL(response.data)
        const link = document.createElement(\'a\')
        link.style.display = \'none\'
        link.href = url
        link.setAttribute(\'download\', \'导出\' + filename)
        document.body.appendChild(link)
        link.click()
      }).catch()
    }

使用了axios的get方法,其中请求的responseType为blob,而非arraybuffer

以上是关于Flask+Vue实现excel文件从服务器端导出至本地的主要内容,如果未能解决你的问题,请参考以下文章

vue中使用axios处理post方法导出excel表格(后端返回文件流)

Vue通过Blob对象实现导出Excel功能

vue3:Excel导入导出解决方案

将列表导出成excel表格图片下载(vue中使用)

Vue小模块之功能全面的表格表格数据的Excel导出

abp框架Excel导出——基于vue