Reputation: 610
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
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
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