python 钉钉导出Excel考勤统计

本文介绍了一种使用Python处理钉钉导出的考勤表的方法,通过pandas和xlwings实现自动化统计加班时长及补贴,包括生成个人统计表和汇总表。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • 解决钉钉导出考勤表统计(加班时长、补贴)
  • 支持自定义格式输出,生成每个人的考勤统计
  • 基于pandas和xlwings对表格进行读写
import pandas as pd
import sys
import os
import numpy as np
import xlwings as xw
import time
import datetime
import glob
sys.path.append(os.path.dirname(os.path.abspath(__file__)))

class CheckIn:
    def __init__(self):
        pass

    def check_table(self, url):
        df = pd.read_excel(url, header=None, index_col=None)
        df = df[2:]
        df = df[[0, 1, 5, 6, 7, 8, 9]]
        df = df.drop(3, axis=0)
        df.columns = df.iloc[0].values
        df = df.drop(2, axis=0)
        # 只处理含‘正常’班和休息的班次
        df = df[df['上班1打卡结果'].isin(['正常']) | df['班次'].isin(['休息'])]
        # 必须包含上下班打卡
        df = df[~df['上班1打卡时间'].isin([np.NaN]) & ~df['下班1打卡时间'].isin([np.NaN])]
        df['累计加班'] = 0
        df['加班次数'] = 0
        df['餐补标准'] = 25
        df['报销金额'] = 0
        for _, row in df.iterrows():
            # 计算上下班时间
            row['上班1打卡时间'] = str(row['上班1打卡时间'])[0: 5]
            row['下班1打卡时间'] = str(row['下班1打卡时间'])[0: 5]
            start_time = row['上班1打卡时间']
            over_time = row['下班1打卡时间']
            add_min = 0
            if '次日' in row['下班1打卡时间']:  # 最晚有效下班时间为24:00
                over_time = '23:59'
                add_min = 60
            # print('start_time', str(start_time))
            start_time = datetime.datetime.strptime(start_time, "%H:%M")
            over_time = datetime.datetime.strptime(over_time, "%H:%M")
            work_time = max(round(((over_time - start_time).seconds + 1 + add_min) / 3600), 0)
            #  餐补统计
            if ('正常' in row['上班1打卡结果']) and (row['下班1打卡时间'] >= '19:00'):
                df.loc[row.name, '加班次数'] = 1
            elif '休息' in row['班次']:
                if work_time >= 4:
                    df.loc[row.name, '加班次数'] = 1
                if work_time >= 7:
                    df.loc[row.name, '加班次数'] = 2
            df.loc[row.name, '报销金额'] = df.loc[row.name, '加班次数'] * df.loc[row.name, '餐补标准']
            #  加班统计
            work_plus_time = 0
            if '正常' in row['上班1打卡结果']:
                if start_time.hour >= 7:  # 有效打卡早7点以后
                    if start_time.hour <= 9:  # 九点后累计上班时长
                        start_time = datetime.datetime.strptime('09:00', "%H:%M")
                    work_plus_time = max(round(((over_time - start_time).seconds + 1 + add_min) / 3600 - 9.5),
                                         0)  # 超过9.5计算加班时长,半小时一个粒度
            elif '休息' in row['班次']:
                if work_time >= 4:
                    work_plus_time = work_time
            df.loc[row.name, '累计加班'] = work_plus_time

        word_plus = url.replace('base', 'new').replace('考勤表', '加班餐补-加班时长明细表')
        df.to_excel(word_plus, index=False)
        df['加班日期'] = df['日期'].map(lambda x: x.split(" ")[0] + ' ') + df['下班1打卡时间'].map(str)
        df.loc[df['班次'] == '休息', '加班日期'] = df['日期'].map(str) + df['上班1打卡时间'].map(str)
        df_output = df[['姓名', '加班日期', '加班次数', '餐补标准', '报销金额', '上班1打卡结果', '班次', '累计加班']]
        return df_output[['姓名', '加班日期', '加班次数', '餐补标准', '报销金额', '累计加班', '班次']]

    def money_table(self, url, data, output_url):
        data = data[data['加班次数'] > 0 | data['班次'].isin(['休息'])]
        data = data.drop(['班次'], axis=1)
        name_list = data['姓名'].unique()
        wb = xw.Book(url)
        sht_sheet1 = wb.sheets['Sheet1']  # 要复制的sheets
        for i, v in enumerate(name_list):
            sht_sheet1.api.Copy(Before=sht_sheet1.api)
            sht = wb.sheets['Sheet1 (2)']
            sht.api.Name = v
            struct_time = time.localtime(time.time())  # 得到结构化时间格式
            now_time = time.strftime("%Y/%m/%d", struct_time)
            sht.range('H4').value = now_time
            sht.range('B4').value = output_url.split('/')[-1].split('\\')[-1].split('20')[0]
            item = data[data['姓名'] == v]
            new_data_rows = item.values.shape[0]
            item.insert(0, '序号', [i+1 for i in range(new_data_rows)])
            start_row = 7
            # last_row = sht.range('A7').expand().last_cell.row
            last_row = 38
            work_rows = last_row - start_row
            sub_rows = abs(new_data_rows - work_rows)
            # print(f'last{last_row},word{work_rows}')
            if new_data_rows > work_rows:
                for _ in range(sub_rows):
                    sht.api.rows(start_row + 1).insert
            elif new_data_rows < work_rows:
                for _ in range(sub_rows):
                    sht.api.rows(start_row + 1).delete
            # print(f'last{sht.range("A7").expand().last_cell.row},new{new_data_rows},word{work_rows}')
            sht.range('A7').value = item.values
        wb.save(output_url)
        wb.close()

    def total(self, df, output_url):
        total_df = df.groupby(by='姓名').sum()[['加班次数', '报销金额', '累计加班']]
        total_df = total_df.sort_values(by='加班次数', ascending=False)
        total_df['备注'] = ''
        total_df = total_df.reset_index()
        total_df = total_df.append([{
            '姓名': '合计', '加班次数': total_df['加班次数'].sum(), '报销金额': total_df['报销金额'].sum(),
            '累计加班': total_df['累计加班'].sum(), '备注':''
        }], ignore_index=True)
        total_df.to_excel(output_url, index=None)


if __name__ == '__main__':
    t = time.time()
    year = '2019'
    month = '5'
    root = '../../data/check'
    standard_url = f'{root}/研发加班餐补201908_standard.xlsx'
    for _, m in enumerate(range(10, 11, 1)):
        month = m
        print(f'生成月份:{month}')
        for check_url in glob.glob(f"{root}/{year}-{month}/base/*.xlsx"):
            if '$' in check_url:
                continue
            check_in = CheckIn()
            check_df = check_in.check_table(url=check_url)
            new_url = check_url.replace('base', 'new')
            total_output_url = new_url.replace('考勤表', '总计表')
            money_output_url = new_url.replace('考勤表', '加班餐补表')
            check_in.total(df=check_df, output_url=total_output_url)
            check_df = check_df.drop('累计加班', axis=1)
            check_in.money_table(url=standard_url, data=check_df, output_url=money_output_url)
    print(time.time()-t)

# print(df_output)
# df_output.to_excel(url.replace('.xlsx', '_清洗.xlsx'), index=None)

文件目录

在这里插入图片描述

钉钉导出表

在这里插入图片描述

生成个人统计表

在这里插入图片描述

依照标准格式表生成每人一张表

在这里插入图片描述

生成汇总统计表

在这里插入图片描述

<think>嗯,用户想开发一个包含多个核心模块的考勤管理系统,我需要先理清楚各个模块的功能和它们之间的关系。首先,用户提到的核心模块有用户管理、考勤管理、请假管理、加班管理和统计报表生成。这些模块应该怎么设计呢? 用户管理模块是基础,需要处理员工信息的增删改查,可能还要有角色权限的设置。比如管理员和普通员工的权限不同,管理员可以修改信息,而普通员工只能查看自己的信息。这部分可能需要数据库设计,每个员工的属性有哪些?姓名、工号、部门、职位、入职时间等等。权限管理可能需要用到RBAC模型,这样灵活一些。 然后是考勤管理,这是系统的核心功能。需要记录员工的打卡数据,可能包括时间、地点、设备信息等。考勤规则可能比较复杂,不同部门可能有不同的上下班时间,或者弹性工作制。如何处理迟到、早退、缺勤的情况?可能需要一个规则引擎来灵活配置。这部分需要与用户管理模块关联,根据员工的部门或职位应用不同的规则。 请假管理模块,员工提交请假申请,审批流程可能需要多级审批。比如,部门经理审批后,再提交给HR。请假类型可能有年假、病假、事假等,每种类型的请假可能有不同的规则,比如需要提交证明文件。这部分需要设计表单和审批流程,可能涉及状态机来跟踪请假申请的状态。 加班管理模块,员工提交加班申请,同样需要审批。加班可能有不同的类型,比如平时加班、周末加班、节假日加班,计算加班工资的方式也不同。需要记录加班开始和结束时间,以及审批状态。可能需要与考勤数据对比,防止虚假申请。 统计报表生成模块,需要从其他模块收集数据,生成各种报表,比如月度考勤汇总、请假统计、加班时长等。可能需要用图表展示,支持导出Excel或PDF。这部分需要设计数据聚合的方式,以及如何高效查询大量数据。 技术选型方面,后端可以用Spring Boot或Django,数据库用MySQL或PostgreSQL。前端可以用Vue或React。权限管理可能用Spring Security或JWT。考勤规则引擎可以考虑Drools,或者自己实现规则配置。报表生成可以用JasperReports或ECharts。 系统集成方面,可能需要与现有的HR系统或OA系统对接,比如通过API或单点登录。考勤设备如指纹打卡机或人脸识别设备的数据如何导入系统?可能需要开发数据接口或定时同步。 安全性也很重要,员工隐私数据需要加密存储,传输过程用HTTPS。权限控制要严格,防止越权访问。日志记录操作,方便审计。 测试方面,每个模块需要单元测试、集成测试。特别是考勤规则的逻辑,需要覆盖各种边界情况。性能测试,确保大量用户同时打卡时系统稳定。 可能遇到的问题,比如考勤数据量大,如何优化查询速度?可以考虑分库分表,或者使用缓存。请假和加班的审批流程如何灵活配置?可能需要工作流引擎,比如Activiti。 用户可能没有提到的需求,比如移动端支持,员工通过手机打卡或提交申请。或者异常考勤处理,比如忘记打卡时如何补卡申请。这些可能需要进一步询问用户。 总之,系统设计需要考虑模块之间的交互,数据一致性,扩展性和性能。每个模块的详细功能需要细化,技术方案要选合适的工具,保证可维护性和可扩展性。</think># 考勤管理系统设计与实现指南 ### 一、系统架构设计 1. 采用分层架构:表现层(前端界面)、业务逻辑层(核心处理)、数据访问层(数据库操作) 2. 技术选型建议: - 后端:Spring Boot(Java)/Django(Python) - 数据库:MySQL/PostgreSQL - 前端:Vue.js/React - 权限控制:RBAC模型+JWT认证[^1] ```java // 示例:用户权限校验逻辑 @PreAuthorize("hasRole('HR_ADMIN')") public void updateAttendanceRule(RuleDTO rule) { // 实现考勤规则更新逻辑 } ``` ### 二、核心模块实现 #### 1. 用户管理模块 - 功能构成: - 员工信息管理(CRUD操作) - 组织架构管理(部门/岗位树形结构) - 角色权限配置(细粒度权限控制) - 数据库表设计: ```sql CREATE TABLE users ( id INT PRIMARY KEY AUTO_INCREMENT, employee_id VARCHAR(20) UNIQUE, name VARCHAR(50), department_id INT, role ENUM('ADMIN','MANAGER','STAFF') ); ``` #### 2. 考勤管理模块 - 核心功能实现: - 考勤规则引擎:支持配置弹性工时、固定班次、异常阈值等 - 考勤数据采集:对接生物识别设备API(指纹/人脸识别) - 异常处理机制:缺勤自动提醒、补卡申请流程 $$ \text{迟到判定公式} = \begin{cases} \text{True} & \text{if } t_{checkin} > t_{start} + \Delta t \\ \text{False} & \text{otherwise} \end{cases} $$ #### 3. 请假/加班管理模块 - 通用流程设计: ``` 申请提交 -> 部门审批 -> HR备案 -> 状态更新 ``` - 特殊处理: - 假期额度计算(年假累计规则) - 加班调休转换机制 - 紧急流程绿色通道 #### 4. 统计报表模块 - 关键指标: - 出勤率:$ \frac{\text{实际出勤天数}}{\text{应出勤天数}} \times 100\% $ - 部门对比分析 - 月度趋势图表 - 实现方式: - 定时任务生成日报/月报 - 支持自定义查询条件 - 可视化图表库集成(ECharts/D3.js) ### 三、系统集成方案 1. 硬件对接:通过TCP/UDP协议对接考勤机设备[^2] 2. 第三方集成: - 企业微信/钉钉接口对接 - 财务系统数据同步 3. 安全防护: - 敏感数据加密存储(AES-256) - 防SQL注入处理 - 操作日志审计追踪 ### 四、实施路线图 1. 需求分析(2周) 2. 原型设计(1周) 3. 模块开发(6-8周) 4. 系统测试(2周) 5. 上线部署(1周)
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值