一、前言
有个统计功能一直是人工操作,提需求要实现按照日期分组动态导出。效果图如下
其中上报时间要按照数据分批导出。
我:把时间当做单独一列字段放到每个数据里不行吗?
产品:NO!
没办法,开搞吧。
二、依赖
选用easyexcel
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.1.0</version>
</dependency>
三、代码实现
Excel导出不难,主要是指定要求按照日期分表头导出,这肯定就需要做动态表头了。实现代码如下:
表头字段需要嵌套list去实现,另外一些细节问题在备注中已经标注了,注意取数据先在sql中排好序。
public static void main(String[] args) {
String fileName = "D:/WorkSpace/" + "write" + System.currentTimeMillis() + ".xlsx";
ExcelWriter excelWriter = EasyExcel.write(fileName).build();
List<List<String>> header = new ArrayList<>();
//加一个公共表头 因为一个header一个单元格所以加五个
header.add(Collections.singletonList("日志上报情况"));
header.add(Collections.singletonList("日志上报情况"));
header.add(Collections.singletonList("日志上报情况"));
header.add(Collections.singletonList("日志上报情况"));
header.add(Collections.singletonList("日志上报情况"));
WriteSheet writeSheet = EasyExcel.writerSheet("sheet").needHead(Boolean.TRUE).head(header).build();
// 表头的数量
int num = 0;
List<List<NoRegisterReportDO>> lists = listHandle(buildBody());
// 遍历 按照上报时间
for (List<NoRegisterReportDO> list :lists) {
//这里生成的是字段名的表头
List<List<String>> contentHeader = buildHeader(list);
//生成每组数据的动态表头 加入时间
List<List<String>> nameHeader = contentHeader.stream().map(item -> Collections.singletonList("上报时间"+list.get(0).getAccessdate())).collect(Collectors.toList());
// 这里必须指定需要头
// 第一次写入会创建头
WriteTable writeTable0 = EasyExcel.writerTable(num).needHead(Boolean.TRUE).head(nameHeader).build();
excelWriter.write((Collection<?>) null, writeSheet, writeTable0);
WriteTable writeTable1 = EasyExcel.writerTable(num + 1).needHead(Boolean.TRUE).head(contentHeader).build();
excelWriter.write(list, writeSheet, writeTable1);
// 插入两次表头加2
num = num + 2;
}
excelWriter.finish();
}
/**
* 组装表头字段
* @param list
* @return
*/
public static List<List<String>> buildHeader(List<NoRegisterReportDO> list) {
List<List<String>> header = new ArrayList<>();
// header.add(Collections.singletonList("上报日期"));
header.add(Collections.singletonList("市"));
header.add(Collections.singletonList("县(市、区)"));
header.add(Collections.singletonList("是否上报"));
header.add(Collections.singletonList("是否补报"));
header.add(Collections.singletonList("备注"));
return header;
}
/**
* 造数据
* @return
*/
public static List<NoRegisterReportDO> buildBody() {
NoRegisterReportDO vo = new NoRegisterReportDO();
NoRegisterReportDO vo1 = new NoRegisterReportDO();
NoRegisterReportDO vo2 = new NoRegisterReportDO();
vo.setIssue("20230601");
vo.setSjmc("石家庄市");
vo.setRemark("remark");
vo.setAccessdate("20230523");
vo.setXzqmc("桥西");
vo.setComplementReportFlag("是");
vo.setSubmitReportFlag("否");
vo1.setSubmitReportFlag("否");
vo1.setComplementReportFlag("是");
vo1.setSjmc("唐山市");
vo1.setIssue("20230601");
vo1.setAccessdate("20230524");
vo1.setRemark("remark");
vo1.setXzqmc("桥西");
vo2.setSubmitReportFlag("否");
vo2.setComplementReportFlag("是");
vo2.setSjmc("唐山市");
vo2.setIssue("20230601");
vo2.setAccessdate("20230525");
vo2.setRemark("remark");
vo2.setXzqmc("桥西");
List<NoRegisterReportDO> list = new ArrayList<>();
list.add(vo);
list.add(vo1);
list.add(vo2);
return list;
}
/**
* 根据accessdate/上报时间区分不同上报日期数据
* @param list
* @return
*/
public static List<List<NoRegisterReportDO>> listHandle(List<NoRegisterReportDO> list){
List<List<NoRegisterReportDO>> info = list.stream()
//默认hashmap 无序,需要设置有序map
.collect(Collectors.groupingBy(NoRegisterReportDO::getAccessdate,LinkedHashMap::new, Collectors.toList()))
.values().stream().collect(Collectors.toList());
return info;
}