字节流压缩ZIP包并下载"/>
Java实现字节流压缩ZIP包并下载
业务场景:系统有一个数据列表,用户点击某行下载按钮,系统可以将该行数据转化成WORD文档的形式供用户下载查看,这里直接用 XWPFTemplate 可以轻松实现,但是数据太多的情况下用户不可能每条数据都点击下载,不仅耗时而且会在浏览器下载非常多的文件,用户不好整理,体验感较差,于是有了新需求:用户可以多选数据行,然后系统压缩成一个ZIP包,所有文件都在ZIP包里,用户只需要下载一个ZIP即可。
简而言之,就是通过ZIP压缩包的形式实现批量下载
代码实现(只贴了核心代码):
1. 封装方法
public byte[] zipFile(List<DownloadFileDto> downloadFileDtoList) throws Exception {// 将字节写到一个字节输出流里ByteArrayOutputStream baos = new ByteArrayOutputStream();try (ZipOutputStream out = new ZipOutputStream(baos)) {// 创建zip file in memoryfor (DownloadFileDto downloadFileDto : downloadFileDtoList) {ZipEntry entry = new ZipEntry(downloadFileDto.getFileName());entry.setSize(downloadFileDto.getByteDataArr().length);out.putNextEntry(entry);out.write(downloadFileDto.getByteDataArr());out.closeEntry();}} catch (IOException e) {logger.error("压缩zip数据出现异常", e);throw new RuntimeException("压缩zip包出现异常");}return baos.toByteArray();}
2. 封装DTO
/*** @author YuePeng* @date 2022/12/22 11:52* 存放文件字节流和文件名*/
public class DownloadFileDto implements Serializable {private static final long serialVersionUID = 2648469408255550980L;// 存放文件名private String fileName = "";// 存放文件字节流private byte[] byteDataArr = new byte[0];public String getFileName() {return fileName;}public void setFileName(String fileName) {this.fileName = fileName;}public byte[] getByteDataArr() {return byteDataArr;}public void setByteDataArr(byte[] byteDataArr) {this.byteDataArr = byteDataArr;}@Overridepublic String toString() {return "DownloadFileDto{" +"fileName='" + fileName + '\'' +", byteDataArr=" + Arrays.toString(byteDataArr) +'}';}
}
3. Controller层
@ApiOperation(value = "批量下载", notes = "下载ZIP压缩包")@RequestMapping(value = "/downloadZip", method = RequestMethod.GET)public ResponseEntity downloadZip(@RequestParam List<String> ids, HttpServletResponse response) throws Exception {// ids即为前端传过来的的行数据id集合if (ids.isEmpty()) {return new ResponseEntity(HttpStatus.OK);}List<DownloadFileDto> downloadFileDtoList = new ArrayList<>();// 这里的i的作用是保证文件名唯一,否则往ZIP中添加文件会报异常int i = 1; for (String id : ids) {// 你的每一个文件字节流byte[] bytes = phvEquipReportService.downloadProveTable(id);String fileName = i + ".docx";DownloadFileDto dto = new DownloadFileDto();dto.setFileName(fileName);dto.setByteDataArr(bytes);downloadFileDtoList.add(dto);i++;}// FIXME 文件名最好为英文,中文的话下载的文件名会乱码,暂时未解决String fileName = "download.zip";response.reset();response.setCharacterEncoding("UTF-8");response.setContentType("application/octet-stream");response.setHeader("Content-Disposition", "attachment;filename=" + new String(fileName.getBytes(StandardCharsets.UTF_8), "ISO8859-1"));byte[] dataByteArr = new byte[0];if (CollectionUtils.isNotEmpty(downloadFileDtoList)) {try {dataByteArr = zipFile(downloadFileDtoList);response.getOutputStream().write(dataByteArr);response.flushBuffer();} catch (Exception e) {logger.error("压缩zip数据出现异常", e);return new ResponseEntity<>(HttpStatus.NO_CONTENT);}}return new ResponseEntity(dataByteArr, HttpStatus.OK);}
本文参考:java将字节数组写成zip文件,压缩字节数组成zip包并下载_秋冬将至的博客-CSDN博客
更多推荐
Java实现字节流压缩ZIP包并下载
发布评论