Excel 考勤表自动清洗工具

从考勤机导出的原始数据,往往非常“详细”。员工一天打卡好几次,表格里密密麻麻地挤在一格: 08:55、12:01、13:30、18:05、18:06
但实际上,我们统计考勤时,只需要“最早”的签到时间和“最晚”的签退时间。
以往处理这种数据,要么用复杂的 Excel 函数,要么手动一个个删,不仅眼睛看花了,还容易出错。
用这个小工具导进去,会自动处理,只保留每一格的第一个时间和最后一个时间。

链接:https://pan.quark.cn/s/28b219285b0c
提取码:Mm5g

import pandas as pd
import re
import tkinter as tk
from tkinter import filedialog, messagebox
import os

def process_time_string(cell_value):
    """ 
    处理逻辑:
    1. 拆分时间
    2. 如果只有一个时间,保留原样
    3. 如果有两个或以上,取【第一个】和【最后一个】,中间换行
    """
    if pd.isna(cell_value):
        return cell_value
    
    cell_str = str(cell_value).strip()
    # 拆分:兼容顿号、逗号、空格、换行符
    times = re.split(r'[、,, \n]+', cell_str)
    # 过滤空项
    times = [t for t in times if t]
    
    if len(times) == 0:
        return ""
    elif len(times) == 1:
        return times[0]
    else:
        # 取头和尾,用换行符(\n)连接
        return f"{times[0]}\n{times[-1]}"

def select_file_and_process():
    file_path = filedialog.askopenfilename(
        title="请选择考勤表 Excel 文件",
        filetypes=[("Excel Files", "*.xlsx *.xls")]
    )
    
    if not file_path:
        return

    try:
        lbl_status.config(text="正在处理中...请稍候", fg="blue")
        root.update()

        # 读取 Excel
        df = pd.read_excel(file_path, dtype=str)
        
        # 处理所有列
        for col in df.columns:
            df[col] = df[col].apply(process_time_string)
            
        # 生成新文件名
        dir_name = os.path.dirname(file_path)
        base_name = os.path.basename(file_path)
        name, ext = os.path.splitext(base_name)
        output_path = os.path.join(dir_name, f"{name}_已整理{ext}")

        # 保存 Excel
        # 这里的 engine='openpyxl' 是为了更好的兼容性
        df.to_excel(output_path, index=False)
        
        lbl_status.config(text="处理成功!", fg="green")
        messagebox.showinfo("成功", f"处理完成!\n\n注意:打开新表格后,请选中全表并点击Excel顶部的【自动换行】按钮,以便正确显示上下两行。\n\n保存位置:\n{output_path}")
        lbl_status.config(text="等待选择文件...", fg="black")

    except Exception as e:
        lbl_status.config(text="出错啦", fg="red")
        messagebox.showerror("错误", f"处理失败:\n{str(e)}")

# ================= 界面设置 =================
root = tk.Tk()
root.title("轻染考勤数据自动整理工具") # 标题已修改
root.geometry("400x220")

# 居中显示的文字说明
instruction_text = (
    "功能说明:\n"
    "1. 自动识别并保留同一格内的【最早】和【最晚】时间\n"
    "2. 格式调整为:上面一个,下面一个 (换行显示)\n"
    "3. 删除中间多余打卡记录"
)

label = tk.Label(root, text=instruction_text, pady=15, justify="left", fg="#333")
label.pack()

btn = tk.Button(root, text="点击选择表格并开始整理", command=select_file_and_process, height=2, bg="#e1f5fe", font=("微软雅黑", 10, "bold"))
btn.pack(pady=5)

lbl_status = tk.Label(root, text="准备就绪", fg="#666")
lbl_status.pack(side=tk.BOTTOM, pady=10)

root.mainloop()

 

阅读剩余
THE END