众所周知,Upload上传有个action的坑,就是你选择文件之后自动调用地址然后就会执行上传接口,这在某些情况的却是很好用的一个组件。但是如果要实现自定义的上传,如下图所示,就要阻止默认上传的事件。
现在我们要实现点击保存按钮才进行上传,所以我们就需要在beforeUpload这个钩子函数里面阻止默认上传。
beforeUpload: file => {
const fileType = file.name.split('.').pop();
if (fileType !== 'xlsx') {
message.error(`上传失败:上传文件格式非.xslx`);
return false
}
const arrData = fileList;
for(let i =0 ;i<arrData.length;i++){
if(arrData[i].name == file.name){
message.error(`上传失败:禁止上传重复的文件`);
return false
}
}
/* return new Promise((resolve,reject)=>{
resolve(file)
}) */
return false
},
对于复合条件的文件,在onChange里面改变文件状态
onChange(info) {
console.log(info)
const fileType = info.file.name.split('.').pop();
if (fileType === 'xlsx') {
setFileList(info.fileList.slice(-1));//限制只上传一个文件
info.file.status = 'done';//更改文件状态
}
},
接下来是按钮的保存事件
const handleOk = async () => {
if (fileList && fileList.length) { //检验是否有上传文件
const formData = new FormData();
formData.append('file', fileList[0].originFileObj);
fetch(toHandleToken(), { method: 'POST', body: formData })
.then(res => res.json())
.then(res => {
//上传成功
}
).catch(e => {
//上传失败
})
} else {
message.error('请上传文件后再提交!');
}
};
OK,这样就可以了
下面附带一种将upload组件处理后的文件流转换的方法
let reader = new FileReader();//创建读取文件的方法
let item = {};
let blob = null;
//转化为binary类型
reader.readAsArrayBuffer(fileList[0].originFileObj)
reader.onload = (e) => {
console.log(e.target.result)
if(typeof e.target.result === 'object'){
blob = new Blob([e.target.result])
}else{
blob = e.target.result
}
console.log(blob)
const formData = new FormData();
formData.append('file',blob);
fetch(toHandleToken(), {method: 'POST', body: formData})
.then(res => res.json())
.then(res => {
}
).catch(e => {
})
}
下面是全部的代码
const ImportModal = () => {
useEffect(() => {
}, []);
//处理导入文件的url
const toHandleToken = () => {
let baseurl
if (process.env.NODE_ENV == 'development') {
baseurl = `${baseUrl}/api/services/file_uploading?`;
} else {
baseurl = `${baseUrl}/api/services/file_uploading?`;
}
let url;
let resInfo = sessionStorage.getItem("oauth");
if (resInfo != null) {
let resJsons = JSON.parse(resInfo);
let token = resJsons.access_token;
url = baseurl + "access_token=" + token;
} else {
url = baseurl + "";
}
return url;
}
const [fileList, setFileList] = useState([]);
const props = {
name: 'file',
multiple: false,
action: toHandleToken(),
headers: {
authorization: 'authorization-text',
},
fileList,
beforeUpload: file => {
console.log(file, '文件');
const fileType = file.name.split('.').pop();
if (fileType !== 'xlsx') {
message.error(`上传失败:上传文件格式非.xslx`);
return false
}
const arrData = fileList;
for (let i = 0; i < arrData.length; i++) {
if (arrData[i].name == file.name) {
message.error(`上传失败:禁止上传重复的文件`);
return false
}
}
/* return new Promise((resolve,reject)=>{
resolve(file)
}) */
return false
},
onChange (info) {
console.log(info)
const fileType = info.file.name.split('.').pop();
if (fileType === 'xlsx') {
setFileList(info.fileList.slice(-1));//限制只上传一个文件
info.file.status = 'done';//更改文件状态
}
},
onDrop (e) {
console.log('Dropped files', e.dataTransfer.files);
},
/* customRequest:async options=>{
const { onSuccess, onError, file, onProgress,action } = options;
} */
};
return (
<Consumer>
{
context => {
const { showImportModal, setShowImportModal } = context;
const handleCancel = () => {
setShowImportModal(false);
};
const handleOk = async () => {
if (fileList && fileList.length) { //检验是否有上传文件
const formData = new FormData();
formData.append('file', fileList[0].originFileObj);
fetch(toHandleToken(), { method: 'POST', body: formData })
.then(res => res.json())
.then(res => {
}
).catch(e => {
})
/* let reader = new FileReader();//创建读取文件的方法
let item = {};
let blob = null;
//转化为binary类型
reader.readAsArrayBuffer(fileList[0].originFileObj)
reader.onload = (e) => {
console.log(e.target.result)
if(typeof e.target.result === 'object'){
blob = new Blob([e.target.result])
}else{
blob = e.target.result
}
console.log(blob)
const formData = new FormData();
formData.append('file',blob);
fetch(toHandleToken(), {method: 'POST', body: formData})
.then(res => res.json())
.then(res => {
}
).catch(e => {
})
} */
} else {
message.error('请上传文件后再提交!');
}
};
return (
<Modal
forceRender
visible={showImportModal}
title="导入文件"
onCancel={() => { handleCancel() }}
destroyOnClose={true}
footer={[
<Button onClick={() => { handleCancel() }}>
取消
</Button>,
<Button type="primary" onClick={() => { handleOk() }}>
保存
</Button>
]}
>
<div className={style.importModalContent}>
<Dragger {...props}>
<div className={style.modalCloudIcon}>
<CloudUploadOutlined />
</div>
<div className={style.modalText}>
将文件拖拽到此处,或<span className={style.upload}>点击上传</span>
<br />
只能上传xlsx文件,且不能超过20MB
</div>
</Dragger>
<div className={style.download}>
<DownloadOutlined />
下载模板
</div>
</div>
</Modal>
);
}
}
</Consumer>
);
};