1.问题描述:按月导出,每天的人员考勤情况
分析:因为月份存在的天数不一样,所以导出的列也可能不一样,因为自己的项目环境目前仅支持导出时映射到同一个固定的实体类,所以列是固定的,当列不固定时,不是很好处理,所以直接使用原生代码处理了。
使用:
1.1 创建HSSFWorkbook对象(excel的文档对象)
// 创建HSSFWorkbook对象(excel的文档对象)
HSSFWorkbook wb = new HSSFWorkbook();
//建立新的sheet对象(excel的表单)
HSSFSheet sheet = wb.createSheet("月度考勤统计");
//设置缺省列高sheet.setDefaultColumnWidth(20);//设置缺省列宽
// sheet.setDefaultRowHeightInPoints(10);
1.2 构建行列数据
// 在sheet里创建第一行,参数为行索引(excel的行),可以是0~65535之间的任何一个
HSSFRow row1 = sheet.createRow(0);
// 创建单元格(excel的单元格,参数为列索引,可以是0~255之间的任何一个
HSSFCell row1Cell = row1.createCell(0);
// 设置单元格内容
row1Cell.setCellValue("月度汇总统计:" + firstDay.format(ymd) + " 至 " + lastDay.format(ymd));
// 获取当月的间隔天数
int daysBetween = DateUtils.daysBetween(Date.from(lastDay.atStartOfDay(ZoneId.systemDefault()).toInstant()), Date.from(firstDay.atStartOfDay(ZoneId.systemDefault()).toInstant())) + 1;
//合并单元格CellRangeAddress构造参数依次表示起始行,截至行,起始列, 截至列
sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, daysBetween));
// 第二行
HSSFRow row2 = sheet.createRow(1);
HSSFCell row2cell = row2.createCell(0);
row2cell.setCellValue("报表生成时间:" + DateUtils.formatDate(new Date(), "yyyy-MM-dd hh:mm"));
sheet.addMergedRegion(new CellRangeAddress(1, 1, 0, daysBetween));
1.3 创建表格的样式
// 设置样式一
HSSFCellStyle cellStyle = wb.createCellStyle();
// 居中展示
cellStyle.setAlignment(HorizontalAlignment.CENTER);
cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
//设置自动换行
cellStyle.setWrapText(true);
// 设置迟到早退样式
HSSFCellStyle cellStyleYe = wb.createCellStyle();
cellStyleYe.setAlignment(HorizontalAlignment.CENTER);
cellStyleYe.setVerticalAlignment(VerticalAlignment.CENTER);
//设置自动换行
cellStyleYe.setWrapText(true);
// 设置背景颜色颜色,颜色展示需要下面两行
cellStyleYe.setFillPattern(FillPatternType.SOLID_FOREGROUND);
cellStyleYe.setFillForegroundColor(IndexedColors.YELLOW.getIndex());
// 设置迟到缺卡,旷工缺卡 样式
HSSFCellStyle cellStyleRed = wb.createCellStyle();
cellStyleRed.setAlignment(HorizontalAlignment.CENTER);
cellStyleRed.setVerticalAlignment(VerticalAlignment.CENTER);
//设置自动换行
cellStyleRed.setWrapText(true);
// 设置颜色
cellStyleRed.setFillPattern(FillPatternType.SOLID_FOREGROUND);
cellStyleRed.setFillForegroundColor(IndexedColors.RED.getIndex());
注意:样式是某个表格cell中引用使用的!!!
1.4 根据数据动态构建表格数据
// 开始从第三行填充数据表头
HSSFRow row3 = sheet.createRow(2);
//创建单元格并设置单元格内容
row3.createCell(0).setCellValue("姓名");
for (int i = 1; i <= daysBetween; i++) {
// 创建天数列
HSSFCell cell = row3.createCell(i);
cell.setCellValue(i);
cell.setCellStyle(cellStyle);
}
// 遍历填充人员每月的数据
for (SysUser user : list) {
HSSFRow rowData = sheet.createRow(row);
rowData.setRowStyle(cellStyle);
rowData.createCell(0).setCellValue(user.getRealname());
row++;
for (int i = 1; i <= daysBetween; i++) {
if (RegisterStatusEnum.ABSENT.getValue().equals(atr.getRegisterStatus())) {
cell.setCellStyle(cellStyleRed);
cell.setCellValue("旷工");
} else if (RegisterStatusEnum.LEAVE_EARLY.getValue().equals(atr.getRegisterStatus())) {
cell.setCellStyle(cellStyleYe);
cell.setCellValue("早退" + "\r\n" + sdf.format(atr.getFirstOnRgTime()) + "-" + sdf.format(atr.getFirstOffRgTime()));
} else if (RegisterStatusEnum.LATE.getValue().equals(atr.getRegisterStatus())) {
cell.setCellStyle(cellStyleYe);
cell.setCellValue("迟到" + "\r\n" + sdf.format(atr.getFirstOnRgTime()) + "-" + sdf.format(atr.getFirstOffRgTime()));
} else {
cell.setCellValue("正常");
}
}
}
1.5 页面导出时,response返回
// 获取导出数据
HSSFWorkbook sheets = attendanceTimeRegisterService.exportStatisticsMonthAllUserByOrgNew(param, user);
// response写出
OutputStream outputStream = null;
try {
response.setContentType("application/x-msdownload;charset=utf-8");
String browse = BrowserUtils.checkBrowse(request);
String fileName = "考勤统计表";
if (StringUtils.isNotBlank(browse) && browse.length() > 4 && "MSIE".equalsIgnoreCase(browse.substring(0, 4))) {
response.setHeader("content-disposition", "attachment;filename=" + java.net.URLEncoder.encode(fileName, "UTF-8") + ".xls");
} else {
String newtitle = new String(fileName.getBytes("UTF-8"), "ISO8859-1");
response.setHeader("content-disposition", "attachment;filename=" + newtitle + ".xls");
}
OutputStream out = response.getOutputStream();
sheets.write(out);
response.flushBuffer();
} catch (Exception e) {
log.error("--通过流的方式获取文件异常--" + e.getMessage(), e);
} finally {
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
log.error(e.getMessage(), e);
}
}
}
1.6 效果展示
版本问题
我的环境是低版本,所以引用样式时,还是传统方式,