从 API 响应下载 excel 文件(Vue.JS - 前端,Flask 后端)

Ger*_*kov 1 rest excel flask vue.js axios

我在前端下载 Excel 文件时遇到一些困难,该文件是通过 API 响应获得的,该响应是我对 Flask 后端进行的。

这是我到目前为止所拥有的:

烧瓶(后端)

...
generator.generate_excel_report()
return send_file(
    generator.get_excel_report(), # returns location to generated file
    mimetype=sc.CONTENT_TYPE_EXCEL, # application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
    as_attachment=True
)
...
Run Code Online (Sandbox Code Playgroud)

我已经通过 Postman 测试了这一点,我可以从那里下载此 Excel 报告,一切似乎都正常。

Vue.JS(前端)

在这里,我向 Flask 后端发出请求,后端返回正文中的文件:

    /**
     * Download Excel version of the report
     */
    downloadExcelReport(data) {
      SERVICE.post(
      `/api/v1/project/${this.projectNumber}/${this.variantName}/${this.buildNumber}/report/excel`, {
            responseType: 'arraybuffer'
          }).then((response) => getExcelReport(response.data))
     },
Run Code Online (Sandbox Code Playgroud)

这里的getExcelReport函数:

/**
 * Make a POST request to the back-end that will generate an Excel sheet
 * for the project, and return it.
 */
export function getExcelReport(data) {
  const blob = new Blob([data], { // Make a BLOB object
    type : 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
  });

  download(blob, "ExcelReport", 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') // use the DownloadJS library and download the file
}
Run Code Online (Sandbox Code Playgroud)

当我尝试打开生成的 Excel 报告时,它显示该文件已损坏。我还可以看到字节数要大得多(大约大两倍)。

我也尝试过 StackOverflow 和 FileReader 的类似解决方案。还有其他人知道我在这里做错了什么吗?

Ger*_*kov 5

我通过以下方式解决了这个问题:

   /**
     * Download Excel version of the report
     */
    downloadExcelReport() {
      const fileName = `${this.projectNumber}_${this.variantName}_#${this.buildNumber}_SWF.xlsx`
      const apiEndpoint = `/api/v1/project/${this.projectNumber}/${this.variantName}/${this.buildNumber}/report/excel`
      const headers = {
        'Content-Disposition': `attachment; filename=${fileName}`,
        'Content-Type':
          'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
      }

      SERVICE.post(apiEndpoint, null, {
        headers: headers,
        responseType: 'arraybuffer',
      })
        .then((response) => {
          const url = window.URL.createObjectURL(new Blob([response.data]))
          const link = document.createElement('a')
          link.href = url
          link.setAttribute('download', fileName)
          document.body.appendChild(link)
          link.click()
        })
        .catch((error) => console.log(error))
    },
Run Code Online (Sandbox Code Playgroud)