飞书考勤Excel导入到自己系统
此篇主要用于记录Excel一行中,单条数据的日期拿取,并判断上下班打卡情况。代码可能满足不了大部分需求,目前只够本公司用,如果需要,可以参考。
需要把飞书月度汇总的考勤表导入系统中可以参考下。
下图为需要获取的年月日以及对应表格的数据。
实现代码如下
//导入Excel接口并调用下方的readAttendanceRecords()方法
/**
* 导入飞书考勤列表
*/
/** 示例:
@ApiOperation("导入飞书考勤表")
@Log(title = "导入飞书考勤表", businessType = BusinessType.IMPORT)
@PostMapping("/importFeiShuDataFile")
public AjaxResult importFeiShuDataFile(MultipartFile file, boolean updateSupport) throws Exception {
File convertFile = convert(file);
List<Attendance> attendanceFeiShus = readAttendanceRecords(convertFile);
String message = attendanceService.importAttendance(attendanceFeiShus, false, "1");
return AjaxResult.success(message);
}
**/
/**
* 将MultipartFile转换为File
*
* @param multipartFile 上传的文件
* @return 转换后的File对象
* @throws IOException 如果文件操作失败
*/
public static File convert(MultipartFile multipartFile) throws IOException {
// 创建一个临时文件
Path tempFile = Files.createTempFile("upload-", ".tmp");
try (InputStream inputStream = multipartFile.getInputStream()) {
// 将MultipartFile的内容复制到临时文件
Files.copy(inputStream, tempFile, StandardCopyOption.REPLACE_EXISTING);
}
// 返回File对象
return tempFile.toFile();
}
public List<Attendance> readAttendanceRecords(File file) throws IOException, InvalidFormatException, ParseException {
List<Attendance> records = new ArrayList<>();
// 创建工作簿对象
Workbook workbook = new XSSFWorkbook(file);
Sheet sheet = workbook.getSheetAt(0); // 获取第一个工作表
// 遍历第一行(跳过表头)
Row row = sheet.getRow(1);
String date = getCellValue(row.getCell(58)); // 日期
// 截取字符串日期
String[] dataArray = date.split("-");
String year = dataArray[0];
String month = dataArray[1];
LocalDate localDate = LocalDate.of(Integer.parseInt(year), Integer.parseInt(month), 1);
LocalDate origin = LocalDate.of(Integer.parseInt(year), Integer.parseInt(month), 1);
// 获取这个月的总天数
int monthLength = localDate.lengthOfMonth();
// 遍历每一行(跳过表头)
for (int i = 2; i <= sheet.getLastRowNum(); i++) {
Row row2 = sheet.getRow(i);
if (row2 == null) continue;
// 解析每一列的数据
String employeeName = getCellValue(row2.getCell(0)); // 员工姓名
String employeeNo = getCellValue(row2.getCell(1)); // 员工ID
// 需要查询员工id的员工对象
Employee employee = new Employee();
if (employeeNo.equals("-")) {
employee.setEmployeeName(employeeName);
// 根据姓名查询员工id
List<Employee> employees = employeeService.selectEmployeeList(employee);
if (CollUtil.isNotEmpty(employees)) {
employee = employees.get(0); // 如果出现多个员工,请在excel里面把员工编号填写上,否则如果姓名相同根据姓名来获取默认第一个
}
}
String day = getCellValue(row2.getCell(58)); // 日期
// 一个月的数据
for (int j = 1; j < monthLength; j++) {
Attendance record = new Attendance();
record.setEmployeeName(employeeName);
record.setEmployeeNo(employee.getEmployeeNo() == null ? employeeNo : employee.getEmployeeNo()); // 如果excel的员工id不为空的话,用excel,否则用查询的
if (day.equals("-")) { // 如果为-,代表没来
day = getCellValue(row2.getCell(58 + j));
localDate = localDate.plusDays(1);// 加一天
// continue;
} else {
// 解析day 的上下班时间
if (!day.contains(",")) { // 说明只上班,没下班,默认下午18:00;
Date startTime = DateUtils.dateTime("HH:mm:ss", day + ":00");
record.setStartTime(startTime);
record.setEndTime(DateUtils.dateTime("HH:mm:ss", "18:00:00"));
} else {
String[] split = day.split(",");
record.setStartTime(DateUtils.dateTime("HH:mm:ss", split[0] + ":00")); // 拼接成HH:mm:ss格式
if (split.length == 3) {
record.setEndTime(DateUtils.dateTime("HH:mm:ss", "18:00:00")); // 一天只打了三次卡,设置默认下班时间为18点
}else {
record.setEndTime(DateUtils.dateTime("HH:mm:ss", split[split.length-1] + ":00" )); // 一天只打了三次卡,设置默认下班时间为18点
}
}
// 将LocalDate转换为ZonedDateTime(默认时区)
ZonedDateTime zonedDateTime = localDate.atStartOfDay(ZoneId.systemDefault());
// 将ZonedDateTime转换为Instant
Instant instant = zonedDateTime.toInstant();
// 将Instant转换为Date
Date Day = Date.from(instant);
record.setDay(Day); // 从该月第一天开始
records.add(record);
localDate = localDate.plusDays(1);// 加一天
day = getCellValue(row2.getCell(58 + j));
}
}
localDate = origin;
}
logger.info("考勤信息:{{}}", records);
workbook.close();
return records;
}
// 获取单元格的值
private static String getCellValue(Cell cell) {
if (cell == null) {
return "";
}
switch (cell.getCellType()) {
case STRING:
return cell.getStringCellValue();
case NUMERIC:
if (DateUtil.isCellDateFormatted(cell)) {
return cell.getLocalDateTimeCellValue().toString(); // 如果是日期类型,返回日期字符串
} else {
return String.valueOf(cell.getNumericCellValue());
}
case BOOLEAN:
return String.valueOf(cell.getBooleanCellValue());
case FORMULA:
return cell.getCellFormula();
default:
return "";
}
}
/**
* 判断某一年是否是闰年
*
* @param year 年份
* @return true表示是闰年,false表示是平年
*/
public static boolean isLeapYear(int year) {
// 规则1:能被4整除但不能被100整除
// 规则2:能被400整除
return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
}