アリ・ナディム
アリ・ナディム

Reputation: 610

How to download exported excel from laravel using axios?

I have my code below from Backend that is working fine when I test it using Laravel's blade. But I can't do the same in using Axios in my React frontend (see frontend code below).

return (new NewsExport())->download($filename);

I somehow found some solutions from another site: they change the backend code, they use the Storage method to return a link instead of a file. But I don't want to use Storage, I want to prevent overstoring files (in case of a user in the frontend rapidly clicks the download button).

My question how can we download the returned file from the backend in the frontend Axios?


My frontend codes (the codes below successfully download an excel file, but the file is corrupted I think because I can't open it when I test it using Microsoft Excel)

let response = await newsApi.exportNewsList(payload).then(response => {
    const url = window.URL.createObjectURL(new Blob([response.data]));
    const link = document.createElement('a');
    link.href = url;
    link.setAttribute('download', 'exc.xlsx'); //or any other extension
    document.body.appendChild(link);
    link.click();
});

Here is the response.data when I log: screenshot

Upvotes: 0

Views: 3232

Answers (2)

tempra
tempra

Reputation: 2331

I think you forgot to specify your responseType as blob in your api options.

const options = {
    method: 'POST',
    responseType: 'blob', <=== you need this one
    data: formData,
    url: '/yourApi',
};

return API.request(options);

Upvotes: 4

Richard Hpa
Richard Hpa

Reputation: 2857

It might be to do with how you are converting the response to a blob. Here is a block of code that I always use when I have to do something like this. I have formatted it to suit your code above so hopefully it will work the same way

const b64toBlob = (b64Data, contentType = '', sliceSize = 512) => {
  const byteCharacters = atob(b64Data);
  const byteArrays = [];

  for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
    const slice = byteCharacters.slice(offset, offset + sliceSize);

    const byteNumbers = new Array(slice.length);
    for (let i = 0; i < slice.length; i++) {
      byteNumbers[i] = slice.charCodeAt(i);
    }

    const byteArray = new Uint8Array(byteNumbers);
    byteArrays.push(byteArray);
  }

  const blob = new Blob(byteArrays, { type: contentType });
  return blob;
};

let response = await newsApi.exportNewsList(payload).then(response => {
  const dataBlob = b64toBlob(
    response.data,
    'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;base64'
  );
  const link = window.document.createElement('a');
  link.href = window.URL.createObjectURL(dataBlob);
  link.download = 'exc.xlsx';
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);
});

Upvotes: 0

Related Questions