赞
踩
选中多个文件上传
通过axios请求
onUploadProgress
方法监听
on-progress
on-success
用这两个钩子函数实现进度条 下面有对应的函数。
本文是每个文件一个请求上传
也可以用一个请求上传多个文件,需要将文件遍历添加到form
表单中,后端用request.getParts();
获取集合,有需要的可以改造一下。
官网地址:https://element.eleme.cn/#/zh-CN/
<template> <div> <!-- multiple 允许上传多个文件 --> <el-upload :disabled="defaultDisabled" ref="upload" :multiple="multiFile" action="" :auto-upload="false" :file-list = "fileList" :http-request="uploadFile" :on-change="changeFileLength" :on-progress="uploadFileProcess" :on-success="handleFileSuccess" :on-preview = "handleFilePreview" :on-remove = "handleFileRemove" :before-upload = "beforeFileUpload" :before-remove = "beforeFileRemove" :limit="limit" :on-exceed = "handleFileExceed"> <div v-if="!defaultDisabled"> <el-button slot="trigger" size="small" type="primary">选取文件</el-button> <el-button style="margin-left: 10px;" size="small" type="success" @click.stop="upload">上传到服务器</el-button> </div> <div slot="tip" class="el-upload__tip">文件大小不能超过1GB</div> </el-upload> </div> </template> <script> module.exports = { name: "upload", props:{ data:{ type:Array, default:[], }, businessId:{ type:String, default:"", }, businessType:{ type:String, default:"", }, filePath:{ type:String, required:true, //必须指定路径 default:"", }, fileSize:{ type:Number, default:(1024 * 1024 * 1024) // 默认1GB }, fileNumber:{ type:Number, default: 5 //默认5个文件 }, disabled:{ type:Boolean, default:false, }, multiple:{ type:Boolean, default:true, } }, data(){ return { fileList: this.data, // 文件列表 size:this.fileSize,// 文件大小限制 limit:this.fileNumber, // 文件数量 path:this.filePath, // 上传路径 defaultDisabled: this.disabled, // 是否禁用 formId: this.businessId, //业务主键 formTable: this.businessType, //业务表 multiFile:this.multiple //默认上传多个文件 } }, created(){ this.getFileList(); }, methods:{ //文件上传前调用,如果返回false 和 失败状态 就会停止上传 并移除fileList的文件 beforeFileUpload(file) { //校验文件大小 if (file.size >= this.size) { //单位GB let gb = (file.size / this.size).toFixed(4); this.$notify.error({ title: '错误', message: `${file.name} 文件大小超出${gb}GB,请重新选择!` }); return false; } }, // 将文件名称进行编码 后台进行解码 changeFileLength(file, fileList){ let fileName = encodeURI(file.name) // 如果可以上传多个文件,这里需要用fileList.forEach()处理 let newFile = new File([file.raw],fileName); newFile.uid = file.uid; // new File 没有uid属性,会导致组件底层报错,这里手动加上 file.raw = newFile; // 替换file的数据 }, // 用户点击上传调用 async upload(){ // 触发上传 调用配置 :http-request="uploadFile" // 即触发 uploadFile函数 await this.$refs.upload.submit(); // 上传完成后执行的操作 ... }, // 该函数调用多次 // 每次param参数传入一个文件 uploadFile(param){ // 创建FormData上传 let form = new FormData(); form.append('file', param.file) form.enctype = "multipart/form-data"; // 将附加信息添加至FormData form.append("filePath", this.path); form.append("businessId", this.formId); form.append("businessType", this.formTable); //上传操作 this.uploadAttach(form,param).then(res => { /*上传成功处理*/ param.onSuccess(res); }).catch(err => { /*报错处理*/ this.$message.error(param.file.name + "上传错误"); param.onSuccess(err); for (let i = 0; i < this.fileList.length; i++) { if (param.file.name === this.fileList[i].name) { this.fileList.splice(i, 1); break; } } }); // } }, // 上传文件 uploadAttach(data,fileObject){ return axios({ method:'post', headers: {"Content-Type": "multipart/form-data"}, url:"/servlet/uploadServlet",//自定义上传url data:data, onUploadProgress: progressEvent => { fileObject.progressFlag = true; fileObject.successFlag = true; let percent=(progressEvent.loaded / progressEvent.total * 100) | 0 fileObject.onProgress({percent});//调用uploader的进度回调 } }) }, // 文件上传过程中的函数(在这里获取进度条的进度) uploadFileProcess(event, file, fileList) { this.fileList = fileList; for (let i = 0; i < this.fileList.length; i++) { if(file.name === this.fileList[i].name){ this.fileList[i].progressFlag = true; this.fileList[i].successFlag = false; if(event.percent != 100){ this.fileList[i].progressPercent = event.percent; } break; } } }, // 文件上传成功的函数(用于文件上传成功之后的逻辑处理) handleFileSuccess(res,file,fileList){ this.fileList = fileList; for (let i = 0; i < this.fileList.length; i++) { if(file.name === this.fileList[i].name){ this.fileList[i].progressFlag = true; if(file.status == 'success' && res.data.code == 200){ this.fileList[i].successFlag = true; res.data = res.data.data; }else{ this.fileList[i].successFlag = false; this.fileList.splice(i, 1); } break; } } }, //查看文件 handleFilePreview(file){ console.log(file); }, //删除文件 handleFileRemove(file,fileList){ console.log(file); }, //文件数超出函数 handleFileExceed(files,fileList){ this.$notify.error({ title: '错误', message: `只能选择${this.limit}个文件,请重新选择文件!` }); }, //文件删除前的操作 beforeFileRemove(file, fileList){}, // 后台获取已经上传的文件列表 getFileList(){ if(this.businessId === "") return; axios.get("/servlet/uploadServlet",{ businessId:this.businessId, }).then(res => { if(res.data.code === 200) this.fileList = res.data.data }).catch(err=>{ this.$message.error("请求失败,请稍后再试!"); }) }, } } </script> <style scoped> </style>
@MultipartConfig
使用这个注解后 用下面方式获取文件Part part = request.getPart("file")
获取的是单文件Collection<Part> parts = request.getParts();
获取的多文件package com.kaiyue.detection.upload; import com.App.Servlet.AppResponse; import com.alibaba.fastjson.JSONObject; import com.kaiyue.common.BeanFactory; import com.kaiyue.common.resource.AppConfig; import com.kaiyue.common.util.DateUtil; import com.kaiyue.jpf.attachment.service.FileService; import com.kaiyue.jpf.common.resource.CommonResource; import javax.servlet.ServletException; import javax.servlet.annotation.MultipartConfig; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.Part; import java.io.*; import java.net.URLDecoder; import java.util.Collection; import java.util.HashMap; import java.util.Random; @WebServlet(name = "uploadServlet", urlPatterns = "/servlet/uploadServlet") @MultipartConfig public class uploadServlet extends HttpServlet { @Override public void destroy() { super.destroy(); } @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } /** * @param request * @param response */ @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { request.setCharacterEncoding("utf-8"); response.setCharacterEncoding("utf-8"); response.setContentType("text/html;charset=utf-8"); FileService fileService = (FileService) BeanFactory.getBeanByName("fileService"); AppResponse res = new AppResponse(); request.setCharacterEncoding("UTf-8"); String businessId = request.getParameter("businessId");//业务主键 String filePath = request.getParameter("filePath");//保存路径 String businessType = request.getParameter("businessType");//业务表名 HashMap<String, String> returnMap = new HashMap<>(); String fileId = "";//文件信息的主键 try { //获取文件对象 Part part = request.getPart("file"); //获取请求头,请求头的格式:form-data; name="file"; filename="snmp4j--api.zip" String header = part.getHeader("content-disposition"); String fileName = getFileName(header); fileName = URLDecoder.decode(fileName, "UTF-8"); //获取配置的磁盘根目录 String path = AppConfig.getRootPath(); Random random = new Random(); int number = random.nextInt(1000); //防止上传的文件重名 取一个新的名字 String newFileName = fileName.substring(0, fileName.lastIndexOf(".")) + DateUtil.getTimeStampId() + number + fileName.substring(fileName.lastIndexOf(".")); File dir = new File(path + CommonResource.FILE_SEPARATOR + filePath + CommonResource.FILE_SEPARATOR); if (!(dir.exists())) { dir.mkdirs(); } //写入磁盘 uploadFile(part, dir + CommonResource.FILE_SEPARATOR + newFileName); String projectId = ""; String userId = ""; //保存到数据库 fileId = fileService.addFileRecord(fileName, filePath + CommonResource.FILE_SEPARATOR + newFileName, userId, businessType, businessId, projectId, part.getSize()); returnMap.put("fileId", fileId);//主键 returnMap.put("businessId", businessId); res.setData(returnMap); res.setCode(AppResponse.OK); res.setMessage("上传成功!"); } catch (Exception e) { res.setData(returnMap); res.setCode(AppResponse.PARAMETER_ERR); res.setMessage("上传失败!"); e.printStackTrace(); } PrintWriter out = response.getWriter(); out.println(JSONObject.toJSONString(res)); out.flush(); out.close(); } /** * 根据请求头解析出文件名 * 请求头的格式:火狐和google浏览器下:form-data; name="file"; filename="snmp4j--api.zip" * IE浏览器下:form-data; name="file"; filename="E:\snmp4j--api.zip" * * @param header 请求头 * @return 文件名 */ public String getFileName(String header) { /** * String[] tempArr1 = header.split(";");代码执行完之后,在不同的浏览器下,tempArr1数组里面的内容稍有区别 * 火狐或者google浏览器下:tempArr1={form-data,name="file",filename="snmp4j--api.zip"} * IE浏览器下:tempArr1={form-data,name="file",filename="E:\snmp4j--api.zip"} */ header = header.substring(header.lastIndexOf("\\") + 1).replaceAll("\"", ""); String[] tempArr1 = header.split(";"); /** *火狐或者google浏览器下:tempArr2={filename,"snmp4j--api.zip"} *IE浏览器下:tempArr2={filename,"E:\snmp4j--api.zip"} */ String[] tempArr2 = tempArr1[2].split("="); //获取文件名,兼容各种浏览器的写法 String fileName = tempArr2[1].substring(tempArr2[1].lastIndexOf("\\") + 1).replaceAll("\"", ""); return fileName; } private void uploadFile(Part part, String path) throws Exception { InputStream stream = null; OutputStream out = null; stream = part.getInputStream(); out = new FileOutputStream(path); int bytesRead = 0; byte[] buffer = new byte[8192]; while ((bytesRead = stream.read(buffer, 0, 8192)) != -1) { out.write(buffer, 0, bytesRead); } out.close(); stream.close(); } }
文件比较大
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。