15

I'm struggling to download an Excel file in xlsx format in my Vue.js application. My Vue.js application make post request to the Node.js application which download that Excel file from remote SFTP server. Backend application works without any problems.

In Vue.js application I use next code:

axios.post(config.backendHost + '/excel', {
  file_name: fileName
}).then((response) => {
  const url = URL.createObjectURL(new Blob([response.data], {
    type: 'application/vnd.ms-excel'
  }))
  const link = document.createElement('a')
  link.href = url
  link.setAttribute('download', fileName)
  document.body.appendChild(link)
  link.click()
});

After downloading file by browser, file opens automatically and I am experiencing an error that looks like this:

We found a problem with some content .xlsx. Do you want us to try and recover as much as we can?

Narendra Jadhav
  • 10,052
  • 15
  • 33
  • 44
Nurzhan Nogerbek
  • 4,806
  • 16
  • 87
  • 193

2 Answers2

30

You need to add the response type as a third argument in your post call

{
    responseType: 'blob'
}

Your final code like that

axios.post(config.backendHost + '/excel', {
    file_name: fileName
}, {
    responseType: 'blob'
}).then((response) => {
    const url = URL.createObjectURL(new Blob([response.data], {
        type: 'application/vnd.ms-excel'
    }))
    const link = document.createElement('a')
    link.href = url
    link.setAttribute('download', fileName)
    document.body.appendChild(link)
    link.click()
});

Or you can use the library FileSaver.js to save your file

import FileSaver from 'file-saver'

axios.post(config.backendHost + '/excel', {
    file_name: fileName
}, {
    responseType: 'blob'
}).then((response) => {

    // response.data is a blob type
    FileSaver.saveAs(response.data, fileName);
});
dibra
  • 368
  • 4
  • 9
  • 1
    Thank you very much! :) I use first option which you described in your post and it works for me. Can I ask you one more question?! During the download, is it possible to change the style inside the excel file? For example, I want the header to be highlighted in a different color. Is it even possible for your opinion? – Nurzhan Nogerbek Sep 22 '19 at 16:25
  • 1
    I don't think if you can do any modifications on the fly, but you can manipulate your file on the server side (NodeJS in your case) before downloading. – dibra Sep 23 '19 at 10:13
  • Any recommendation on how to write a unit test for this? – Tom Nov 11 '20 at 23:22
  • @Tom i'm not sure where the problem lies in unit testing this ? If your test always returns the same file, you can hash it using a hashing algorithm like MD5 (fast but weak due to collisions) and just verify in the test that the file returned has that same hash digest – Lorenzo Feb 25 '21 at 06:23
  • FWIW: I needed to say `{responseType: 'arraybuffer'}`, not `{responseType: 'blob'}`. I was sending a .XLSX file from Django as an HttpResponse. – cjohnson318 May 18 '22 at 19:23
2

my case worked:

  axios.get(`/api/v1/companies/${companyId}/export`, {
    responseType: 'blob',
  }).then((response) => {
    const url = URL.createObjectURL(new Blob([response.data]))
    const link = document.createElement('a')
    link.href = url
    link.setAttribute(
      'download',
      `${companyId}-${new Date().toLocaleDateString()}.xlsx`
    )
    document.body.appendChild(link)
    link.click()
  })
Jorge Epuñan
  • 710
  • 7
  • 9