new FormData() を理解する必要があります -- アップロード時に、コンテンツをファイル ストリームに変換します
new FileReader() -- base64 圧縮、現在不明
1.Excelファイルのエクスポート
3 種類のエクスポート: 1 つは純粋なフロントエンド エクスポート、2 種類のバックエンド エクスポート: アドレス エクスポート用にバックエンドに分割され、もう 1 つはファイル ストリームの形式でエクスポートされます。非常に大きい
Blod : blob は、ラージ オブジェクトを含むバイナリ ラージ オブジェクトを格納するためのコンテナーです。ボールド オブジェクトを作成します。
バックエンドはバイナリ データのストリームを返し、Excel を生成します。
① Template Acquisition--Export をクリックし、ポップアップボックスで確認し、Confirm をクリック
② インターフェースを呼び出して結果を取得、インターフェースのresponseType: 'blob'
③windowのurlメソッドを呼び出してタグを作成し、a=urlをクリック、設定してダウンロードをクリック
-- ファイルを pdf としてエクスポートする場合、タイプを変更します: 'application/pdf;chartset=UTF-8'
// 模板获取
const getTemplate = async () => {
const res = await getStuTemplate()
// const blob = new Blob(['\ufeff' + res], { type: 'application/vnd.ms-excel' })
// 调用window的url方法
const url = window.URL.createObjectURL(res)
// 通过创建a标签实现
const link = document.createElement('a')
link.href = url
// 命名
// link.download = res?.headers['content-disposition'].split(';')[1].split('=')[1] || '模板'
link.download = decodeURI('考生信息')
document.body.appendChild(link)
// 下载文件
link.click()
// 释放内存
document.body.removeChild(link)
}
// 考生信息--导出excel模板
export async function getStuTemplate(params?: any) {
return request(`/${Proxy_Api}/entrantManage/exportExcel`, {
method: 'GET',
responseType: 'blob',
params,
})
}
// 导出 -- PDF
const getTemplate = async () => {
const res = await getStuTemplate({ code })
// 创建blob对象,解析流数据
const blob = new Blob([res], { type: 'application/pdf;chartset=UTF-8'})
// 调用window的url方法,根据解析后的blob对象创建URL 对象
const url = window.URL.createObjectURL(blob)
// 通过创建a标签实现
const link = document.createElement('a')
link.href = url
// 命名
// link.download = res?.headers['content-disposition'].split(';')[1].split('=')[1] || '模板'
link.download = decodeURI('请假统计')
document.body.appendChild(link)
// 下载文件
link.click()
// 释放内存
document.body.removeChild(link)
}
二、エクセルファイルのインポート・アップロード
①Draggerコンポーネントを使用して アップロードし、アップロードをクリックしてファイルを選択します
②コンポーネントのpropsを設定し、beforeUploadフック関数でファイルを傍受し、アクションアドレスを設定せず、自動アップロードをキャンセルする
③ beforeUpload を通じて、デフォルトのアップロードをインターセプトし、アップロードされたファイルを処理し、ファイル形式を判断します
④モーダルポップアップボックスの確認をクリック後、新たに FormData() を作成し、append を使用して fetch リクエストを送信し、返されたデータを json 形式に変換する必要があります
① 设置组件
<Modal destroyOnClose={true} title="数据导入" visible={isUploadOpen} onOk={handleOkUpload} onCancel={handleCancelUpload} width={550}>
<Dragger {...props} style={
{ marginBottom: 20, marginTop: 20 }}>
<p className="ant-upload-drag-icon"><InboxOutlined /></p>
<p className="ant-upload-text">点击或将文件拖拽到这里上传</p>
<p className="ant-upload-hint">当前仅支持扩展名:.xls/.xlsx</p>
</Dragger>
<p style={
{ fontSize: 12, color: '#00000073', marginTop: 10 }}>注:若在此之前已经上传过数据而此次上传存在覆盖操作,则相关分组信息需要重新导入</p>
</Modal>
// dragger组件
② 设置组件props
// 设置文件变量
const [oneFile, setOneFile] = useState<any>();
const props: UploadProps = {
maxCount: 1, //最大数量
multiple: false, //是否支持多选
onRemove: (file) => { //删除
setOneFile(null)
},
// beforeUpload 拦截默认上传,回调参数就是file文件
// 可以对文件类型进行判断
beforeUpload: (file) => {
const fileName = file.name.substring(file.name.lastIndexOf('.') + 1, file.name.length)
const fileType = fileName == 'xls' || fileName == 'xlsx'
if (!fileType) {
message.error('上传失败,请上传xls/xlsx格式的文件')
} else {
setOneFile(file)
}
return false;
},
};
③ 上传文件
/**点击上传 */
const handleOkUpload = () => {
const formData = new FormData();
formData.append('file', oneFile as RcFile);
fetch(`${Proxy_Api}/entrantManage/importExcel/${code}`, {
method: 'POST',
body: formData,
})
.then((res) => {
return res.json()
})
.then((res) => {
if (res?.success) {
message.success('导入成功');
setOneFile(null)
setIsUploadOpen(false)
} else {
message.error(res.desc)
}
})
.catch(() => {
message.error('导入失败');
})
};
3. 写真をアップロードする
① props をアップロードする、アクションを設定しない、beforeUpload を設定する、ファイルのアップロードをインターセプトする
② アップロードしたファイル、フォーマット、サイズを判断し、毎回アップロード前に変数 oneFile を修正して最終提出する
③ props の onChange を設定 アップロードしたファイルを変更する場合は、base64 メソッドを呼び出し、imageUrl 変数を変更して、現在アップロードされている画像をページに表示します。
④Submit、新しいFormDataをファイルストリームに変換、appendを使用、fetchリクエストを送信、返却データはjson形式に変換する必要あり
① 设置组件
const [imageUrl, setImageUrl] = useState<any>();
<Form.Item label="考点图片" name="photo">
<Upload {...props} >
{imageUrl ?
// 上传图片后,图片反显,图片+上传按钮
[<img src={imageUrl} alt="avatar" style={
{ height: '60px', marginRight: 10 }} />, <Button icon={<UploadOutlined />}>上传文件</Button>]
: <Button icon={<UploadOutlined />}>上传文件</Button>}</Upload>
</Form.Item>
② 设置上传props
// 上传的props
const props: UploadProps = {
maxCount: 1,
multiple: false,
name: "avatar",
action: "#",
listType: "picture",
className: "avatar-uploader",
showUploadList: false,
onRemove: (file) => {
setOneFile(null)
},
/**上传文件之前的钩子,参数为上传的文件,可设置文件格式和大小,若返回false停止上传 */
beforeUpload: beforeUpload,
onChange: handleChange,
};
③ 提交上传文件
const [oneFile, setOneFile] = useState<any>(); //文件变量
/**上传文件之前的钩子,参数为上传的文件,可设置文件格式和大小,若返回false停止上传 */
const beforeUpload = (file: RcFile) => {
const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';
if (!isJpgOrPng) {
message.error('请上传 JPG/PNG 格式的图片!');
}
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isLt2M) {
message.error('图片需要小于 2MB!');
}
setOneFile(file)
return isJpgOrPng && isLt2M;
// 返回false ,不请求,但是获取不到显示图片,用action:"#",替换不请求
// return false;
};
④ base64设置反显图片
// 上传判断,是否显示图片
const getBase64 = (img: RcFile, callback: (url: string) => void) => {
const reader = new FileReader();
reader.addEventListener('load', () => callback(reader.result as string));
// 方法可以将读取到的文件编码成DataURL ,可以将资料(例如图片、excel文件)内嵌在网页之中,不用放到外部文件
reader.readAsDataURL(img);
};
⑤ onChange--上传文件改变时的回调 */
const handleChange: UploadProps['onChange'] = (info: UploadChangeParam<UploadFile>) => {
if (info.file.status === 'uploading') {
return;
}
if (info.file.status === 'done') {
getBase64(info.file.originFileObj as RcFile, (url) => {
setImageUrl(url);
});
}
};
⑥ 提交
/**新增、修改--确认 */
const handleOk = () => {
addForm.validateFields().then(async (values) => {
if (imageUrl) {
const { address, examYear, code, name } = values
let newForm = new FormData()
newForm.append("address", address);
newForm.append("examYear", examYear);
newForm.append('code', code);
newForm.append('name', name);
newForm.append('photo', oneFile);
fetch(`${Proxy_Api}/examPlaceManage`, {
method: 'POST',
body: newForm,
})
.then((res) => {
return res.json()
})
.then((res) => {
if (res?.success) {
message.success('新增成功');
setOneFile(null)
setIsModalOpen(false);
} else {
const { desc } = res
message.error(desc);
}
})
.catch(() => {
message.error('新增失败');
})