用el-upload上传表格数据,并且手动提交。
需要将上传的文件以及后端需要的参数一并传过去。
代码如下:
<template>
<el-dialog
v-model="dialogTableVisible"
title="导入对账单"
width="900"
@close="dialogTableClose"
>
<el-form :inline="true" :model="formInline" class="demo-form-inline">
<el-form-item label="供应商">
<el-select
v-model="formInline.supplier_code"
placeholder="选择供应商"
style="width: 180px"
>
<el-option
v-for="item in importState.supplier"
:key="item.code"
:label="item.name"
:value="item.code"
/>
</el-select>
</el-form-item>
<el-form-item label="导入对账单">
<el-upload
:action="config.file_upload" // 请求的后端地址
class="upload-demo"
:data="formInline" // 这里绑定需要另外传递的参数
:file-list="fileList"
:before-upload="beforeUpload"
:on-change="handleChange"
:on-success="handleSuccess"
:on-error="handleError"
:show-file-list="false"
:headers="headers" // 需要的请求头
:limit="1"
ref="upload"
:auto-upload="false" // 不自动上传
accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel"
><el-button>导入数据</el-button>
<template #tip>
<div class="el-upload__tip">
支持扩展名:.xls .xlsx 大小不超过3M
</div>
</template>
</el-upload>
</el-form-item>
<el-button type="primary" @click="onSubmit">提交</el-button>
</el-form>
<el-table
:data="importState.previewTable"
v-if="importState.previewTable.length > 0"
>
<el-table-column
v-for="(item, index) in Object.keys(importState.previewTable[0])"
:key="index"
:prop="item"
:label="item"
/>
</el-table>
</el-dialog>
</template>
<script lang="ts" setup>
import { getCurrentInstance } from "vue";
import type { UploadUserFile } from "element-plus";
import cloneDeep from "lodash/cloneDeep";
import { read, utils } from "xlsx";
const instance: any = getCurrentInstance();
const formInline = reactive({
supplier_code: "",
});
// =========== 导入Excel ==========
const headers: any = reactive({});
let fileList = reactive<UploadUserFile[]>([]);
const importState = reactive<any>({
previewTable: [],
supplier: [],
});
//读取文件,我这里有个上传之后解析表格预览的功能,于是使用了xlsx插件
const file2Xce = (file: any) => {
return new Promise(function (resolve) {
const reader = new FileReader();
reader.onload = function (e: any) {
const data = e.target.result;
const workbook = read(data, { type: "binary" });
const sheetName = workbook.SheetNames[0];
const sheet = workbook.Sheets[sheetName];
const sheetData = utils.sheet_to_json(sheet);
resolve(sheetData);
};
reader.readAsBinaryString(file);
});
};
// change事件,进行了header的设置,以及文件类型的判断
const handleChange = (file: any, files: any) => {
fileList = files;
headers["Authorization"] = localStorage.getItem("token");
headers["Content-Disposition"] = "attachment; filename=" + file.name;
const types = file.name.split(".")[1];
const fileType = ["xlsx", "xls"].some((item) => {
return item === types;
});
if (!fileType) {
ElMessage.error("文件格式错误,请重新选择文件!");
}
if (file.size / 1024 / 1024 > 1) {
ElMessage.error("上传文件大小不能超过 1M !");
return false;
}
// 读取文件
file2Xce(file.raw).then((tab: any) => {
importState.previewTable = cloneDeep(tab);
if (!tab.length) {
ElMessage.error("空文件或数据缺失,请重新选择文件!");
}
});
};
// 导入对账单提交
const onSubmit = () => {
instance?.refs.upload.submit(); // 调用el-upload的提交事件
};
const handleSuccess = (response, file) => {
// 文件上传成功的处理逻辑
if (response.code === 0) {
ElMessage.success("上传成功");
dialogTableVisible.value = false;
}
};
const handleError = (error) => {
// 文件上传失败的处理逻
ElMessage.success("上传失败");
};
// 关闭弹窗事件
const dialogTableClose = () => {
importState.previewTable = [];
};
</script>
手动上传主要就两步。
1、先设置不自动上传。
两个办法,第一个办法:直接设置auto-upload为false
注意: 使用了:auto-upload=false之后before-upload事件就不生效了,这时候就需要on-change事件了!!!
第二个办法:可不设置auto-upload属性,然后在before-upload事件中return false,也可以实现手动上传。
例如:
:before-upload="handleUpload"
const handelUpload = (file) => {
// 你的一些逻辑处理
return false // 阻止上传
}
2、在你需要手动提交的按钮事件中使用submit方法。
const onSubmit = () => {
instance?.refs.upload.submit(); // 调用el-upload的提交事件
};
ok!以上就可以进行手动上传啦!