如何使用axios从laravel下载导出的excel



我下面有来自后端的代码,当我使用Laravel的刀片进行测试时,它运行良好。但在React前端使用Axios时,我无法做到这一点(请参阅下面的前端代码(。

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

不知何故,我从另一个网站找到了一些解决方案:他们更改了后端代码,使用Storage方法返回链接而不是文件。但我不想使用Storage,我想防止文件积压(以防前端用户快速点击下载按钮(。

我的问题是,我们如何在前端Axios中从后端下载返回的文件?


我的前端代码(下面的代码成功下载了一个excel文件,但我认为该文件已损坏,因为我在使用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();
});

这是我登录时的response.data:屏幕截图

我想您忘记在api选项中将responseType指定为blob

const options = {
method: 'POST',
responseType: 'blob', <=== you need this one
data: formData,
url: '/yourApi',
};
return API.request(options);

这可能与如何将响应转换为blob有关。这里有一个代码块,当我必须做这样的事情时,我总是使用它。我已经将其格式化以适合您上面的代码,所以希望它能以相同的方式工作

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);
});

最新更新