我使用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)
}
};
其他回答
诀窍是在render()中创建一个不可见的锚标记,并添加一个React ref,允许在我们有axios响应时触发单击:
class Example extends Component {
state = {
ref: React.createRef()
}
exportCSV = () => {
axios.get(
'/app/export'
).then(response => {
let blob = new Blob([response.data], {type: 'application/octet-stream'})
let ref = this.state.ref
ref.current.href = URL.createObjectURL(blob)
ref.current.download = 'data.csv'
ref.current.click()
})
}
render(){
return(
<div>
<a style={{display: 'none'}} href='empty' ref={this.state.ref}>ref</a>
<button onClick={this.exportCSV}>Export CSV</button>
</div>
)
}
}
以下是文档:https://reactjs.org/docs/refs-and-the-dom.html。你可以在这里找到类似的想法:https://thewebtier.com/snippets/download-files-with-axios/。
当响应带有可下载文件时,响应头将类似于
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');
});
我有一个问题,我从axios const axiosResponse = await axios.get(pdf.url)传输到谷歌驱动器googleDrive.files。create({media: {body: axiosResponse.)data, mimeType}, requestBody: {name: fileName, parents: [parentFolder], mimeType}, auth: jwtClient})上传一个损坏的文件。
文件损坏的原因是axios转换了axiosResponse。数据转换为字符串。为了解决这个问题,我必须要求axios返回一个axios.get流。url, {responseType: 'stream'})。
实现接收文档的Axios处理程序,数据格式为octect-stream, 数据可能看起来很奇怪PK一些JbxfFGvddvbdfbVVH34365436fdkln作为它的八字节流格式,你可能最终会创建这个数据可能被损坏的文件,{responseType: 'blob'}将数据转换为可读格式,
axios.get("URL", {responseType: 'blob'})
.then((r) => {
let fileName = r.headers['content-disposition'].split('filename=')[1];
let blob = new Blob([r.data]);
window.saveAs(blob, fileName);
}).catch(err => {
console.log(err);
});
你可能尝试过这样的解决方案, 窗口。saveAs(blob, 'file.zip')将尝试将文件保存为zip,但将不会工作,
const downloadFile = (fileData) => {
axios.get(baseUrl+"/file/download/"+fileData.id)
.then((response) => {
console.log(response.data);
const blob = new Blob([response.data], {type: response.headers['content-type'], encoding:'UTF-8'});
const link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
link.download = 'file.zip';
link.click();
})
.catch((err) => console.log(err))
}
const downloadFile = (fileData) => {
axios.get(baseUrl+"/file/download/"+fileData.id)
.then((response) => {
console.log(response);
//const binaryString = window.atob(response.data)
//const bytes = new Uint8Array(response.data)
//const arrBuff = bytes.map((byte, i) => response.data.charCodeAt(i));
//var base64 = btoa(String.fromCharCode.apply(null, new Uint8Array(response.data)));
const blob = new Blob([response.data], {type:"application/octet-stream"});
window.saveAs(blob, 'file.zip')
// const link = document.createElement('a');
// link.href = window.URL.createObjectURL(blob);
// link.download = 'file.zip';
// link.click();
})
.catch((err) => console.log(err))
}
function base64ToArrayBuffer(base64) {
var binaryString = window.atob(base64);
var binaryLen = binaryString.length;
var bytes = new Uint8Array(binaryLen);
for (var i = 0; i < binaryLen; i++) {
var ascii = binaryString.charCodeAt(i);
bytes[i] = ascii;
};
return bytes;
}
另一个简单的解决方法是,
window.open("URL")
将继续打开不必要的新选项卡,用户可能不得不让允许弹出的工作这段代码,如果用户想同时下载多个文件,所以先去解决方案或如果不尝试其他解决方案也怎么办
使用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