我使用axios的基本http请求,如GET和POST,它工作得很好。现在我需要能够下载Excel文件。这在axios中可行吗?如果是,谁有一些示例代码?如果不是,我还可以在React应用程序中使用什么来做同样的事情?
当前回答
这个函数将帮助您下载一个现成的xlsx, csv等文件下载。我只是从后端发送一个就绪的xlsx静态文件,它在反应。
const downloadFabricFormat = async () => {
try{
await axios({
url: '/api/fabric/fabric_excel_format/',
method: 'GET',
responseType: 'blob',
}).then((response) => {
const url = window.URL.createObjectURL(new Blob([response.data]));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', 'Fabric Excel Format.xlsx');
document.body.appendChild(link);
link.click();
});
} catch(error){
console.log(error)
}
};
其他回答
当响应带有可下载文件时,响应头将类似于
Content-Disposition: "attachment;filename=report.xls"
Content-Type: "application/octet-stream" // or Content-type: "application/vnd.ms-excel"
您可以创建一个单独的组件,该组件将包含一个隐藏的iframe。
import * as React from 'react';
var MyIframe = React.createClass({
render: function() {
return (
<div style={{display: 'none'}}>
<iframe src={this.props.iframeSrc} />
</div>
);
}
});
现在,你可以将可下载文件的url作为prop传递给这个组件,所以当这个组件接收到prop时,它将重新渲染,文件将被下载。
编辑:你也可以使用js-file-download模块。链接到Github回购
const FileDownload = require('js-file-download');
Axios({
url: 'http://localhost/downloadFile',
method: 'GET',
responseType: 'blob', // Important
}).then((response) => {
FileDownload(response.data, 'report.csv');
});
我的答案是一个完全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的设计。
使用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
对于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;
}
使用axios进行API调用的函数:
function getFileToDownload (apiUrl) {
return axios.get(apiUrl, {
responseType: 'arraybuffer',
headers: {
'Content-Type': 'application/json'
}
})
}
调用函数,然后下载excel文件:
getFileToDownload('putApiUrlHere')
.then (response => {
const type = response.headers['content-type']
const blob = new Blob([response.data], { type: type, encoding: 'UTF-8' })
const link = document.createElement('a')
link.href = window.URL.createObjectURL(blob)
link.download = 'file.xlsx'
link.click()
})