飞书考勤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);
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/981393.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Python项目】基于Python的图像去雾算法研究和系统实现

Python项目】基于Python的图像去雾算法研究和系统实现 技术简介&#xff1a;采用Python技术、MYSQL数据库等实现。 系统简介&#xff1a;图像去雾系统主要是基于暗通道先验和逆深度估计技术的去雾算法&#xff0c;系统功能模块分为&#xff08;1&#xff09;图像上传模块&…

游戏引擎学习第135天

仓库:https://gitee.com/mrxiao_com/2d_game_3 回顾 game_asset.cpp 的创建 在开发过程中&#xff0c;不使用任何现成的游戏引擎或第三方库&#xff0c;而是直接基于 Windows 进行开发&#xff0c;因为 Windows 目前仍然是游戏的标准平台&#xff0c;因此首先在这个环境中进行…

【Linux】冯诺依曼体系结构-操作系统

一.冯诺依曼体系结构 我们所使用的计算机&#xff0c;如笔记本等都是按照冯诺依曼来设计的&#xff1a; 截止目前&#xff0c;我们所知道的计算机都是由一个一个的硬件组装起来的&#xff0c;这些硬件又由于功能的不同被分为了输入设备&#xff0c;输出设备&#xff0c;存储器…

[liorf_localization_imuPreintegration-2] process has died

使用liorf&#xff0c;编译没报错&#xff0c;但是roslaunch报错如下&#xff1a; 解决方法&#xff1a; step1: 如果你之前没有安装 GTSAM&#xff0c;可以尝试安装它 step2: 检查是否缺少依赖库 ldd /home/zz/1210/devel/lib/liorf_localization/liorf_localization_imuPr…

模块11_面向对象

文章目录 模块11_面向对象模块十回顾&&模块十一重点 第一章.接口1.接口的介绍2.接口的定义以及使用3.接口中的成员3.1抽象方法3.2默认方法3.3静态方法3.4成员变量3.4成员变量 4.接口的特点5.接口和抽象类的区别 第二章.多态1.多态的介绍2.多态的基本使用3.多态的条件下…

常见webshell工具的流量特征

1、蚁剑 1.1、蚁剑webshell静态特征 蚁剑中php使用assert、eval执行&#xff1b;asp只有eval执行&#xff1b;在jsp使用的是Java类加载&#xff08;ClassLoader&#xff09;&#xff0c;同时会带有base64编码解码等字符特征。 1.2、蚁剑webshell动态特征 查看流量分析会发现…

03标准IO接口

一、系统与标准IO的区别 相同点:系统IO与标准IO都可以操作linux系统下的文件。 ⭐不同点: 系统IO&#xff1a;打开文件得到的是一个整数&#xff0c;称为文件描述符。 标准IO&#xff1a;打开文件得到的是一个指针&#xff0c;称为文件指针。系统IO&#xff1a;可以访问linux…

Axure高保真Element框架元件库

点击下载《Axure高保真Element框架元件库》 原型效果&#xff1a;https://axhub.im/ax9/9da2109b9c68749a/#g1 摘要 本文详细阐述了在 Axure 环境下打造的一套高度还原 Element 框架的组件元件集。通过对 Element 框架组件的深入剖析&#xff0c;结合 Axure 的强大功能&#…

【Linux】进程信号——信号保存和信号捕捉

文章目录 信号保存信号相关的概念信号是如何保存的呢&#xff1f;有关信号保存的系统调用sigprocmask信号的增删查改查看pending表验证接口 信号捕捉用户态与内核态信号捕捉流程 总结 信号保存 信号相关的概念 信号递达&#xff1a;指 操作系统 将一个信号&#xff08;Signal…

【FL0090】基于SSM和微信小程序的球馆预约系统

&#x1f9d1;‍&#x1f4bb;博主介绍&#x1f9d1;‍&#x1f4bb; 全网粉丝10W,CSDN全栈领域优质创作者&#xff0c;博客之星、掘金/知乎/b站/华为云/阿里云等平台优质作者、专注于Java、小程序/APP、python、大数据等技术领域和毕业项目实战&#xff0c;以及程序定制化开发…

因子分析讲解

一、定义 因子分析&#xff08;Factor Analysis&#xff09;是一种常用于多变量统计分析的方法&#xff0c;主要用于数据降维、识别潜在的结构、理解变量间的关系。它通过将一组观察变量&#xff08;通常是高度相关的变量&#xff09;转化为一组较少的、互不相关的因子&#x…

从 JVM 源码(HotSpot)看 synchronized 原理

大家好&#xff0c;我是此林。 不知道大家有没有这样一种感觉&#xff0c;网上对于一些 Java 框架和类的原理实现众说纷纭&#xff0c;看了总是不明白、不透彻。常常会想&#xff1a;真的是这样吗&#xff1f; 今天我们就从 HotSpot 源码级别去看 synchronized 的实现原理。全…

DeepSeek搭配Excel,制作自定义按钮,实现办公自动化!

今天跟大家分享下我们如何将DeepSeek生成的VBA代码&#xff0c;做成按钮&#xff0c;将其永久保存在我们的Excel表格中&#xff0c;下次遇到类似的问题&#xff0c;直接在Excel中点击按钮&#xff0c;就能10秒搞定&#xff0c;操作也非常的简单. 一、代码准备 代码可以直接询问…

Metal学习笔记十一:贴图和材质

在上一章中&#xff0c;您设置了一个简单的 Phong 光照模型。近年来&#xff0c;研究人员在基于物理的渲染 &#xff08;PBR&#xff09; 方面取得了长足的进步。PBR 尝试准确表示真实世界的着色&#xff0c;真实世界中离开表面的光量小于表面接收的光量。在现实世界中&#xf…

zabbix“专家坐诊”第277期问答

在线答疑:乐维社区 问题一 Q&#xff1a;这个怎么解决呢&#xff1f; A&#xff1a;缺少这个依赖。 Q&#xff1a;就一直装不上。 A&#xff1a;装 zabbix-agent2-7.0.0-releasel.el7.x86 64 需要前面提示的那个依赖才可以装。 问题二 Q&#xff1a;大佬&#xff0c;如果agen…

让单链表不再云里雾里

一日不见&#xff0c;如三月兮&#xff01;接下来与我一起创建单链表吧&#xff01; 目录 单链表的结构&#xff1a; 创建单链表&#xff1a; 增加结点&#xff1a; 插入结点&#xff1a; 删除结点&#xff1a; 打印单链表&#xff1a; 单链表查找&#xff1a; 单链表…

图像生成-ICCV2019-SinGAN: Learning a Generative Model from a Single Natural Image

图像生成-ICCV2019-SinGAN: Learning a Generative Model from a Single Natural Image 文章目录 图像生成-ICCV2019-SinGAN: Learning a Generative Model from a Single Natural Image主要创新点模型架构图生成器生成器源码 判别器判别器源码 损失函数需要源码讲解的私信我 S…

指纹细节提取(Matlab实现)

指纹细节提取概述指纹作为人体生物特征识别领域中应用最为广泛的特征之一&#xff0c;具有独特性、稳定性和便利性。指纹细节特征对于指纹识别的准确性和可靠性起着关键作用。指纹细节提取&#xff0c;即从指纹图像中精确地提取出能够表征指纹唯一性的关键特征点&#xff0c;是…

泵吸式激光可燃气体监测仪:快速精准守护燃气管网安全

在城市化进程加速的今天&#xff0c;燃气泄漏、地下管网老化等问题时刻威胁着城市安全。如何实现精准、高效的可燃气体监测&#xff0c;守护“城市生命线”&#xff0c;成为新型基础设施建设的核心课题。泵吸式激光可燃气体监测仪&#xff0c;以创新科技赋能安全监测&#xff0…

HTML label 标签使用

点击 <label> 标签通常会使与之关联的表单控件获得焦点或被激活。 通过正确使用 <label> 标签&#xff0c;可以使表单更加友好和易于使用&#xff0c;同时提高整体的可访问性。 基本用法 <label> 标签通过 for 属性与 id 为 username 的 <input> 元素…