![在这里插入图片描述](https://img-blog.csdnimg.cn/704689e5702a4d77aceba5f9151a4f85.png)
依赖
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.1.2</version>
</dependency>
工具类
@Data
@Slf4j
public class ExcelExportUtil {
private static final Logger log = LoggerFactory.getLogger(ExcelExportUtil.class);
private List<String> headList;
private List<String> headKey;
private List<Integer> headWidth;
private List<HashMap> data;
private List<HashMap<String,String>> cellStyleList;
private Map<String, CellStyle> styles;
private int fontSize = 14;
private int rowHeight = 30;
private int columWidth = 200;
private String sheetName = "sheet";
private String fileName;
HSSFWorkbook wb;
HSSFSheet sheet;
HSSFCellStyle headCellStyle;
HttpServletResponse response;
public ExcelExportUtil() {
this.wb = new HSSFWorkbook();
}
public ExcelExportUtil exportExport(HttpServletResponse response) throws IOException {
this.response = response;
int size = data.size();
int count = (size - 1) / 50000 + 1;
for (int i = 0; i < count; i++) {
sheet = wb.createSheet(sheetName + (i + 1));
exportExport(sheet,
data.subList(i * 50000, ((i + 1) * 50000 > size ? size : 50000 * (i + 1))));
}
return this;
}
private void exportExport(HSSFSheet sheet, List<HashMap> data) throws IOException{
checkConfig();
HSSFCellStyle cellStyle = wb.createCellStyle();
HSSFDataFormat format = wb.createDataFormat();
cellStyle.setDataFormat(format.getFormat("@"));
cellStyle.setAlignment(HorizontalAlignment.RIGHT);
HSSFRow headRow = sheet.createRow(0);
for (int i = 0; i < headList.size(); i++) {
Integer width = 15;
if (headWidth != null && headWidth.size() >= headList.size()){
width = headWidth.get(i);
}
sheet.setColumnWidth(i, 256 * width + 184);
HSSFCell cellHead = headRow.createCell(i);
cellHead.setCellValue(headList.get(i));
cellHead.setCellStyle(headCellStyle);
}
int a = 1;
for (int i = 0; i < data.size(); i++) {
HSSFRow row = sheet.createRow(a);
HashMap map = data.get(i);
HashMap styleMap = cellStyleList.get(i);
HSSFCell cell;
for (int j = 0; j < headKey.size(); j++) {
cell = row.createCell(j);
Object valueObject = map.get(headKey.get(j));
if (valueObject == null) {
valueObject = "";
}
if (valueObject instanceof Integer) {
cell.setCellValue(((Integer) (valueObject)).floatValue());
cell.setCellType(CellType.NUMERIC);
} else if (valueObject instanceof BigDecimal) {
cell.setCellValue(((BigDecimal) (valueObject)).floatValue());
cell.setCellType(CellType.NUMERIC);
} else if (valueObject instanceof Double) {
cell.setCellValue((Double) valueObject);
cell.setCellType(CellType.NUMERIC);
}else {
cell.setCellValue(StringUtils.isEmpty(String.valueOf(valueObject)) ? "" : String.valueOf(valueObject));
}
if(styleMap.get(headKey.get(j))!=null){
cell.setCellStyle(styles.get(styleMap.get(headKey.get(j))));
}else{
cell.setCellStyle(cellStyle);
}
}
a++;
}
}
public void flushExplorer() throws Exception{
response.setHeader("content-Type", "application/vnd.ms-excel");
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName + ".xls", "utf-8"));
try {
wb.write(response.getOutputStream());
}
catch (Exception e)
{
log.error("导出Excel异常{}", e.getMessage());
throw new UtilException("导出Excel失败,请联系网站管理员!");
}
finally
{
IOUtils.closeQuietly(wb);
}
}
public HSSFCellStyle getHSSFCellStyle(){
return wb.createCellStyle();
}
protected void checkConfig() throws IOException {
if (headKey == null) {
throw new IOException("表头不能为空");
}
if (headWidth != null && headWidth.size() < headKey.size()){
throw new IOException("设置宽度的列数必须超过表头列数");
}
if (fontSize < 0 || rowHeight < 0 || columWidth < 0) {
throw new IOException("字体、宽度或者高度不能为负值");
}
if (StringUtils.isEmpty(sheetName)) {
throw new IOException("工作表表名不能为NULL");
}
createDefaultHeadStyle();
}
public void createDefaultHeadStyle() {
headCellStyle= wb.createCellStyle();
headCellStyle.setAlignment(HorizontalAlignment.CENTER);
headCellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
headCellStyle.setFillForegroundColor(HSSFColor.HSSFColorPredefined.GREY_50_PERCENT.getIndex());
HSSFFont font = wb.createFont();
font.setFontName("Arial");
font.setColor(IndexedColors.WHITE.getIndex());
font.setFontHeightInPoints((short)10);
font.setBold(true);
headCellStyle.setFont(font);
headCellStyle.setBorderBottom(BorderStyle.THIN);
headCellStyle.setBorderLeft(BorderStyle.THIN);
headCellStyle.setBorderTop(BorderStyle.THIN);
headCellStyle.setBorderRight(BorderStyle.THIN);
}
}
测试用例
@GetMapping("/exportSum")
public void exportSum(HttpServletResponse response, AttendanceCountDetail detail) throws Exception {
List<String> headList = new ArrayList<>();
List<String> headKey = new ArrayList<>();
List<Integer> widList = new ArrayList<>();
headList.add("开始");
headKey.add("begin");
widList.add(15);
headList.add("结束");
headKey.add("end");
widList.add(15);
headList.add("总出勤天数");
headKey.add("sumDays");
widList.add(13);
headList.add("夜班天数");
headKey.add("yeDays");
widList.add(13);
Date tmp = DateUtils.dateTime("yyyyMMdd","20220925");
Date endDate = DateUtils.dateTime("yyyyMMdd","20221024");
HashMap holidays = HolidayUtil.getHoliday(2022);
while (tmp.getTime() <= endDate.getTime()) {
Integer yyyyMMdd = Integer.valueOf(DateUtils.fmtDateToStr(tmp, "yyyyMMdd"));
if(holidays.get(yyyyMMdd)!=null){
headList.add(DateUtils.fmtDateToStr(tmp,"MM/dd")+"("+holidays.get(yyyyMMdd)+"倍"+")");
headKey.add(DateUtils.fmtDateToStr(tmp,"yyyyMMdd"));
}else{
headList.add(DateUtils.fmtDateToStr(tmp,"MM/dd"));
headKey.add(DateUtils.fmtDateToStr(tmp,"yyyyMMdd"));
}
widList.add(8);
tmp = DateUtils.addDays(tmp,1);
}
ArrayList<HashMap> dataList = new ArrayList<>();
ArrayList<HashMap<String, String>> styleList = new ArrayList<>();
Set set = new HashSet();
HashMap<String, Object> dataMap = new HashMap<>();
HashMap<String, String> styleMap = new HashMap<>();
Integer sum = 1;
Integer yeDays = 0;
ArrayList<AttendanceCountDetail> aList = attendanceCountService.getCountSum(detail);
for (AttendanceCountDetail a : aList) {
if (set.contains(a.getStaffName())) {
if(a.getOverTimeStr()==null){
dataMap.put(a.getInDate().toString(), "异常");
}else if(a.getOverTimeStr()<0){
dataMap.put(a.getInDate().toString(), "假");
}else{
if(holidays.get(a.getInDate())!=null){
dataMap.put(a.getInDate().toString(), a.getOverTimeStr()+8);
}else {
dataMap.put(a.getInDate().toString(), a.getOverTimeStr());
}
}
if(a.getBanciType() == AttendanceCountServiceImpl.Banci.YEBAN.value()){
yeDays+=1;
styleMap.put(a.getInDate().toString(), "bColor");
}
dataMap.put("end",a.getInDate());
sum+=1;
}else{
if(dataMap.size()!=0) {
dataMap.put("sumDays",sum);
dataMap.put("yeDays",yeDays);
dataList.add(dataMap);
styleList.add(styleMap);
dataMap = new HashMap<>();
styleMap = new HashMap<String, String>();
sum = new Integer(0);
yeDays = new Integer(0);
}
if(a.getStaffName()==null){
break;
}
dataMap.put("begin",a.getInDate());
if(a.getOverTimeStr()==null){
dataMap.put(a.getInDate().toString(), "异常");
}else if(a.getOverTimeStr()<0){
dataMap.put(a.getInDate().toString(), "假");
}else{
if(holidays.get(a.getInDate())!=null){
dataMap.put(a.getInDate().toString(), a.getOverTimeStr()+8);
}else{
dataMap.put(a.getInDate().toString(), a.getOverTimeStr());
}
}
if(a.getBanciType() == AttendanceCountServiceImpl.Banci.YEBAN.value()){
yeDays+=1;
styleMap.put(a.getInDate().toString(), "bColor");
}
dataMap.put("end",a.getInDate());
sum+=1;
}
}
ExcelExportUtil excelExportUtil = new ExcelExportUtil();
HSSFCellStyle cellStyle = excelExportUtil.getHSSFCellStyle();
cellStyle.setFillForegroundColor(HSSFColor.HSSFColorPredefined.LIGHT_YELLOW.getIndex());
cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
HashMap<String, CellStyle> styles = new HashMap<>(1);
styles.put("bColor",cellStyle);
excelExportUtil.setStyles(styles);
excelExportUtil.setHeadList(headList);
excelExportUtil.setHeadKey(headKey);
excelExportUtil.setHeadWidth(widList);
excelExportUtil.setCellStyleList(styleList);
excelExportUtil.setData(dataList);
excelExportUtil.setSheetName("考勤统计");
excelExportUtil.setFileName("考勤");
excelExportUtil.exportExport(response).flushExplorer();
}
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class AttendanceCountDetail {
private String staffName;
private String positionSeq;
private String department;
private Integer banciType;
private Integer inDate;
private Integer inTime;
private Integer outDate;
private Integer outTime;
private Double overTimeStr;
private Integer isLate;
}