|
@@ -0,0 +1,155 @@
|
|
|
+package com.management.platform.service;
|
|
|
+
|
|
|
+import com.management.platform.entity.UserCorpwxTime;
|
|
|
+import org.apache.poi.ss.usermodel.*;
|
|
|
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+import org.springframework.web.multipart.MultipartFile;
|
|
|
+
|
|
|
+import java.io.IOException;
|
|
|
+import java.time.LocalDate;
|
|
|
+import java.time.format.DateTimeFormatter;
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.List;
|
|
|
+
|
|
|
+@Service
|
|
|
+public class ExcelParserService {
|
|
|
+
|
|
|
+ public List<UserCorpwxTime> parseAttendanceExcel(MultipartFile file) throws IOException {
|
|
|
+ List<UserCorpwxTime> attendanceList = new ArrayList<>();
|
|
|
+
|
|
|
+ try (Workbook workbook = new XSSFWorkbook(file.getInputStream())) {
|
|
|
+ Sheet sheet = workbook.getSheetAt(0); // 获取第一个工作表
|
|
|
+
|
|
|
+ // 获取表头行
|
|
|
+ Row headerRow = sheet.getRow(0);
|
|
|
+
|
|
|
+ // 从第二行开始解析数据(假设第一行是表头)
|
|
|
+ for (int i = 2; i <= sheet.getLastRowNum(); i++) {
|
|
|
+ Row row = sheet.getRow(i);
|
|
|
+ if (row == null) continue;
|
|
|
+
|
|
|
+ // 获取姓名和部门
|
|
|
+ String name = getCellValue(row.getCell(0));
|
|
|
+ String department = getCellValue(row.getCell(2));
|
|
|
+
|
|
|
+ // 从第4列开始是日期列
|
|
|
+ for (int col = 3; col < row.getLastCellNum(); col++) {
|
|
|
+ Cell dateCell = headerRow.getCell(col);
|
|
|
+ Cell timeCell = row.getCell(col);
|
|
|
+
|
|
|
+ if (dateCell == null || timeCell == null) continue;
|
|
|
+
|
|
|
+ // 解析日期(格式如:03-01\n周六)
|
|
|
+ String dateStr = getCellValue(dateCell);
|
|
|
+ String[] dateParts = dateStr.split("\n");
|
|
|
+ if (dateParts.length < 1) continue;
|
|
|
+
|
|
|
+ // 假设年份是当前年(可能需要根据实际情况调整)
|
|
|
+ String monthDay = dateParts[0];
|
|
|
+ int year = LocalDate.now().getYear();
|
|
|
+ LocalDate date = LocalDate.parse(year + "-" + monthDay, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
|
|
|
+
|
|
|
+ // 解析时间记录
|
|
|
+ String timeRecord = getCellValue(timeCell);
|
|
|
+ if (timeRecord == null || timeRecord.isEmpty() || "-".equals(timeRecord)) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 分割时间记录(可能有多个打卡时间)
|
|
|
+ String[] times = timeRecord.split("\n");
|
|
|
+ if (times.length < 2) continue;
|
|
|
+
|
|
|
+ // 取第一个和最后一个时间作为上班和下班时间
|
|
|
+ String startTime = times[0];
|
|
|
+ String endTime = times[times.length - 1];
|
|
|
+
|
|
|
+ // 创建考勤记录对象
|
|
|
+ UserCorpwxTime attendance = new UserCorpwxTime();
|
|
|
+ attendance.setName(name);
|
|
|
+ attendance.setCreateDate(date);
|
|
|
+ attendance.setStartTime(startTime);
|
|
|
+ attendance.setEndTime(endTime);
|
|
|
+
|
|
|
+ // 计算工作时长(这里简化处理,实际需要更精确的计算)
|
|
|
+ if (startTime != null && endTime != null) {
|
|
|
+ try {
|
|
|
+ double workHours = calculateWorkHours(startTime, endTime);
|
|
|
+ attendance.setWorkHours(workHours);
|
|
|
+ } catch (Exception e) {
|
|
|
+ // 时间格式不正确时忽略
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 设置星期几
|
|
|
+ if (dateParts.length > 1) {
|
|
|
+ attendance.setWeekDayTxt(dateParts[1]);
|
|
|
+ // 可以根据星期文字设置星期数字
|
|
|
+ attendance.setWeekDay(convertWeekDay(dateParts[1]));
|
|
|
+ }
|
|
|
+
|
|
|
+ attendanceList.add(attendance);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return attendanceList;
|
|
|
+ }
|
|
|
+
|
|
|
+ private String getCellValue(Cell cell) {
|
|
|
+ if (cell == null) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ switch (cell.getCellTypeEnum()) {
|
|
|
+ case STRING:
|
|
|
+ return cell.getStringCellValue().trim();
|
|
|
+ case NUMERIC:
|
|
|
+ if (DateUtil.isCellDateFormatted(cell)) {
|
|
|
+ return cell.getDateCellValue().toString();
|
|
|
+ } else {
|
|
|
+ return String.valueOf(cell.getNumericCellValue());
|
|
|
+ }
|
|
|
+ case BOOLEAN:
|
|
|
+ return String.valueOf(cell.getBooleanCellValue());
|
|
|
+ case FORMULA:
|
|
|
+ return cell.getCellFormula();
|
|
|
+ default:
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private double calculateWorkHours(String startTime, String endTime) {
|
|
|
+ // 简单计算工作时长(小时)
|
|
|
+ // 实际应用中需要更精确的计算,考虑午休时间等
|
|
|
+ String[] startParts = startTime.split(":");
|
|
|
+ String[] endParts = endTime.split(":");
|
|
|
+
|
|
|
+ int startHour = Integer.parseInt(startParts[0]);
|
|
|
+ int startMinute = Integer.parseInt(startParts[1]);
|
|
|
+ int endHour = Integer.parseInt(endParts[0]);
|
|
|
+ int endMinute = Integer.parseInt(endParts[1]);
|
|
|
+
|
|
|
+ double hours = (endHour - startHour) + (endMinute - startMinute) / 60.0;
|
|
|
+
|
|
|
+ // 减去午休时间(假设12:00-13:00为午休)
|
|
|
+ if (startHour <= 12 && endHour >= 13) {
|
|
|
+ hours -= 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ return hours;
|
|
|
+ }
|
|
|
+
|
|
|
+ private int convertWeekDay(String weekDayTxt) {
|
|
|
+ switch (weekDayTxt) {
|
|
|
+ case "周一": return 1;
|
|
|
+ case "周二": return 2;
|
|
|
+ case "周三": return 3;
|
|
|
+ case "周四": return 4;
|
|
|
+ case "周五": return 5;
|
|
|
+ case "周六": return 6;
|
|
|
+ case "周日": return 7;
|
|
|
+ default: return 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|