Java多文件生成并压缩下载功能(思路详解)
年前一直忙着项目现场实施,没时间整理,今天终于得空开始整理。
做WMS系统经常会遇到导出各种类型的库存单,此时就可以在后台将这些整合压缩到一个压缩包内然后再下载压缩包,一个接口就可以完成的事。
有两个思路:
思路一:将生成的多个文件先逐个存到本地一个临时的文件夹内并压缩,获取压缩文件下载,下载完以后删除该临时文件夹和内部文件 思路二:所有都在内存中实现,将生成的多个文件的输出流转换成为byte数组塞入压缩包的输出流中,最后下载该压缩包
第一个思路虽然操作复杂,但是却很容易想到的。
第二个思路,所有文件流都放在内存中操作,操作大大的简便了。本文将要讲述的就是此种方式。
controller层:
//思路二:所有都在内存中实现,将生成的多个文件的输出流转换成为byte数组塞入压缩包的输出流中,最后下载该压缩包 @RequestMapping("/zip/download2") public void downloadZip2(String name, HttpServletResponse httpResponse) { documentService.downloadReport(name, httpResponse); }
service层:
public void downloadReport(String name, HttpServletResponse httpResponse){ //使用EasyExcel生成excel表1 Map excelOut = exportExcel(name); //使用EasyExcel生成excel表2(同上) Map excelOut2 = exportExcel2(name); //将要压缩的文件塞到一个list里面 List<Map> fileList = new ArrayList(); fileList.add(excelOut); fileList.add(excelOut2); //压缩多个文件并下载 zipFiles(fileList,httpResponse); }
要养成一个良好的习惯,当一个方法中的代码量过于臃肿时候,要抽出来一部分生成一个新的方法来给调用。
//生成excel表格导出到本地 public Map exportExcel(String name) { List<User> userList = userDao.queryUsersByName(name); try (ByteArrayOutputStream out = new ByteArrayOutputStream()) { //使用easyExcel导出excel String excelFileName = "根据人名查询数据.xlsx"; ExcelWriter writer = new ExcelWriter(out, ExcelTypeEnum.XLSX, true); Sheet sheet = new Sheet(1, 0, User.class); //设置自适应宽度 sheet.setAutoWidth(Boolean.TRUE); writer.write(userList, sheet); writer.finish(); Map excelOut = new HashMap(); excelOut.put("fileName",excelFileName); excelOut.put("outByte",out.toByteArray()); return excelOut; } catch (Exception e) { log.error(e.getMessage(), e); } return null; }
//多个文件压缩成压缩包并下载 public void zipFiles(List<Map> fileList,HttpServletResponse httpResponse) { try(ZipOutputStream zipOutputStream = new ZipOutputStream(httpResponse.getOutputStream()); OutputStream out =null) { //下载压缩包 httpResponse.setContentType("application/zip"); httpResponse.setHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode("附件.zip", "UTF-8")); // 创建 ZipEntry 对象 for (Map map:fileList){ ZipEntry zipEntry = new ZipEntry((String) map.get("fileName")); zipOutputStream.putNextEntry(zipEntry); zipOutputStream.write((byte[]) map.get("outByte")); } } catch (IOException e) { log.error(e.getMessage(), e); } }
dao层就是简单的一个sql语句根据用户名称查询用户数据
如此便完成了多文件压缩并下载的功能,如下。
当然,思路一虽然复杂,但是对于新手同学我还是建议把思路一自己实现一下,其中对于文件IO的一些操作将会让你更加容易理解并吸收。