在javaweb中,使用ajax实现文件上传预览
1.表单:
-设置input type="file",multiple="multiple"可以选择多个文件,id是用来获取element,上面的hidden是用来保存字段值,即保存最终的文件名称,可能是多个
2.js:
<script type="text/javascript"> var inputEle = document.getElementById('file1'); inputEle.onchange = function (e) { var formData = new FormData(); for (var i = 0; i < this.files.length; i++) { var file = this.files[i]; console.log(file); formData.append('file', file); }; formData.append('eId', ${dInfo.enterpriseId}); // formData.append(其他参数) if(this.files.length > 0){ //有文件就call后台,没有就不call var type="handleagreementattachment"; var falg="fileFlag1"; fileUpload(formData,type,falg); } } //文件上传,call后台 function fileUpload(formData,type,flag) { $.ajax({ url: "${ctx}/file/fileUtil/FileUpload", type: 'POST', cache: false, processData: false, contentType: false, enctype:"multipart/form-data", dataType:"json", data: formData, async:false, error: function (request) { alert("服务器故障"); }, success: function (data) { console.log(data); //wasterwatermonitorattachment var fileValue = $("#"+ type +"").val(); for(var i=0;i<data.length;i++){ fileValue += data[i]["fileName"]+";"; //回显预览 var radom = Math.random().toString(36).substring(2); $("#"+ flag +"").append("<li id='"+ radom +"'><a href='"+ data[i]["fileAdd"]+data[i]["fileName"] +"' style='width:60px;' title="+ data[i]["fileName"] +">" + "<img src='${ctxStatic}/hb/fileimages/"+ data[i]["type"] +".png' alt='' style='margin-bottom: 10px'/><b>"+ data[i]["shortName"] +"</b></a>" + "<b style='color:red;cursor:pointer;' onclick=delFile('"+ radom +"','"+ data[i]["fileName"] +"','"+ type +"');>删除</b></li>"); } $("#"+ type +"").val(fileValue); } }); } //删除文件 function delFile(id,name,type) { var a = confirm("确认删除 " + name + " 吗?"); if(a==true){ var node = document.getElementById(id); node.remove(); //删除这个节点 var value = $("#"+ type +"").val(); //获取本来的字段值 value = value.replace(name+";",""); //删除其中的某个文件 $("#"+ type +"").val(value); //重新赋值 return true; }else{ return false; } } </script>
要注意这一块script要放到<body>的最下面,否则会导致 inputEle 获取不到element,因为页面没有加载完成;ajax call的时候只需要传递 formData 就可以了,我这边是业务需求所以多了几个对象。
3.java后台接收并处理文件,接收的时候可以debug一下,这里可以获取到很多的文件属性。我这边写了一个公用的后台,不管哪里使用,直接call这里就好了。
这里上传的文件可能是多个 MultiparFile[] 来接收文件参数,返回给前端的是一个文件对象的集合,业务需要,所以用文件对象来存储文件的各种属性。
package com.zhouhe.modules.myUtils; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletRequest; import java.util.List; /** * 文件上传 * @Author zhouhe * @Date 2019/12/5 13:07 */ @Controller @RequestMapping(value = "${adminPath}/file/fileUtil") public class FileController { /** * 文件上传,ajax 方式 * @param request * @param model * @param file * @return */ @ResponseBody @RequestMapping(value="/FileUpload", method = RequestMethod.POST) public List<FileEntity> FileUpload(HttpServletRequest request, Model model,@RequestParam(value="file",required=false) MultipartFile[] file) { // List<MultipartFile> files = ((MultipartHttpServletRequest) request).getFiles("file"); String eId = request.getParameter("eId"); //企业 id List<FileEntity> fileList = FileUpload.uploadFiles(file,eId); return fileList; } }
4.下面是调用文件上传Util
package com.zhouhe.modules.myUtils; import com.zhouhe.modules.api.util.Constants; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.multipart.MultipartFile; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; /** * 文件上传 ajax 方式 * @Author zhouhe * @Date 2019/12/5 13:12 */ public class FileUpload { private static Logger logger = LoggerFactory.getLogger(FileUpload.class); public static final String FILE_URL = Constants.LOCAL_FILE_URL; //本地路径 // public static final String FILE_URL = Constants.BASE_FILE_URL; //服务器部署路径 /** * 多个文件上传,循环调用单个文件上传的方法 * @param file * @param folder * @return */ public static List<FileEntity> uploadFiles(MultipartFile[] file,String folder){ String fileFolder = FILE_URL+ "ea/" + folder; //一起一档的文件目录是 基础目录 + ea + 企业id List<FileEntity> fileList = new ArrayList<FileEntity>(); File isFolder = new File(fileFolder); if (!isFolder.exists()) { isFolder.mkdirs(); } for(int i=0;i<file.length;i++){ fileList.add(uploadFile(file[i],fileFolder,folder)); } return fileList; } /** * 上传文件(单个) * 1.Constants.LOCAL_FILE_URL 是本地文件存储路径,部署要换成 Constants.BASE_FILE_URL * 2.jsp 表单提交的时候要设置 method="post" enctype="multipart/form-data" * 3.要在 springmvc 中有对上传文件的大小做限制 * 4.要考虑传递过来的是多个文件问题,暂时没有实现 * * @param upFile 页面传过来的文件 * @param fileFolder 上传文件的全路径 * @param folder 存储的文件夹 这里是企业id * @return 文件对象 */ public static FileEntity uploadFile(MultipartFile upFile,String fileFolder, String folder){ //定义返回对象,返回文件对象 FileEntity f = new FileEntity(); if (upFile.getSize() > 0) { // 得到文件的原始名称,如:美女.png String fileName = upFile.getOriginalFilename(); File file = new File(fileFolder,fileName); try { upFile.transferTo(file); //上传文件 String fileRoute = Constants.DOWNLOAD_URL +"ea/"+folder+"/"; //文件下载路径,服务器路径 f.setFileAdd(fileRoute); f.setFileName(fileName); //文件名 f.setShortName(shortName(fileName)); //文件缩略名 f.setSuffix(fileName.substring(fileName.lastIndexOf(".") + 1)); //后缀 f.setType(getType(fileName.substring(fileName.lastIndexOf(".") + 1))); //文件类型 return f; //返回文件对象 } catch (IOException e) { e.printStackTrace(); logger.debug("上传文件失败"); } } return null; } /** * 文件缩略名 * 保留4个字符,后面用 ... 代替 * @param name * @return */ public static String shortName(String name){ if(name.length() > 4){ String str = name.substring(4,name.length()); name = name.replace(str,"..."); } return name; } /** * 根据文件后缀判断文件类型 * @param name * @return */ public static String getType(String name){ if ("pdf".equals(name)) { return "pdf"; } else if ("excel".equals(name)) { return "excel"; } else if ("xls".equals(name)) { return "excel"; } else if ("xlsx".equals(name)) { return "excel"; } else if ("docx".equals(name)) { return "word"; } else if ("doc".equals(name)) { return "word"; } else if ("png".equals(name)) { return "png"; } else if ("jpg".equals(name)) { return "png"; } else if ("jpeg".equals(name)) { return "png"; } else if ("rar".equals(name)) { return "zip"; } else if ("ppt".equals(name)) { return "ppt"; } else if ("pptx".equals(name)) { return "ppt"; }else { return "txt"; } } }
5.文件属性类
package com.zhouhe.modules.myUtils; /** * 文件属性类 * @Author zhouhe * @Date 2019/12/3 16:17 */ public class FileEntity { private String fileName; //文件名称 private String shortName; //文件缩略名 private String fileAdd; //文件地址 private String suffix; //文件后缀 private String type; //文件类型 public String getShortName() { return shortName; } public void setShortName(String shortName) { this.shortName = shortName; } public String getType() { return type; } public void setType(String type) { this.type = type; } public String getFileName() { return fileName; } public void setFileName(String fileName) { this.fileName = fileName; } public String getFileAdd() { return fileAdd; } public void setFileAdd(String fileAdd) { this.fileAdd = fileAdd; } public String getSuffix() { return suffix; } public void setSuffix(String suffix) { this.suffix = suffix; } }
6.文件预览的话只需要把文件属性传递到页面即可