使用Java导出压缩包文件

1,131 阅读2分钟

一.使用场景

生成多个excel文件打包压缩后导出压缩包。

二.解决方法探索

在面向百度(谷歌)编程之后的过程中发现大多数的解决方式都是先在本地建一个临时的文件夹,将每个excel放到这个文件夹中,全部添加完成后打包这个文件夹,再删除这个文件夹

看到这种解决方式,我觉得这种方式并不是很合适!我觉得会有更优雅的方式,在一番搜索之后,我发现了下面代码所展示的这种解决方式,并不需要创建中间过渡文件,直接打包压缩,非常感谢这位博主。

原博链接javaWeb导出POI创建的多个excel的压缩文件.

三.代码

@ResponseBody
    @RequestMapping(value = "/xxx")
    public BaseResp unDirectExport(Date date, HttpServletResponse response) throws Exception {
        String fileName = xxx;
        ResponseUtil.setMultipartHeader(response, fileName);
        List<T> list = xxxService.query(xx);
      
        //按某个条件分组
        Map<String, List<T>> map = list.stream().collect(Collectors.groupingBy(T::getXXX));
        exportExcel(response, map);
        return BaseResp.succResp();
    }

    private void exportExcel(HttpServletResponse response, Map<String, List<T>> map) throws IOException {
        //Excel sheet 标题
        String[] headers = {""};
        ServletOutputStream outputStream = response.getOutputStream();
        ZipOutputStream zipOutputStream = new ZipOutputStream(outputStream);
        try {
            map.forEach((k, v) -> {
                //新建一个Excel 并设置下sheet头
                HSSFWorkbook workbook = createExcelAndSetHeaders(headers, k);
                //向sheet中 继续填充对象的数据
                setSheetCellValue(workbook.getSheet(k), v);
                try {
                    //重点开始,创建压缩文件
                    ZipEntry zipEntry = new ZipEntry(k + ".xls");
                    zipOutputStream.putNextEntry(zipEntry);
                } catch (IOException e) {
                    logger.error("向XXX压缩包中添加Excel失败");
                    throw new Exception("向XXX压缩包中添加Excel失败");
                }
                try {
                    //写入一个压缩文件
                    workbook.write(zipOutputStream);
                } catch (IOException e) {
                    logger.error("向zipOutputStream中写入流数据失败");
                    throw new Exception("向zipOutputStream中写入流数据失败");
                }
            });
            zipOutputStream.flush();
        } catch (Exception e) {
            //重复丢出异常,有点多余,但是为了套上try catch finally 关闭数据流
            logger.error("导出XXX失败,原因" + e.getErrorCode());
            throw new Exception("导出XXX失败,原因:" + e.getErrorCode());
        } finally {
            //关闭数据流,注意关闭的顺序
            zipOutputStream.close();
            outputStream.close();
        }
    }

    private HSSFWorkbook createExcelAndSetHeaders(String[] headers, String sheetName) {
        HSSFWorkbook hssfWorkbook = new HSSFWorkbook();
        HSSFSheet hssfSheet = hssfWorkbook.createSheet(sheetName);
        HSSFRow row0 = hssfSheet.createRow(0);
        for (int i = 0; i < headers.length; i++) {
            HSSFCell cellHeader = row0.createCell(i);
            cellHeader.setCellValue(headers[i]);
        }
        return hssfWorkbook;
    }

    private void setSheetCellValue(HSSFSheet hssfSheet, List<T> dtos) {
        for (T dto : dtos) {
            //从当前sheet页的最后一行后新增一行,开始填充数据
            HSSFRow row = hssfSheet.createRow(hssfSheet.getLastRowNum() + 1);
            int count = -1;
            row.createCell(++count).setCellValue(dto.getXXX);
            row.createCell(++count).setCellValue(dto.getXXX);
            row.createCell(++count).setCellValue(dto.getXXX);
            row.createCell(++count).setCellValue(dto.getXXX);
            row.createCell(++count).setCellValuedto.getXXX);
        }
    }
import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

/**
 * @author zhaojq
 * @email zhaojq@tsintergy.com
 * @date 2019 2019/10/14 17:11
 */
public class ResponseUtil {

    private ResponseUtil() {
    }
    public static void setMultipartHeader(HttpServletResponse response, String fileName) 	{
        try {
            response.setCharacterEncoding("utf-8");
            response.setContentType("multipart/form-data");
            response.setHeader("Content-Disposition", "attachment;filename*=UTF-8''" + URLEncoder.encode(fileName, "UTF-8"));
        } catch (UnsupportedEncodingException e) {
            throw new BusinessException("文件名编码异常");
        }
    }
}