文件上传(Sevlet3.0之前)
1 2 3 4 5 6 7 8 <form action ="${pageContext.request.contextPath}/user/insertOrUpdate" method ="POST" enctype ="multipart/form-data" > <input type ="hidden" name ="id" value ="${user.id }" > <p > 姓名<input type ="text" name ="name" value ="${user.name }" > </p > <p > 头像<img src ="${user.headImage }" > 上传<input type ="file" name ="pic" > </p > <p > 年龄<input type ="text" name ="age" value ="${user.age }" > </p > <p > 生日<input type ="text" name ="bornDate" value ='<fmt:formatDate value="${user.bornDate }" pattern="yyyy-MM-dd"></fmt:formatDate>' > </p > <input type ="submit" value ="${empty user.id ? '添加' : '提交' }" > </form >
导入 jar 包:commons-fileupload
、commons-io
配置 mvc.xml
1 2 3 4 5 6 7 <bean id ="multipartResolver" class ="org.springframework.web.multipart.commons.CommonsMultipartResolver" > <property name ="maxUploadSize" > <value > 1048576</value > </property > </bean >
CommonsMultipartResolver 的 id名是固定的
如何使用:Controller
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 @RequestMapping ("insertOrUpdate" )public String insertOrUpdate (User user, MultipartFile pic) throws IOException { user = handleHeadPic(user, pic); if (user.getId() != null ) { service.update(user); } else { service.save(user); } return "redirect:/user/list" ; } private User handleHeadPic (User user, MultipartFile pic) throws IOException { String baseDir = context.getRealPath("/" ); String uploadDir = "/upload/" ; if (user.getId() != null ) { deleteUserHeadImgFile(user); } String uuid = UUID.randomUUID().toString(); String filename = uuid + "." + FilenameUtils.getExtension(pic.getOriginalFilename()); String headImgUrl = uploadDir + filename; Files.copy(pic.getInputStream(), Paths.get(baseDir, headImgUrl)); user.setHeadImage(headImgUrl); return user; } private void deleteUserHeadImgFile (User user) { String baseDir = context.getRealPath("/" ); String uploadDir = "/upload/" ; User oldUser = service.get(user.getId()); String oldImageUrl = oldUser.getHeadImage(); System.out.println(Paths.get(baseDir, uploadDir)); if (StringUtil.isNotEmpty(oldImageUrl)) new File(baseDir + oldImageUrl).delete(); }
文件上传(Servlet3.0之后)
不需要在导入 commons-fileupload
mvc.xml
1 <bean id ="multipartResolver" class ="org.springframework.web.multipart.support.StandardServletMultipartResolver" />
需要在 web.xml 中配置 multipart-config。 对应的的表单提交的类型 multipart/form-data
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <servlet > <servlet-name > springDispatcherServlet</servlet-name > <servlet-class > org.springframework.web.servlet.DispatcherServlet</servlet-class > <init-param > <param-name > contextConfigLocation</param-name > <param-value > classpath:mvc.xml</param-value > </init-param > <load-on-startup > 1</load-on-startup > <multipart-config > <max-file-size > 1048576</max-file-size > <max-request-size > 1048576</max-request-size > <file-size-threshold > 10240</file-size-threshold > </multipart-config > </servlet >
即可使用,使用方式与3.0之前一样
Controller.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 @RequestMapping ("/insertOrUpdate" )public String insertOrUpdate (Model model, User user, MultipartFile pic) throws IOException { String baseDir = context.getRealPath("/" ); String newUrl = getHeadImageUrlWithPic(pic); String oldUrl = user.getHeadImg(); if (pic.getSize() > 0 ) { user.setHeadImg(newUrl); } if (user.getId() != null ) { service.update(user); } else { service.insert(user); } Files.copy(pic.getInputStream(), Paths.get(baseDir, user.getHeadImg())); return "redirect:/user/list" ; } private void deleteImageByUrl (String imageUrl) { String baseDir = context.getRealPath("/" ); new File(baseDir + imageUrl).delete(); } private String getHeadImageUrlWithPic (MultipartFile pic) throws IOException { String uploadDir = "/uploads/" ; String uuid = UUID.randomUUID().toString(); String filename = uuid + "." + FilenameUtils.getExtension(pic.getOriginalFilename()); String headImageUrl = uploadDir + filename; return headImageUrl; }
文件下载
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 @RequestMapping ("/download" )public ResponseEntity<byte []> downloadFile(@PathVariable String fileName, HttpServletRequest request) throws Exception { fileName = fileName + ".xls" ; String realPath = context.getRealPath("/" ) + "/" + fileName; File file = new File(realPath); HttpHeaders headers = new HttpHeaders(); headers.setContentDispositionFormData("attachment" , encodeChineseDownloadFileName(request, fileName)); headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); return new ResponseEntity<byte []>(FileUtils.readFileToByteArray(file), headers, HttpStatus.OK); } private String encodeChineseDownloadFileName (HttpServletRequest request, String fileName) throws UnsupportedEncodingException { String resultFileName = "" ; String agent = request.getHeader("User-Agent" ).toUpperCase(); if (null == agent) { resultFileName = fileName; } else { if (agent.indexOf("FIREFOX" ) != -1 || agent.indexOf("CHROME" ) != -1 ) { resultFileName = new String(fileName.getBytes("UTF-8" ), "iso-8859-1" ); } else { resultFileName = URLEncoder.encode(fileName, "UTF-8" ); resultFileName = StringUtils.replace(resultFileName, "+" , "%20" ); } } return resultFileName; }
应用
上传下载头像
数据库字段 head_img 保存用户头像的 url 连接。
显示头像,直接加载对应的路径,<img id="headImg" height="50px" src='${not empty emp.headImage ? emp.headImage : "/uploads/default.jpg"}'></p>
新增上传头像:保存头像
更新头像:删除旧的头像,保存头像
流程, 保存图片 下面的代码保证上传新的图片后,会显示出来。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 function changImg (e ) { for (var i = 0 ; i < e.target.files.length; i++) { var file = e.target.files.item(i); if (!(/^image\/.*$/i .test(file.type))) { continue ; } var freader = new FileReader(); freader.readAsDataURL(file); freader.onload = function (e ) { $("#headImg" ).attr("src" , e.target.result); } } } <form class ="form-horizontal" action="/employee/insertOrUpdate" method="post" id="editForm" enctype="multipart/form-data" > <div class ="form-group" > <label class ="col-sm-2 control-label" >头像:</label> <div class="col-sm-6"> <p><img id="headImg" height="50px" src='${not empty emp.headImage ? emp.headImage : "/u ploads/default .jpg"}'></p> <input type=" file" class=" form-control" name=" pic" accept=" image
首先,form 表单必须使用 multipart/form-data
提交。
后台代码:使用 MultipartFile 来接收文件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 @RequestMapping ("/insertOrUpdate" )@RequiresPermissions (value = {"Employee:insertOrUpdate" , "员工更新" }, logical = Logical.OR)@ResponseBody public JsonResult insertOrUpdate (Model model, Employee e, MultipartFile pic, Long deptId, Long[] ids) throws IOException { JsonResult jsonResult = new JsonResult(); if (e.isAdmin() == false && (ids == null || ids.length == 0 )) { return jsonResult.mark("没有选择角色" ); } String newHeadImageUrl = null ; String oldHeadImageUrl = e.getHeadImage(); if (Optional.ofNullable(pic).filter(p -> p.getSize() > 0 ).isPresent()) { newHeadImageUrl = getHeadImageUrlWithPic(pic); e.setHeadImage(newHeadImageUrl); } try { Department dept = new Department(); dept.setId(deptId); e.setDept(dept); employeeService.save(e, ids); List<String> permissions = permissionService.getsExpressionsByEmpId(e.getId()); Employee currentEmp = (Employee) SecurityUtils.getSubject().getPrincipal(); if (currentEmp != null && currentEmp.getId() == e.getId()) { crmRealm.clearCache(); } if (newHeadImageUrl != null ) { if (oldHeadImageUrl != null ) { deleteImageByUrl(oldHeadImageUrl); } Files.copy(pic.getInputStream(), Paths.get(context.getRealPath("/" ), e.getHeadImage())); } return jsonResult; } catch (Exception e1) { return jsonResult.mark(e1.getMessage()); } } private void deleteImageByUrl (String imageUrl) { String baseDir = context.getRealPath("/" ); new File(baseDir + imageUrl).delete(); } private String getHeadImageUrlWithPic (MultipartFile pic) throws IOException { String uploadDir = "/uploads/" ; String uuid = UUID.randomUUID().toString(); String filename = uuid + "." + FilenameUtils.getExtension(pic.getOriginalFilename()); String headImageUrl = uploadDir + filename; return headImageUrl; }
导入、导出(excel)
首先不要忘记继承文件下载相关环境。然后下面是需求分析
面向对象的思想,每一个层级,都应该是一个对象
导出步骤:
查询所有员工
将员工数据写到 excel 文件中
创建工作薄
new HSSFWorkbook() 创建的是 xls,2003版本的
new XSSFWorkbook() 创建的是 xlsx,2007版本的
创建纸张
为每个员工创建行
在行中添加单元格
为单元格设置数据
导入 jar 包
1 2 3 4 5 6 <dependency > <groupId > org.apache.poi</groupId > <artifactId > poi</artifactId > <version > 3.17</version > </dependency >
导出
相当于文件下载功能,下载 excel。
1 2 3 4 5 6 7 8 9 10 11 $('.btn-export' ).click(function ( ) { let link = document .createElement('a' ); link.href = '/employee/exportXls?' + $('#searchForm' ).serialize() link.target = '_blank' link.click() $(link).remove() }) <button type="button" class ="btn btn-warning btn-export" > <span class ="glyphicon glyphicon-export" ></span > 导出 </button>
思路,创建 a 标签完成下载,拼接参数。
employeeController.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 @RequestMapping ("/exportXls" )@RequiresPermissions (value = {"Employee:exportXls" , "员工导出" }, logical = Logical.OR)public void exportXls (Model model, QueryEmployee qe, HttpServletResponse resp) throws IOException { resp.setHeader("Content-Disposition" ,"attachment;filename=employee.xls" ); qe.setDeptId(Optional.ofNullable(qe.getDeptId()) .filter(s -> s.intValue() > 0 ).orElse(null )); Workbook book = employeeService.exportXls(qe); book.write(resp.getOutputStream()); }
employeeServiceImpl.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 @Override public Workbook exportXls (QueryEmployee qe) { List<Employee> employees = employeeMapper.selectAll(qe); HSSFWorkbook book = new HSSFWorkbook(); HSSFSheet sheet = book.createSheet("员工信息" ); HSSFRow header = sheet.createRow(0 ); header.createCell(0 ).setCellValue("用户名" ); header.createCell(1 ).setCellValue("邮箱" ); header.createCell(2 ).setCellValue("年龄" ); for (int i = 0 ; i < employees.size(); i++) { HSSFRow row = sheet.createRow(i + 1 ); row.createCell(0 ).setCellValue(employees.get(i).getName()); row.createCell(1 ).setCellValue(employees.get(i).getEmail()); row.createCell(2 ).setCellValue(employees.get(i).getAge()); } return book; }
导入(excel)
导入步骤:
将员工数据写到 excel 文件中
上传 excel
根据 excel file 获取工作薄
获取纸张
获取行
遍历行,获取行中的单元格
创建员工对象,设置单元格中的值,然后插入数据
一般会给定一个模板文件,然后下载模板文件,填写数据之后,再导入。 导入模态框
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 $('.btn-import' ).click(function ( ) { $('#editModal' ).modal() }) $('.btn_save' ).click(function ( ) { $('#editForm' ).submit() }) $('#editForm' ).ajaxForm(function (data ) { $('#editModal' ).modal('hide' ) if (data.success) { $.messager.confirm("温馨提示" , "导入成功" , function ( ) { $('#searchForm' ).submit(); }) } else { $.messager.alert("温馨提示" , "导入失败" ) } }) body ... body <#--导入模态框--> <div class ="modal fade" id="editModal" > <div class ="modal-dialog" > <div class ="modal-content" > <div class ="modal-header" > <button type="button" class ="close" data-dismiss="modal" aria-label="Close" ><span aria-hidden ="true" > ×</span > </button> <h4 class="modal-title">员工导入</ h4> </div> <div class="modal-body"> <form class="form-horizontal" action="/ employee/importXls" method=" post" id=" editForm" enctype=" multipart/form-data"> <div class=" form-group"> <div class=" col-sm-6 "> <input type=" file" name=" file" accept=" application/vnd.ms-excel"><br/> <a href=" /template/employee_import.xls" class=" btn btn-success"> <span class=" glyphicon glyphicon-download-alt"></span> 下载模板 </a> </div> </div> </form> </div> <div class=" modal-footer"> <button type=" button" class=" btn btn-primary btn_save">保存</button> <button type=" button" class=" btn btn-default " data-dismiss=" modal">取消</button> </div> </div> </div> </div>
EmployeeController.java
1 2 3 4 5 6 7 8 9 10 11 @RequestMapping ("/importXls" )@ResponseBody public JsonResult importXls (Model model, MultipartFile file) { JsonResult jsonResult = new JsonResult(); try { employeeService.importXls(file); return jsonResult; } catch (Exception e) { return jsonResult.mark("上传失败" ); } }
EmployeeServiceImpl.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 @Override public void importXls (MultipartFile file) throws IOException { HSSFWorkbook book = new HSSFWorkbook(file.getInputStream()); HSSFSheet sheet = book.getSheet("员工信息" ); for (int i = 0 ; i < sheet.getLastRowNum(); i++) { HSSFRow row = sheet.getRow(i + 1 ); String name = row.getCell(0 ).getStringCellValue(); String email = row.getCell(1 ).getStringCellValue(); int age = Integer.parseInt(row.getCell(2 ).getStringCellValue()); Employee employee = new Employee(); Department department = new Department(); department.setId(2l ); employee.setDept(department); employee.setName(name); String password = new Md5Hash("1" , name).toString(); employee.setPassword(password); employee.setEmail(email); employee.setAge(age); employeeMapper.insert(employee); } }