文章目录
- 单文件上传
- 后端
- 方法参数
- 方法逻辑
- 前端
- 多文件上传
- 后端
- 前端
单文件上传
后端
这个方法是用于处理HTTP POST
请求的,具体来说它处理的是上传 .dxf
文件的操作。下面是对该方法的详细解释:
方法参数
- @RequestParam:用于获取HTTP请求中的参数,这里是从请求中获取名为 “file” 的multipart类型文件。
- MultipartFile multipartFile:表示从客户端上传的文件,通常通过HTML表单或API调用发送。
方法逻辑
-
文件校验
- 检查文件是否为空。
- 检查文件大小是否超过50MB(52428800字节)。
- 如果文件为空或者过大,则返回一个失败的消息给客户端,错误代码为
BaseErrorCode.CLIENT_ERROR.code()
,并附带错误信息。
-
文件类型验证
- 获取文件原始名称
originalFilename
。 - 验证文件扩展名是否为
.dxf
,如果不是则返回一个失败的消息给客户端,错误信息为“只能导入dxf文件”。
- 获取文件原始名称
-
获取文件输入流
- 使用
getInputStream()
方法获取文件的输入流,这通常用于读取文件内容。
- 使用
-
返回结果
- 方法最后返回了一个
R.ok(resultMap)
,表示成功响应。
- 方法最后返回了一个
@PostMapping("/uploadDxfFile") public R uploadDxfFile(@RequestParam(value = "file", required = true) MultipartFile multipartFile) throws Exception { // 文件校验工作 if (multipartFile.isEmpty() || multipartFile.getSize() > 52428800) { R.fail(BaseErrorCode.CLIENT_ERROR.code(), "上传文件不能为空,且不能大于50MB"); } // 获取文件名 String originalFilename = multipartFile.getOriginalFilename(); if (!(originalFilename.endsWith(".dxf"))) { return R.fail(BaseErrorCode.CLIENT_ERROR.code(), "只能导入dxf文件"); } // 获取文件输入流 InputStream inputStream = multipartFile.getInputStream(); return R.ok(resultMap); }
复制
前端
【组件】
<el-upload class="upload-demo" :action="uploadDxfAction" :data="uploadPostData" :on-preview="handlePreview" :on-remove="handleRemove" :before-remove="beforeRemove" :on-success="handleSuccess" :headers="headers" :limit="1" :on-exceed="handleExceed" :file-list="fileList" style=" width: 100%;"> <el-button size="mini" type="primary">上传dxf文件</el-button> <div slot="tip" class="el-upload__tip" style="color: red;"> 只能上传.dxf文件,且不超过50MB </div> </el-upload>
复制
:action="uploadDxfAction"
:定义文件要上传到的后台接口地址:limit="1"
:限制只能上传一个文件:on-success="handleSuccess"
:定义文件上传成功时执行的方法:headers="headers"
:如果后台做了权限验证,需要在这里定义文件上传时的请求头’
【变量定义】
data() { return { // token token: '', // 请求头 headers: {}, passengerFlowImportDialogVisible: false, // 文件上传地址(后端接受文件的地址) uploadDxfAction: process.env.VUE_APP_BASE_API + "/packing/item/uploadDxfFile", // 文件列表 fileList: [], // 导入文件的同时向后台提交数据 uploadPostData: {}, /// 批量上传物品 uploadItemList: [], // 设置所导入零件参数的时候,点击到的行 selectRow: {}, }; },
复制
【方法定义】
handleSuccess(res) { console.log("文件上传成功"); console.log("res:" + JSON.stringify(res.data.code)); // 这里可以定义一些文件上传成功之后的操作,例如成功提示、文件信息解析…… }, handleRemove(file, fileList) { console.log(file, fileList); }, handlePreview(file) { console.log(file); }, handleExceed(files, fileList) { this.$message.warning( `只能选择 1 个文件,如果想要更换文件,请删除原有文件` ); }, beforeRemove(file, fileList) { return this.$confirm(`确定移除 ${file.name}?`); }, // 清除已经上传的文件 clearFileList() { this.fileList = []; }, handleChange(file, fileList) { this.fileList = fileList; },
复制
多文件上传
后端
/** * 导入一组dxf文件并完成解析 * * @param multipartFiles 文件列表 * @param paramMap 额外参数映射 * @return 返回结果 * @throws Exception 异常 */ @PreAuthorize("@ss.hasPermi('packing:item:uploadDxfFiles')") @Log(title = "上传dxf文件组", businessType = BusinessType.IMPORT) @PostMapping("/uploadBatchDxfFile") public R uploadBatchDxfFile(@RequestParam(value = "files", required = true) List<MultipartFile> multipartFiles, @RequestParam(required = false) Map paramMap) throws Exception { if (multipartFiles.isEmpty()) { return R.fail(BaseErrorCode.CLIENT_ERROR.code(), "上传文件组不能为空"); } // 解析出每个文件 List<Item> items = multipartFiles.stream() .filter(file -> !file.isEmpty() && file.getSize() <= 52428800 && file.getOriginalFilename().endsWith(".dxf")) .map(file -> { try { // 处理文件 } catch (Exception e) { throw new RuntimeException("解析文件出错:" + file.getOriginalFilename(), e); } }) .collect(Collectors.toList()); if (items.isEmpty()) { return R.fail(BaseErrorCode.CLIENT_ERROR.code(), "没有有效的dxf文件被上传"); } HashMap<String, Object> resultMap = new HashMap<>(); resultMap.put("items", items); return R.ok(resultMap); }
复制
前端
<el-upload ref="batchUpload" class="upload-demo" :action="uploadBatchDxfAction" :data="uploadPostData" :on-preview="handlePreview" :on-remove="handleRemove" :before-remove="beforeRemove" :on-success="handleBatchSuccess" :headers="headers" multiple :on-exceed="handleExceed" :file-list="fileList" :on-change="handleChange" :auto-upload="false" style="width: 100%;"> <el-button slot="trigger" size="small" type="primary">选取文件</el-button> <el-button style="margin-left: 10px;" size="small" type="success" @click="submitBatchUpload">上传解析 </el-button> <div slot="tip" class="el-upload__tip" style="color: red;"> 只能上传.dxf文件,每个文件不超过50MB </div> </el-upload>
复制
首先需要关闭自动上传:auto-upload="false"
,不然所选择的文件会被一个一个上传,我们希望同时将这些文件上传到服务器进行处理。
变量定义、方法定义和上面类似,这里只展示不一样的。在选取完文件之后,并不会自动上传到服务器,需要点击按钮手动上传,如果直接调用el-upload的提交方法,还是会一个一个文件的上传,因此我们需要自己写一个请求方法,我的请求方法如下:
import axios from 'axios' // 批量上传文件 export function uploadBatchDxfFile(fileList, token) { const formData = new FormData(); // 遍历文件列表,将每个文件添加到formData中 fileList.forEach((file, index) => { // 你可以选择使用一个通用的键名(如'files'),并让后端处理多个同名的键值 // 或者为每个文件使用唯一的键名,这取决于你的后端需求 formData.append(`files`, file.raw, file.name); // 这里的`files`是后端期望的字段名 }); return axios.post(process.env.VUE_APP_BASE_API + '/packing/item/uploadBatchDxfFile', formData, { headers: { 'Content-Type': 'multipart/form-data', Authorization: `Bearer ${token}` } }).then(response => { // 处理成功的响应 return response.data; }).catch(error => { // 处理错误情况 throw error; }); }
复制
注意需要给vue项目引入axios,才能使用上面的请求方法。最终在页面中给按钮触发事件绑定下面的方法即可
/** * 将选中的文件批量上传 */ submitBatchUpload() { if (this.fileList.length === 0) { this.$modal.msgWarning("请先选择文件再上传解析"); return; } uploadBatchDxfFile(this.fileList, this.token).then(res => { }) },
复制