You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Spring Boot中提取Excel列数据并实现员工周工时统计及邮件提醒

Spring Boot 实现Excel工时统计与异常推送方案

一、依赖引入

核心功能涉及Excel解析、定时任务、邮件推送三个模块,推荐依赖如下(Maven示例):

<!-- EasyExcel:内存占用低,适合解析大体积Excel -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>3.3.2</version>
</dependency>
<!-- Spring官方邮件依赖 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-mail</artifactId>
</dependency>

定时任务直接使用Spring自带的@Scheduled注解即可,无需额外引入依赖。

二、5个工作日工时提取逻辑

要准确统计周工时,按以下步骤处理即可:

  1. 先定义Excel映射实体,至少包含员工ID、员工姓名、考勤日期、当日工时四个核心字段
  2. 读取Excel全量月度工时数据后,按「员工ID + 周起始日期」做分组,周起始日期可以取当周周一作为唯一标识
  3. 每个分组内过滤出周一到周五的工作日数据:通过LocalDate.getDayOfWeek()判断,排除值为SATURDAY、SUNDAY的行
  4. 对过滤后的5天工时求和,判断总和是否小于40,符合条件的归入异常待推送名单

注意:如果Excel本身已剔除周末数据,直接按周分组求和即可,仅需额外校验每个分组的有效数据条数是否为5,避免节假日等特殊场景导致统计错误。

三、核心代码示例

1. Excel映射实体类

@Data
public class EmployeeWorkHour {
    @ExcelProperty("员工ID")
    private String empId;
    @ExcelProperty("姓名")
    private String empName;
    @ExcelProperty(value = "考勤日期", converter = LocalDateConverter.class)
    private LocalDate attendanceDate;
    @ExcelProperty("当日工时")
    private BigDecimal workHour;
}

2. 工时统计核心方法

public List<Map<String, Object>> getAbnormalEmpList(String excelPath) {
    // 读取Excel全量数据
    List<EmployeeWorkHour> allData = EasyExcel.read(excelPath)
            .head(EmployeeWorkHour.class)
            .sheet()
            .doReadSync();
    // 按员工+周维度分组
    Map<String, List<EmployeeWorkHour>> weekGroupMap = allData.stream()
            .collect(Collectors.groupingBy(data -> {
                // 取当周周一作为周唯一标识
                LocalDate weekStart = data.getAttendanceDate()
                        .with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
                return data.getEmpId() + "_" + weekStart;
            }));
    List<Map<String, Object>> abnormalList = new ArrayList<>();
    for (Map.Entry<String, List<EmployeeWorkHour>> entry : weekGroupMap.entrySet()) {
        // 过滤工作日并求和
        BigDecimal totalHour = entry.getValue().stream()
                .filter(d -> !d.getAttendanceDate().getDayOfWeek().equals(DayOfWeek.SATURDAY)
                        && !d.getAttendanceDate().getDayOfWeek().equals(DayOfWeek.SUNDAY))
                .map(EmployeeWorkHour::getWorkHour)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        // 筛选工时不足40小时的员工
        if (totalHour.compareTo(new BigDecimal(40)) < 0) {
            Map<String, Object> item = new HashMap<>();
            item.put("empId", entry.getValue().get(0).getEmpId());
            item.put("empName", entry.getValue().get(0).getEmpName());
            item.put("weekTotalHour", totalHour);
            item.put("weekStart", entry.getKey().split("_")[1]);
            abnormalList.add(item);
        }
    }
    return abnormalList;
}

3. 每周一邮件推送实现

首先在application.yml中配置邮件参数:

spring:
  mail:
    host: smtp.xxx.com
    username: 发件人邮箱
    password: 邮箱授权码
    port: 465
    properties:
      mail:
        smtp:
          ssl:
            enable: true

定时任务代码:

@Component
@Slf4j
public class WorkHourPushTask {
    @Resource
    private JavaMailSender javaMailSender;
    //  cron表达式:每周一上午9点执行
    @Scheduled(cron = "0 0 9 ? * MON")
    public void pushAbnormalList() {
        // 调用统计方法获取异常名单,excel路径填你本地硬编码的固定路径
        List<Map<String, Object>> abnormalList = getAbnormalEmpList("/xxx/月度工时表.xlsx");
        // 构造邮件内容
        SimpleMailMessage message = new SimpleMailMessage();
        message.setFrom("发件人邮箱");
        message.setTo("收件人邮箱");
        message.setSubject("上周工时不足40小时员工明细");
        String content = abnormalList.stream()
                .map(item -> "员工ID:" + item.get("empId") + ",姓名:" + item.get("empName") + ",周总工时:" + item.get("weekTotalHour"))
                .collect(Collectors.joining("\n"));
        message.setText("上周工时不足40小时的员工明细如下:\n" + content);
        javaMailSender.send(message);
    }
}

最后在Spring Boot启动类上添加@EnableScheduling注解开启定时任务功能即可。

四、额外优化点

  • 如果需要排除法定节假日,可提前维护节假日列表,过滤逻辑额外排除节假日日期即可
  • 可添加Excel读取异常捕获逻辑,避免文件格式错误导致任务执行失败

内容的提问来源于stack exchange,提问作者rubysunn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 23:15:03