需求分析
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 并转成字节流
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<JavaBean>写入Excel,writer.write(row,true)完成对Excel的写入,
writer.flush(byteArrayInputStream,true);可以将Excel写入ByteArrayOutputStream流,
writer.close() 关闭流。
part2 . 封装的zipUtil类
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返回
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[]