springboot-内存中压缩zip文件夹

需求分析

1.有几个Excel文件,是通过Excel poi 读数据库生成的outputStream流文件,目标是将这几个output流文件,通过zip打成压缩包,通过servlet流,返回给浏览器,最终通过浏览器完成对压缩包的下载。

2.想要实现的是在内存中对文件进行压缩,而不生成实体文件。

解决方案

思路

首先,将创建的excel outputStream流放在字节数组中;

通过迭代,通过zip工具类,将字节数组传递给zipEntry,并给该文件文件名

最后将zipEntry放入到zipOutputStream中

note

1、zipOutputStream 是zip工具(java.util.zip.ZipOutputStream)中的一个类,接收ByteArrayOutputStream;

2、部分代码使用了 hutools包中的Excel库;

代码
part1:写入Excel 并转成字节流
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
ByteArrayOutputStream byteArrayInputStream = new ByteArrayOutputStream();
ExcelWriter writer = ExcelUtil.getWriter();
writer.addHeaderAlias("studentNumber", "学号");
writer.addHeaderAlias("studentName", "姓名");
writer.addHeaderAlias("examPaperId", "试卷编号");
writer.addHeaderAlias("questionBh", "题目编号");
writer.addHeaderAlias("questionName", "题目名称");
writer.addHeaderAlias("stage", "阶段");
writer.addHeaderAlias("questionDesc", "题目描述");
writer.addHeaderAlias("src", "学生代码");
writer.addHeaderAlias("score", "成绩");

result.add(ExcelSubmitModel.builder().score(Double.valueOf(examInfo.getExaminationScore())).build());
List<ExcelSubmitModel> rows = CollUtil.newArrayList(result);
writer.write(rows, true);
writer.flush(byteArrayInputStream, true);
writer.close();

首先,先声明一个ByteArrayOutputStream流,ExcelWriter是hutools中对Excel poi的封装,

writer.addHeaderAlias(“”,””)是添加JavaBean类中的字段和Excel中文标题的对应关系。

ExcelWriter支持将List写入Excel,writer.write(row,true)完成对Excel的写入,

writer.flush(byteArrayInputStream,true);可以将Excel写入ByteArrayOutputStream流,

writer.close() 关闭流。

part2 . 封装的zipUtil类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class ZipUtil {
public static ByteArrayOutputStream zip(HashMap<String, ByteArrayOutputStream> files, File tar) {
try {
ByteArrayOutputStream fileOutputStream = new ByteArrayOutputStream();
ZipOutputStream zipOutputStream = new ZipOutputStream(fileOutputStream);
Iterator maplist = files.entrySet().iterator();
while (maplist.hasNext()) {
Map.Entry<String, ByteArrayOutputStream> entry = (Map.Entry<String, ByteArrayOutputStream>) maplist.next();
ZipEntry zipEntry = new ZipEntry(entry.getKey());
zipOutputStream.putNextEntry(zipEntry);
zipOutputStream.write(entry.getValue().toByteArray());

}
zipOutputStream.close();
fileOutputStream.close();
return fileOutputStream;
} catch (Exception e) {
e.printStackTrace();
}
return null;

}
}

这个方法类,是接收一个HashMap<String,ByteArrayOutputStream>(Excel文件名,字节流),返回ByteArrayOutputStream 以便下一步的操作处理;

part3.将压缩后的字节流通过浏览器的response返回
1
2
3
4
5
ByteArrayOutputStream zip = ZipUtil.zip(excel, new File("d://test8.zip"));

response.setHeader("Content-Disposition", "attachment;filename="+ URLEncoder.encode( examDesc + "_学生提交记录.zip","utf-8"));
response.setContentType("application/zip");
response.getOutputStream().write(zip.toByteArray());
note

1、需要注意的部分是 如果返回的文件名中有中文,则需要 在resonse.setHeader()中,通过UrlEncoder.encode()来说明编码类型为utf-8

2、response可以接收的参数为 ByteArray;

3、整体思路 将文件转为ByteArrayOutputStream—>将ByteArrayOutputStream —>zipEntry—->zipzipOutputStream —>ByteArrayOutputStream—->byte[]


springboot-内存中压缩zip文件夹
http://yoursite.com/2019/08/18/springboot-内存中压缩zip文件夹/
作者
yangchen
发布于
2019年8月18日
许可协议