python 钉钉导出Excel考勤统计

  • 解决钉钉导出考勤表统计(加班时长、补贴)
  • 支持自定义格式输出,生成每个人的考勤统计
  • 基于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)

文件目录

在这里插入图片描述

钉钉导出表

在这里插入图片描述

生成个人统计表

在这里插入图片描述

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

在这里插入图片描述

生成汇总统计表

在这里插入图片描述

  • 2
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Python钉钉Webhook机器人是一种通过Webhook技术实现的自动发送消息到钉钉群组的工具。它可以通过Python编程语言快速配置和使用。 首先,我们需要在钉钉管理后台创建一个Webhook机器人,并获取相应的Webhook地址。然后,我们可以使用Python的requests库发送HTTP请求到这个Webhook地址,来触发消息的发送。 我们可以使用以下代码示例来实现一个Python钉钉Webhook机器人: ```python import requests import json def send_dingtalk_message(webhook_url, message): headers = { 'Content-Type': 'application/json', } data = { 'msgtype': 'text', 'text': { 'content': message, }, } response = requests.post(webhook_url, headers=headers, data=json.dumps(data)) if response.status_code == 200: print('消息发送成功') else: print('消息发送失败') # 使用示例 webhook_url = '钉钉机器人的Webhook地址' message = '这是一条来自Python钉钉机器人的消息' send_dingtalk_message(webhook_url, message) ``` 上述代码中,我们定义了一个`send_dingtalk_message`函数,该函数接收Webhook地址和要发送的消息作为参数,并通过requests库发送POST请求。消息的内容由`text`字段中的`content`属性指定,这里指定的是`message`参数。 通过调用`send_dingtalk_message`函数,我们可以将指定的消息发送到钉钉群组中。如果消息发送成功,函数将输出"消息发送成功",否则输出"消息发送失败"。 总之,Python钉钉Webhook机器人可以帮助我们通过Python编程语言快速实现消息的发送和接收,方便进行钉钉群组的管理和交流。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值