根据list数据,即时用jxl生成多个excel文件流,打包成zip

@ApiOperation(value = "static-pool/download/zip",notes = "批量导出某月的数据")
    @RequestMapping(value = "/static-pool/download/zip",method = RequestMethod.GET)
    public ResponseCommonType downloadZIP(String month,HttpServletResponse servletResponse) throws ParseException, IOException, WriteException {
        ResponseCommonType rs = new ResponseCommonType();
        rs.setIsSuccess(true);
        //获取开始时间为null,结束日期是月底的报告.按照生成时间降序
        List reportfileinfoList = fileService.selectFilesByMonth(month);
        //按照产品分组,只导出月底日期的最新那份
        Map> map = reportfileinfoList.stream().collect(Collectors.groupingBy(Reportfileinfo::getProductCode));
        //把文件名和byte[]封装到fileInfo对象
        List files = new ArrayList<>();
        //遍历每个产品的n个文件
        for (Map.Entry> entry : map.entrySet()) {
            List productFiles = entry.getValue();
            //只要最新一个,数据库中已经按照生成时间降序排序
            Reportfileinfo info = productFiles.get(0);
            String reportManageMongoKey = info.getReportManageMongoKey();
            //静态逾期
            List reportstaticallyoverdueList = new ArrayList<>();
            Reportbasicinfo rbi = null;
            Reportfileinfo rfi = null;
            List mongoByName = mongoService.findByName(reportManageMongoKey);
            List reportfileinfoByKey = exportToWordService.getReportfileinfoByKey(reportManageMongoKey);
            if (CollectionUtils.isEmpty(mongoByName)) {//MongoDB有数据
                rs.setIsSuccess(false);
                rs.setResponseMessage("MongoDB没有数据");
            }
            Manage manage = mongoByName.get(0);
            ManagementBodyModel managementBodyModel = JSON.parseObject(manage.getManageValue(), ManagementBodyModel.class);
            reportstaticallyoverdueList = managementBodyModel.getReportstaticallyoverdueList();
            rbi = managementBodyModel.getReportbasicinfo();
            rfi = reportfileinfoByKey.get(0);

            //根据字节输出流,创建一个workbook对象
            ByteOutputStream byteOutputStream = new ByteOutputStream();
            WritableWorkbook wbook = Workbook.createWorkbook(byteOutputStream);
            //设置excel数据和格式
            setExcelData(wbook, reportstaticallyoverdueList);
            wbook.write();
            wbook.close();
            byte[] bytes = byteOutputStream.getBytes();
            byteOutputStream.close();

            Calendar c = Calendar.getInstance();
            c.setTime(rfi.getGndDate());
            int monthV = c.get(Calendar.MONTH) + 1;
            String fileName = "【" + c.get(Calendar.YEAR) + "年" + monthV + "月】" + rbi.getTrustProductCode() + rbi.getProductShortName() + "项目静态池数据" + LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"))+".xls";
            FileInfo fileInfo = new FileInfo("", fileName, bytes);
            files.add(fileInfo);

            if (files == null) {
                rs.setIsSuccess(false);
                rs.setResponseMessage("没有获取到文件");
                return rs;
            }
        }

        String zipFileName = month.split("-")[0] + "年" + month.split("-")[1] + "项目静态池数据" + LocalDate.now().toString().replace("-", "") + ".zip";
        toZip_ByteArrayOutputStream(files, zipFileName, servletResponse);

        return rs;
    }

    private void setExcelData(WritableWorkbook wbook,List list) throws WriteException {
        // sheet名称
        WritableSheet wsheet = wbook.createSheet("静态池数据", 0);

        WritableCellFormat format1 = new WritableCellFormat();
        // 把水平对齐方式指定为居中
        format1.setAlignment(jxl.format.Alignment.CENTRE);
        // 把垂直对齐方式指定为居中
        format1.setVerticalAlignment(jxl.format.VerticalAlignment.CENTRE);
        format1.setBorder(Border.ALL, BorderLineStyle.THIN);

        NumberFormat nf = new NumberFormat("0.00");
        WritableCellFormat numberFormat = new WritableCellFormat(nf);
        // 把水平对齐方式指定为居中
        numberFormat.setAlignment(jxl.format.Alignment.CENTRE);
        // 把垂直对齐方式指定为居中
        numberFormat.setVerticalAlignment(jxl.format.VerticalAlignment.CENTRE);
        numberFormat.setBorder(Border.ALL, BorderLineStyle.THIN);

        //设置表格头
        wsheet.addCell(new Label(0, 0, "静态池", format1));
        wsheet.addCell(new Label(1, 0, "报告期末", format1));
        wsheet.addCell(new Label(2, 0, "静态池规模", format1));
        wsheet.addCell(new Label(3, 0, "静态池笔数", format1));
        wsheet.addCell(new Label(4, 0, "期末存续笔数", format1));
        wsheet.addCell(new Label(5, 0, "逾期1-30天金额", format1));
        wsheet.addCell(new Label(6, 0, "逾期31-60天金额", format1));
        wsheet.addCell(new Label(7, 0, "逾期61-90天金额", format1));
        wsheet.addCell(new Label(8, 0, "逾期90天+金额", format1));
        wsheet.addCell(new Label(9, 0, "M1逾期率", format1));
        wsheet.addCell(new Label(10, 0, "M2逾期率", format1));
        wsheet.addCell(new Label(11, 0, "M3逾期率", format1));
        wsheet.addCell(new Label(12, 0, "M3+逾期率", format1));
        //设置每列宽度
        wsheet.setColumnView(0, 8);
        wsheet.setColumnView(1, 8);
        wsheet.setColumnView(2, 15);
        wsheet.setColumnView(3, 10);
        wsheet.setColumnView(4, 12);
        wsheet.setColumnView(5, 15);
        wsheet.setColumnView(6, 15);
        wsheet.setColumnView(7, 15);
        wsheet.setColumnView(8, 15);
        wsheet.setColumnView(9, 15);
        wsheet.setColumnView(10, 15);
        wsheet.setColumnView(11, 15);
        wsheet.setColumnView(12, 15);
        //高度
        wsheet.setRowView(0, 500);

        for (int i = 0; i < list.size(); i++) {
            Reportstaticallyoverdue info = list.get(i);
            wsheet.addCell(new Label(0, 1 + i, info.getStaticPool(), format1));
            wsheet.addCell(new Label(1, 1 + i, info.getObservationMonth(), format1));
            wsheet.addCell(new Label(2, 1 + i, info.getStaticPoolScale()!=null?info.getStaticPoolScale().toString():"", format1));
            wsheet.addCell(new Label(3, 1 + i, info.getStaticPoolNumber() != null ? info.getStaticPoolNumber().toString() : "", format1));
            wsheet.addCell(new Label(4, 1 + i, info.getRemainingNum(), format1));
            wsheet.addCell(new Label(5, 1 + i, info.getOverdueM1Amount() != null ? info.getOverdueM1Amount().toString() : "", format1));
            wsheet.addCell(new Label(6, 1 + i, info.getOverdueM2Amount() != null ? info.getOverdueM2Amount().toString() : "", format1));
            wsheet.addCell(new Label(7, 1 + i, info.getOverdueM3Amount() != null ? info.getOverdueM3Amount().toString() : "", format1));
            wsheet.addCell(new Label(8, 1 + i, info.getOverdueM4Amount() != null ? info.getOverdueM4Amount().toString() : "", format1));
            wsheet.addCell(new Label(9, 1 + i, info.getM1() != null ? info.getM1().toString() : "", format1));
            wsheet.addCell(new Label(10, 1 + i, info.getM2() != null ? info.getM2().toString() : "", format1));
            wsheet.addCell(new Label(11, 1 + i, info.getM3() != null ? info.getM3().toString() : "", format1));
            wsheet.addCell(new Label(12, 1 + i, info.getM4() != null ? info.getM4().toString() : "", format1));
        }
    }





import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class ZIPUtil {
    /**
     * 批量文件流压缩
     * @author momo
     * @since 2018-8-9
     * @param files  被压缩压缩文件名, 被压缩的文件流
     * @throws IOException
     */
    public static void toZip_ByteArrayOutputStream(List files, String zipFileName, HttpServletResponse response) throws IOException {
        if (files == null) {
            return;
        }
        //1.创建字节数组输出流,用于返回压缩后的输出流字节数组
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        //2.创建压缩输出流
        ZipOutputStream zipOut = new ZipOutputStream(baos);

        //3.遍历要批量压缩的集合文件流
        ByteArrayInputStream bais = null;
        FileInfo fileInfo = null;
        String fileName = null;
        int temp = 0;
        for (int i = 0; i < files.size(); i++) {

            fileInfo = files.get(i);

            fileName = fileInfo.getFilename();

            //3.1将需要压缩的字节输出流,转为字节数组输入流,
            bais = new ByteArrayInputStream(fileInfo.getContent());

            //3.2设置ZipEntry对象,并对需要压缩的文件命名
            zipOut.putNextEntry(new ZipEntry(fileName));

            //3.3读取要压缩的字节输出流,进行压缩
            temp = 0;
            while ((temp = bais.read()) != -1) {
                zipOut.write(temp);    // 压缩输出
            }

            // 3.4关闭流
            bais.close();
        }

        zipOut.close();

        // 清空response
        response.reset();
        // 设置response的Header
        zipFileName = new String(zipFileName.getBytes("UTF-8"), "ISO-8859-1");
        response.addHeader("Content-Disposition", String.format("attachment; filename=\"%s\"", zipFileName));
        response.setContentType("application/octet-stream;charset=utf-8");
        OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
        response.setContentType("application/octet-stream");
        toClient.write(baos.toByteArray());
        toClient.flush();
        toClient.close();

        baos.close();// 关闭流
    }

}
核心代码:
//根据字节输出流,创建一个workbook对象
ByteOutputStream byteOutputStream = new ByteOutputStream();
WritableWorkbook wbook = Workbook.createWorkbook(byteOutputStream);
//设置excel数据和格式
setExcelData(wbook, reportstaticallyoverdueList);
wbook.write();
wbook.close();
byte[] bytes = byteOutputStream.getBytes();
byteOutputStream.close();

这样得到了一个带excel格式的字节输出流, 能得到其字节数组.

ZIPUtil类里,实现了根据byte[]数组,生成zip流,响应到浏览器端.  核心代码是:
//1.创建字节数组输出流,用于返回压缩后的输出流字节数组
ByteArrayOutputStream baos = new ByteArrayOutputStream();

步骤总结:

1.基于字节输出流ByteOutputStream,创建一个workbook对象

2.wbook.write();实现把wbook对象数据,更新到字节输出流

3.byteOutputStream对象.getBytes();得到字节输出流里的字节数组

4.根据字节数组打包成zip. (可以打包任何格式的文件)

     4.1

     4.2

 

PS:这里的FileInfo只是对文件id,文件名,文件内容字节数组的一个简单封装:

private String id;
private String filename;
private byte[] content;

 

你可能感兴趣的:(Java)