Gergan Zhekov
Gergan Zhekov

Reputation: 1064

Downloading an excel file from API response (Vue.JS - front-end, Flask-backend)

I am having some difficulties downloading an excel file in my front-end, which I get through the API response, which I am making to a Flask back-end.

This is what I have so far:

Flask (Backend)

...
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
)
...

I have tested that this works through Postman, from where I can download this excel report and everything seems OK.

Vue.JS (Front-end)

Here, I make a request to the Flask back-end, which returns the file in the body:

    /**
     * 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))
     },

And the getExcelReport function here:

/**
 * 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
}

When I try to open the generated Excel report, it says that the file is corrupted. I can also see that the number of bytes is much bigger (around twice bigger).

I have also tried similar solutions from StackOverflow with FileReader. Does anyone else have an idea what I am doing wrong here?

Upvotes: 1

Views: 3562

Answers (1)

Gergan Zhekov
Gergan Zhekov

Reputation: 1064

I solved the issue the following way:

   /**
     * 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))
    },

Upvotes: 5

Related Questions