Bootstrap

antd Upload上传实现自定义上传

众所周知,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>
    );
};
;