问题场景
在日常开发中, 数据导出遇到的情况不少, 但是基本都是单个文件导出. 本次项目开发中遇到需要批量导出的情况, 查找资料后功能基本实现, 先记录一下.
解决代码
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();
// 创建压缩文件内容实例
// 如果需要创建多个可多次putNextEntry
zos.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"))