如上图所示,需要使用easyExcel动态导出上述表格并指定合并其中的单元格,日期是动态的,每个月不相同,直接上实现代码,以demo形式展现,更好理解
/**
* 考勤记录动态导出测试
*/
@GetMapping("/export_excel_test.do")
@ApiOperation(value = "考勤记录动态导出测试", httpMethod = "GET")
@CrossOrigin
public void attendRecordExcelOut(HttpServletResponse response) throws Exception{
modelService.testAttendRecordExcelOut(response);
}
public void testAttendRecordExcelOut(HttpServletResponse response) throws Exception{
DispatchAuditRecord auditRecord = new DispatchAuditRecord();
auditRecord.setAbsentTotal(1L);
auditRecord.setIllnessTotal(2L);
auditRecord.setMatrimonyTotal(3L);
auditRecord.setVisitFamilyTotal(4L);
auditRecord.setAnnualLeaveTotal(5L);
auditRecord.setWorkOvertimeTotal(6L);
auditRecord.setNightShiftTotal(7L);
auditRecord.setAttendDayTotal(8L);
auditRecord.setOperationDayTotal(9L);
List<DispatchAttendRecord> recordList = new ArrayList<>();
DispatchAttendRecord attendRecord = new DispatchAttendRecord();
attendRecord.setStaffName("张测试");
attendRecord.setPostName("岗位");
DispatchAttendStatus attendStatus1 = new DispatchAttendStatus();
attendStatus1.setDay("1");
attendStatus1.setAttendStatus("休息");
DispatchAttendStatus attendStatus2 = new DispatchAttendStatus();
attendStatus2.setDay("2");
attendStatus2.setAttendStatus("加班");
ArrayList<DispatchAttendStatus> attendStatuses = new ArrayList<>();
attendStatuses.add(attendStatus1);
attendStatuses.add(attendStatus2);
attendRecord.setList(attendStatuses);
attendRecord.setAbsent(1L);
attendRecord.setIllness(2L);
attendRecord.setMatrimony(3L);
attendRecord.setVisitFamily(4L);
attendRecord.setAnnualLeave(5L);
attendRecord.setWorkOvertime(6L);
attendRecord.setNightShift(7L);
attendRecord.setAttendDay(8L);
attendRecord.setOperationDay(9L);
recordList.add(attendRecord);
List<List<Object>> contents = generateContents(recordList,auditRecord);
List<List<String>> head = generateHead(recordList);
String fileName = String.valueOf(System.currentTimeMillis()/1000);
response.setContentType("application/octet-stream");
response.setCharacterEncoding("utf-8");
response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xls");
EasyExcel.write(response.getOutputStream())
.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
.head(head).sheet("考勤记录列表")
.doWrite(contents);
}
/**
* 生成动态表头
* @param recordList
* @return 数据结构 外面一层list是每一列的list,里面一层list是每一列对应的单元格的list
*/
private List<List<String>> generateHead(List<DispatchAttendRecord> recordList){
List<String> head1 = Arrays.asList("序号", "姓名", "职名或岗位");
List<List<String>> headList = new ArrayList<>();
for (String head : head1) {
List<String> inside = new ArrayList<>();
inside.add(head);
inside.add(head);
headList.add(inside);
}
DispatchAttendRecord record = recordList.get(0);
List<DispatchAttendStatus> list = record.getList();
for (DispatchAttendStatus day : list) {
List<String> inside = new ArrayList<>();
inside.add("日期");
inside.add(day.getDay());
headList.add(inside);
}
List<String> head3 = Arrays.asList("旷工", "病事", "婚产护丧","探亲","年休","加班","夜班","出勤天数","其中|高铁线作业天数");
for (String head : head3) {
List<String> inside = new ArrayList<>();
inside.add("各种情况统计汇总");
inside.add(head);
headList.add(inside);
}
return headList;
}
/**
* 组装数据
*/
private List<List<Object>> generateContents(List<DispatchAttendRecord> records,DispatchAuditRecord auditRecord) {
List<List<Object>> contents = new ArrayList<>();
// 将records转为导出需要的格式
for (int i = 0; i <= records.size(); i++) {
if (i < records.size()){
DispatchAttendRecord e = records.get(i);
// 手动按表格顺序写入
List<Object> nodes = new ArrayList<>();
// 序号
nodes.add(String.valueOf(i+1));
// 姓名
nodes.add(e.getStaffName());
// 职名或岗位
nodes.add(e.getPostName());
// 细分到每一日
List<DispatchAttendStatus> list = e.getList();
for (DispatchAttendStatus detail : list) {
nodes.add(detail.getAttendStatus());
}
//旷工
nodes.add(e.getAbsent());
//病事
nodes.add(e.getIllness());
//婚产护丧
nodes.add(e.getMatrimony());
//探亲
nodes.add(e.getVisitFamily());
//年休
nodes.add(e.getAnnualLeave());
//加班
nodes.add(e.getWorkOvertime());
//夜班
nodes.add(e.getNightShift());
//出勤天数
nodes.add(e.getAttendDay());
//其中|高铁线作业天数
nodes.add(e.getOperationDay());
contents.add(nodes);
}else {
//合计
DispatchAttendRecord e = records.get(i-1);
// 手动按表格顺序写入
List<Object> nodes = new ArrayList<>();
// 序号
nodes.add("合计");
// 姓名
nodes.add("");
// 职名或岗位
nodes.add("");
// 细分到每一日
List<DispatchAttendStatus> list = e.getList();
for (DispatchAttendStatus detail : list) {
nodes.add("");
}
//旷工
nodes.add(auditRecord.getAbsentTotal());
//病事
nodes.add(auditRecord.getIllnessTotal());
//婚产护丧
nodes.add(auditRecord.getMatrimonyTotal());
//探亲
nodes.add(auditRecord.getVisitFamilyTotal());
//年休
nodes.add(auditRecord.getAnnualLeaveTotal());
//加班
nodes.add(auditRecord.getWorkOvertimeTotal());
//夜班
nodes.add(auditRecord.getNightShiftTotal());
//出勤天数
nodes.add(auditRecord.getAttendDayTotal());
//其中|高铁线作业天数
nodes.add(auditRecord.getOperationDayTotal());
contents.add(nodes);
}
}
return contents;
}
将以上代码拷贝到idea中可以直接执行。替换掉其中的实体类,根据自己实际业务修改即可