问题场景
在日常开发中, 数据导出遇到的情况不少, 但是基本都是单个文件导出. 本次项目开发中遇到需要批量导出的情况, 查找资料后功能基本实现, 先记录一下.
解决代码
public void getFile(String fileName, String time, HttpServletResponse response) {response.setContentType("application/octet-stream");response.setHeader("Content-Disposition", "attachment; filename=" + fileName + ".zip");byte[] buff = new byte[1024];// 创建缓冲输入流OutputStream outputStream = null;List<SysTempFilePo> pos = tempFileService.list(new QueryWrapper<SysTempFilePo>().eq("time", time));Assert.notEmpty(pos, "服务器找不到上传的文本内容, 请重试");try {// 创建ByteArrayOutputStream 存储压缩流,后期用于读出压缩文件流内容ByteArrayOutputStream bos = new ByteArrayOutputStream();// 创建ZipOutputStream 用于生成压缩文件流ZipOutputStream zos = new ZipOutputStream(bos);for (SysTempFilePo po : pos) {String html = po.getHtml();String css = po.getCss();String name = po.getName();// 创建压缩文件内容实例// 如果需要创建多个可多次putNextEntryzos.putNextEntry(new ZipEntry("/" + name + "/" + name + ".vue"));// 读取文件内容,并将文件内容放到压缩流中zos.write(html.getBytes(Charsets.UTF_8));zos.putNextEntry(new ZipEntry("/" + name + "/" + name + ".css"));zos.write(css.getBytes(Charsets.UTF_8));}// 切记要先关闭流,不然后续无法获取压缩流内容zos.close();// 获取压缩字节流byte[] zipBytes = bos.toByteArray();outputStream = response.getOutputStream();outputStream.write(zipBytes);outputStream.flush();} catch (IOException e) {// 出现异常返回给页面失败的信息log.error(e.getMessage(), e);} finally {if (outputStream != null) {try {outputStream.close();} catch (IOException e) {log.error(e.getMessage(), e);}}}
测试结果
注意点
在使用压缩流写文件时候,如果需要展示文件层级关系或者指定文件夹, 可以在给文件命名时使用’/‘拼接即可. 如
zos.putNextEntry(new ZipEntry("/" + name + "/" + name + ".css"))
