前言
最近公司有一个项目有一个压缩文件然后下载的功能
背景是这样的,数据库中有很多文件,然后客户需要一个导出功能,然后导出选中某些范围的数据为excel,因为数据量比较大,一个文件可能不太行(全部导出大概有上千万数据)
所以需要对数据进行切割,切割成一个个的小文件,但是又不能一个一个的去下载,那也太乱了,所以就需要将查询出来的数据写成excel然后再把这些文件压缩成zip,最后用户下载到手的是一个zip文件
一开始是这样做的,导出excel使用的是easyExcel,先把数据切割后一个一个的下载到服务器本地,然后把这些文件通过zip流压缩成一个zip文件,最后给用户下载后再把这些文件删掉
但是这样是极度不合理的,所有在我仔细查看了Java和EasyExcel的文档以及百度了半天之后,找到了下面的方法
代码
/**
* @author ZhongJing </p>
* @date 2022/10/23 </p>
*/
@RestController
public class FileDownload {
private Person[] persons = {
new Person("张三", 18, "男"),
new Person("李四", 22, "女"),
new Person("王五", 32, "男"),
new Person("赵六", 42, "女"),
new Person("田七", 67, "男"),
};
@GetMapping(value = "/hello")
public String hello() {
return "hello";
}
@GetMapping(value = "/test")
public void downloadZipFile(HttpServletResponse response) {
ServletOutputStream sos = null;
ZipOutputStream zos = null;
try {
// 从response获取输出流
sos = response.getOutputStream();
// Zip输出流
zos = new ZipOutputStream(sos);
for (int i = 0; i < persons.length; i++) {
// 假装这个p是从数据库取出的数据
Person p = persons[i];
// 确定导出excel的后缀格式
ExcelWriter excelWriter = EasyExcel.write().excelType(ExcelTypeEnum.XLSX).build();
// 确定sheet,我不咋用excel,我不知道这个玩意儿是啥
WriteSheet writeSheet = EasyExcel.writerSheet("人员信息").build();
// 参数是要求一个集合,方便演示我们是一个对象,如果是业务场景,直接一个集合就更方便了
ArrayList<Person> list = new ArrayList<>();
list.add(p);
// 把集合数据写到这个sheet里,也就是绑定sheet和write的关系
excelWriter.write(list, writeSheet);
// 创建一个zip实体,其实就是表示压缩文件里的一个文件
ZipEntry zipEntry = new ZipEntry("表格" + i + ".xlsx");
// 把这个zip实体添加到压缩流中
zos.putNextEntry(zipEntry);
// Workbook这是poi里的一个东西,具体的可以自己百度看看什么意思
Workbook workbook = excelWriter.writeContext().writeWorkbookHolder().getWorkbook();
// 把当前的内容写到zip流里面
workbook.write(zos);
}
zos.flush();
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
try {
assert zos != null;
zos.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
sos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
测试
当我们通过localhost:8080/test的url请求下载后,下载到test.zip这个文件
打开里面是这样的
可以看到,确实是没有问题的,这样就不需要用之前的笨办法一个一个导出成excel然后再压缩再下载啦~