我使用axios的基本http请求,如GET和POST,它工作得很好。现在我需要能够下载Excel文件。这在axios中可行吗?如果是,谁有一些示例代码?如果不是,我还可以在React应用程序中使用什么来做同样的事情?
当前回答
我的答案是一个完全hack-我只是创建了一个链接,看起来像一个按钮,并添加URL到它。
<a class="el-button"
style="color: white; background-color: #58B7FF;"
:href="<YOUR URL ENDPOINT HERE>"
:download="<FILE NAME NERE>">
<i class="fa fa-file-excel-o"></i> Excel
</a>
我使用的是优秀的VueJs,因此使用了奇怪的表意,然而,这个解决方案是框架不可知的。这个想法适用于任何基于HTML的设计。
其他回答
对于axios POST请求,请求应该是这样的: 这里的关键是responseType和header字段必须在Post的第3个参数中。第二个参数是应用程序参数。
export const requestDownloadReport = (requestParams) => async dispatch => {
let response = null;
try {
response = await frontEndApi.post('createPdf', {
requestParams: requestParams,
},
{
responseType: 'arraybuffer', // important...because we need to convert it to a blob. If we don't specify this, response.data will be the raw data. It cannot be converted to blob directly.
headers: {
'Content-Type': 'application/json',
'Accept': 'application/pdf'
}
});
}
catch(err) {
console.log('[requestDownloadReport][ERROR]', err);
return err
}
return response;
}
我的答案是一个完全hack-我只是创建了一个链接,看起来像一个按钮,并添加URL到它。
<a class="el-button"
style="color: white; background-color: #58B7FF;"
:href="<YOUR URL ENDPOINT HERE>"
:download="<FILE NAME NERE>">
<i class="fa fa-file-excel-o"></i> Excel
</a>
我使用的是优秀的VueJs,因此使用了奇怪的表意,然而,这个解决方案是框架不可知的。这个想法适用于任何基于HTML的设计。
Axios。后解决方案与IE和其他浏览器
我在这里找到了一些不可思议的解决方案。但他们通常不会考虑IE浏览器的问题。也许这样可以为别人节省一些时间。
axios.post("/yourUrl",
data,
{ responseType: 'blob' }
).then(function (response) {
let fileName = response.headers["content-disposition"].split("filename=")[1];
if (window.navigator && window.navigator.msSaveOrOpenBlob) { // IE variant
window.navigator.msSaveOrOpenBlob(new Blob([response.data],
{ type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }
),
fileName
);
} else {
const url = window.URL.createObjectURL(new Blob([response.data],
{ type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download',
response.headers["content-disposition"].split("filename=")[1]);
document.body.appendChild(link);
link.click();
}
}
);
上面的例子适用于excel文件,但是稍加改变就可以应用于任何格式。
在服务器上,我这样做是为了发送一个excel文件。
response.contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
response.addHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=exceptions.xlsx")
你需要返回File({file_to_download}, "application/vnd.ms-excel")从后端到前端,在你的js文件中,你需要更新下面写的代码:
function exportToExcel() {
axios.post({path to call your controller}, null,
{
headers:
{
'Content-Disposition': "attachment; filename=XYZ.xlsx",
'Content-Type': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
},
responseType: 'arraybuffer',
}
).then((r) => {
const path= window.URL.createObjectURL(new Blob([r.data]));
const link = document.createElement('a');
link.href = path;
link.setAttribute('download', 'XYZ.xlsx');
document.body.appendChild(link);
link.click();
}).catch((error) => console.log(error));
}
使用URL.CreateObject()的答案对我来说工作得很好。 我仍然想指出使用HTTP报头的选项。
使用HttpHeaders有以下优点:
广泛的浏览器支持 不需要在浏览器的内存中创建一个blob对象 在显示给用户反馈之前,不需要等待服务器的完整响应吗 无尺寸限制
使用HttpHeaders需要你访问下载文件的后端服务器(这似乎是OP的Excel文件的情况)
HttpHeaders解决方案:
前端:
//...
// the download link
<a href="download/destination?parameter1=foo¶m2=bar">
click me to download!
</a>
后端
(本例中是c#,但也可以是任何语言。根据需要进行调整)
...
var fs = new FileStream(filepath, FileMode.OpenOrCreate, FileAccess.Read);
Response.Headers["Content-Disposition"] = "attachment; filename=someName.txt";
return File(fs, "application/octet-stream");
...
此解决方案假定您可以控制响应的后端服务器。
https://github.com/eligrey/FileSaver.js/wiki/Saving-a-remote-file#using-http-header