当前位置: 首页 > article >正文

飞书考勤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);// 根据姓名查询员工idList<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转换为InstantInstant instant = zonedDateTime.toInstant();// 将Instant转换为DateDate 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);}

相关文章:

飞书考勤Excel导入到自己系统

此篇主要用于记录Excel一行中&#xff0c;单条数据的日期拿取&#xff0c;并判断上下班打卡情况。代码可能满足不了大部分需求&#xff0c;目前只够本公司用&#xff0c;如果需要&#xff0c;可以参考。 需要把飞书月度汇总的考勤表导入系统中可以参考下。 下图为需要获取的年…...

【leetcode hot 100 560】和为K的子数组

解法一&#xff1a;用左右指针寻找字串&#xff0c;如果和>k&#xff0c;则减少一个数&#xff08;left&#xff09;&#xff1b;如果和<k&#xff0c;则加上一个数&#xff08;right&#xff09;。 class Solution {public int subarraySum(int[] nums, int k) {int nu…...

EGO-Planner的无人机视觉选择(yolov5和yolov8)

EGO-Planner的无人机视觉选择&#xff08;yolov5和yolov8&#xff09; 效果 yolov5检测效果 yolov8检测效果 一、YOLOv8 vs YOLOv5&#xff1a;关键差异解析 1. 训练效率&#xff1a;为何YOLOv8更快&#xff1f; 架构轻量化 YOLOv8采用C2f模块&#xff08;Cross Stage Partia…...

C++ | 面向对象 | 类

&#x1f47b;类 &#x1f47e;语法格式 class className{Access specifiers: // 访问权限DataType variable; // 变量returnType functions() { } // 方法 };&#x1f47e;访问权限 class className {public:// 公有成员protected:// 受保护成员private:// 私有成员 }…...

性能测试分析和调优

步骤 性能调优的步骤 性能调优的步骤&#xff1a; 1.确定问题&#xff1a;根据性能测试的结果来分析确定bug。–测试人员职责 2.分析原因&#xff1a;分析问题产生的原因。----开发人员职责 3.给出解决方案&#xff1a;可以是修改软件配置、增加硬件资源配置、修改代码等----…...

阿里云oss文件上传springboot若依java

一、第一步 引入依赖 <!-- 阿里云OSS --> <dependency><groupId>com.aliyun.oss</groupId><artifactId>aliyun-sdk-oss</artifactId> </dependency> 二、第二步 application.yml #阿里云oss服务配置 aliyun:oss:endpoint: …...

【自学笔记】Oracle基础知识点总览-持续更新

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 Oracle 数据库基础知识点总览1. 数据库安装与配置2. SQL基础3. PL/SQL基础4. 数据库管理5. 高级主题 总结 Oracle 数据库基础知识点总览 1. 数据库安装与配置 安装…...

使用create_sql_query_chain工具根据自然语言问题生成SQL查询,踩坑版

1. 开启调试模式 from langchain import debugdebug True # 启用调试模式说明&#xff1a; 这里从 langchain 库中导入了一个名为 debug 的变量&#xff08;或模块&#xff09;&#xff0c;然后将它设置为 True。这通常用来启用调试模式&#xff0c;方便开发者在程序运行时看…...

PyInstaller 打包python 程序 成 可执行文件

pyinstaller --onefile --name my_project --add-data "config/config.json:config" main.py 要将整个 Python 项目打包成一个可执行文件&#xff0c;可以使用 PyInstaller 来完成这个任务。以下是如何将整个项目打包成可执行文件的步骤&#xff1a; 1. 安装 PyIns…...

生鲜行业智能化供应链解决方案技术白皮书

行业痛点与技术挑战 损耗控制难题 行业平均损耗率达18%-25%&#xff0c;需构建动态定价模型与智能分拣系统 冷链管理复杂度 全程温控数据采集点超过23个/车次&#xff0c;异常响应延迟需压缩至90秒内 供需预测偏差 传统模式预测准确率不足65%&#xff0c;亟需AI驱动需求预测体…...

preg_replace 与 str_replace 的比较与选择

preg_replace 与 str_replace 的比较与选择 ——PHP字符串处理的核心工具深度解析 一、核心功能定位 在PHP的字符串处理中&#xff0c;str_replace和preg_replace是两种最常用的替换函数&#xff0c;但其设计目标和应用场景存在本质差异&#xff1a; str_replace 简单字符串替…...

无人机自主导航与避障技术!

自主导航的实现 环境感知&#xff1a;通过传感器&#xff08;如摄像头、激光雷达、超声波传感器等&#xff09;获取周围环境信息。 地图构建&#xff1a;利用SLAM&#xff08;同步定位与地图构建&#xff09;技术&#xff0c;实时生成环境地图并确定无人机的位置。 路径规划…...

密码学(哈希函数)

4.1 Hash函数与数据完整性 数据完整性&#xff1a; 检测传输消息&#xff08;加密或未加密&#xff09;的修改。 密码学Hash函数&#xff1a; 构建某些数据的简短“指纹”&#xff1b;如果数据被篡改&#xff0c;则该指纹&#xff08;以高概率&#xff09;不再有效。Hash函数…...

深入探索 STM32 微控制器:从基础到实践

一、引言 在当今的嵌入式系统领域&#xff0c;STM32 系列微控制器凭借其高性能、低功耗、丰富的外设以及广泛的应用场景&#xff0c;成为了众多开发者的首选。无论是在工业控制、智能家居、医疗设备&#xff0c;还是在消费电子等领域&#xff0c;STM32 都展现出了强大的生命力…...

React 常见面试题及答案

记录面试过程 常见问题&#xff0c;如有错误&#xff0c;欢迎批评指正 1. 什么是虚拟DOM&#xff1f;为什么它提高了性能&#xff1f; 虚拟DOM是React创建的一个轻量级JavaScript对象&#xff0c;表示真实DOM的结构。当状态变化时&#xff0c;React会生成新的虚拟DOM&#xf…...

SpringSecurity 实现token 认证

配置类 Configuration EnableWebSecurity EnableGlobalMethodSecurity(prePostEnabledtrue) public class SpringSecurityConfig extends WebSecurityConfigurerAdapter { Bean Override public AuthenticationManager authenticationManagerBean() throws Exception {return s…...

【详解 | 辨析】“单跳多跳,单天线多天线,单信道多信道” 之间的对比

文章目录 1. 单跳 & 多跳2. 单天线 & 多天线3. 单信道 & 多信道4. 小区内通信 & 小区间通信5. 更多辨析5.1 无线Mesh网络&#xff0c;Ad Hoc网络&#xff0c;无线传感器网络&#xff08;MSN&#xff09;5.2 “单天线/多天线”与“单信道/多信道”的区别 6. 工业…...

嵌入式开发工程师笔试面试指南-HR面试常见问题汇总

在嵌入式领域的招聘面试中,HR 通过一系列精心设计的问题,全面考察候选人的综合素质、专业能力以及与岗位的匹配度。以下从多个关键方面汇总了 HR 在嵌入式面试中常见的问题。 ** 一、语言表达方面 请简单介绍一下你自己这是面试开场常见问题,旨在让候选人做一个自我展示,…...

Docker 搭建 Gitlab 服务器 (完整详细版)

参考 Docker 搭建 Gitlab 服务器 (完整详细版)_docker gitlab-CSDN博客 Docker 安装 (完整详细版)_docker安装-CSDN博客 Docker 日常命令大全(完整详细版)_docker命令-CSDN博客 1、Gitlab镜像 # 查找Gitlab镜像 docker search gitlab # 拉取Gitlab镜像 docker pull gitlab/g…...

MongoDB安全管理

MongoDB如何鉴权 保证数据的安全性是数据库的重大职责之一。与大多数数据库一样&#xff0c;MongoDB内部提供了一套完整的权限防护机制。如下例所示&#xff1a; mongo --host 127.0.0.1 --port 27017 --username someone --password errorpass --authenticationDatabasestor…...

架构案例:从初创互联网公司到分布式存储与反应式编程框架的架构设计

文章目录 引言一、初创互联网公司架构演化案例1. 万级日订单级别架构2. 十万级日订单级别架构3. 百万级日订单级别架构 二、分布式存储系统 Doris 架构案例三、反应式编程框架架构案例总结 引言 分布式架构 今天我们将探讨三种不同类型的架构案例&#xff0c;分别探讨 一个初…...

神经网络之CNN图像识别(torch api 调用)

1.简介 CNN 是受生物学上感受野机制启发而提出的。它通过卷积操作自动提取数据中的特征&#xff0c;避免了传统机器学习方法中复杂的特征工程过程&#xff0c;能够自动学习到数据中的有效特征&#xff0c;从而进行分类、识别等任务。 2.结构 2.1卷积&#xff1a; 假设你有一…...

使用Truffle、Ganache、MetaMask、Vue+Web3完成的一个简单区块链项目

文章目录 概要初始化Truffle项目创建编写合约编译合约配置Ganache修改truffle-config.js文件编写迁移文件部署合约使用Truffle 控制台使用MetaMask和VueWeb3与链交互 概要 使用Truffle、Ganache、MetaMask、VueWeb3完成的一个简单区块链项目。 初始化Truffle项目 安装好truf…...

学生管理前端

文章目录 首页student.html查询功能 首页 SpringBoot前端html页面放在static文件夹下&#xff1a;/src/main/resources/static 默认首页为index.html&#xff0c;我们可以用两个超链接或者两个button跳转到对应的页面。这里只是单纯的跳转页面&#xff0c;不需要提交表单等其…...

DeepSeek 助力 Vue3 开发:打造丝滑的网格布局(Grid Layout)

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享一篇文章&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495; 目录 Deep…...

lvgl运行机制分析

lv_timer_handler() 是 LVGL 的“心脏”&#xff1a;这个函数会依次做以下事情&#xff1a; 处理定时器&#xff08;如动画、延迟回调&#xff09;。 读取输入设备&#xff08;如触摸屏、按键的状态&#xff09;。 刷新脏区域&#xff08;仅重绘屏幕上发生变化的区域&#xf…...

ffmpeg avformat_open_input的作用

1. avformat_open_input 的作用 avformat_open_input 是 FFmpeg 中用于打开输入文件或输入设备的函数。它的主要作用是初始化输入文件或设备的上下文&#xff08;AVFormatContext&#xff09;&#xff0c;并准备好从输入源读取数据。 2. avformat_open_input 的功能 打开输入文…...

leaflet扩展插件esri-leaflet.js

esri-leaflet.js是一个开源的JavaScript库&#xff0c;它允许开发者在Leaflet地图上轻松地使用Esri的服务&#xff0c;如ArcGIS Online和ArcGIS Server的图层。以下是对esri-leaflet.js插件的详细介绍&#xff1a; 一、主要功能 esri-leaflet.js的主要功能是将Esri的地图服务…...

8 SpringBoot进阶(上):AOP(面向切面编程技术)、AOP案例之统一操作日志

文章目录 前言1. AOP基础1.1 AOP概述: 什么是AOP?1.2 AOP快速入门1.3 Spring AOP核心中的相关术语(面试)2. AOP进阶2.1 通知类型2.1.1 @Around:环绕通知,此注解标注的通知方法在目标方法前、后都被执行(通知的代码在业务方法之前和之后都有)2.1.2 @Before:前置通知,此…...

day01_Java基础

文章目录 day01_Java基础一、今日课程内容二、Java语言概述&#xff08;了解&#xff09;1、Java语言概述2、为什么要学习Java语言3、Java平台版本说明4、Java特点 三、Java环境搭建&#xff08;操作&#xff09;1、JDK和JRE的概述2、JDK的下载和安装3、IDEA的安装4、IDEA的启动…...