Python自动化处理Excel考勤数据实战:读取、修正与批量生成
本文介绍如何利用Python的xlrd、xlwt和xlutils库自动化处理Excel考勤数据。重点解析日期与时间值的内部存储机制及数字类型转换问题,提供从读取多个Excel文件、比对请假与外出记录到生成校正后文件的完整代码示例,并通过.bat批处理文件实现一键执行,适用于办公场景下的考勤数据批量修正。
说明:由于公司OA系统暂时缺失,人事部门在进行考勤统计时,需要人工交叉比对多个Excel表格以确认员工是否存在旷工或迟到情况。这项工作不仅耗时费力,还极易出现人为错误。为此,技术人员利用一天时间开发了一套自动化脚本,旨在解决这一痛点。
1. 下载相关Python包 在Python中操作Excel文件,主要依赖以下三个库: xlrd:用于读取Excel文件。 xlwt:用于写入Excel文件。注意,该库无法修改现有的Excel文件,仅能创建新文件。 xlutils:用于修改Excel文件。其原理是通过xlrd读取原文件并复制一份数据,随后进行修改。若保存时使用原文件名,则覆盖原文件;若使用新文件名,则生成一个新文件。
注意事项: a. Python读取Excel中的日期和时间数据时 若表格内容为2019/5/13,Python读取到的值为43606.0,该数值代表从1899年12月30日起经过的天数。 若表格内容为9:00:00,Python读取到的值为0.375,该数值代表时间占全天24小时的比例,即9/24。 若表格内容为2019/5/13 9:00:00,Python读取到的值为43598.375。 由于Python读取到的日期和时间均转化为数字,因此可以直接进行相加运算。
b. Python读取Excel中的数字时,例如员工编号181129,最终结果可能显示为181129.0,而非整数形式。
c. 在调用save函数保存新的Excel文件时,文件后缀名必须为.xls。
2. 将Python文件转换为.bat格式 考虑到非技术人员(如人事同事)无法直接使用命令行执行Python脚本,我们需要提供一种简便的执行方式。通过创建.bat批处理文件即可实现“傻瓜式”操作。 新建一个文本文件,将其重命名为“A考勤小工具.bat”,并在文件中输入以下代码: @py.exe Akqfx.py 其中,@py.exe表示后续参数为Python可执行文件。
3. 附上相关代码和Excel格式文本


Akqfx.py
# 该脚本为修正考勤记录
# author: yangbao
import os
from datetime import datetime
import xlrd
from xlutils.copy import copy
# 定义文件是否存在
def get_list_file():
current_list = os.listdir()
must_list = ['原始数据.xls', '外出.xls', '法定假日.xls', '请假.xls']
cj_set = set(must_list) - set(current_list)
if cj_set:
for i in cj_set:
print('{} 不存在,请检查!'.format(i))
return 0
else:
return 1
# 定义是否存在流程
def get_qjorwc(file_name, person_id, input_time):
book = xlrd.open_workbook(file_name)
book_sheet = book.sheet_by_index(0)
flag = 0
for i in range(1, book_sheet.nrows):
if int(book_sheet.cell_value(i, 1)) == int(person_id):
# 文件不同,时间处理不同
if file_name == '请假.xls':
cell_begin = book_sheet.cell_value(i, 4)
cell_end = book_sheet.cell_value(i, 5)
else:
cell_begin = book_sheet.cell_value(i, 3) + book_sheet.cell_value(i, 4)
cell_end = book_sheet.cell_value(i, 5) + book_sheet.cell_value(i, 6)
# 判断原始数据旷工和迟到是否在请假或外出流程里
# 给额外5min的宽限时间
if cell_begin-5/1440 <= input_time <= cell_end+5/1440:
flag = 1
break
return flag
# 定义是否是法定假日
def get_fdjr(input_time):
book = xlrd.open_workbook('法定假日.xls')
book_sheet = book.sheet_by_index(0)
flag = 0
for i in range(1, book_sheet.nrows):
dt = datetime(*xlrd.xldate_as_tuple(book_sheet.cell_value(i, 0), 0))
if dt.strftime('%Y-%m-%d') == input_time:
flag = 1
break
return flag
def main():
ys_book = xlrd.open_workbook('原始数据.xls')
ys_book_sheet = ys_book.sheet_by_index(0)
new_ys_book = copy(ys_book)
new_ys_book_sheet = new_ys_book.get_sheet(0)
unnormal_list = ['旷工', '迟到']
for i in range(ys_book_sheet.nrows):
# 查上班时间
if ys_book_sheet.cell_value(i, 5) in unnormal_list:
# 查是否是法定假日
dt = ys_book_sheet.cell_value(i, 3)[:10]
if get_fdjr(dt):
new_ys_book_sheet.write(i, 5, '*')
# 查是否有流程
if ys_book_sheet.cell_value(i, 4) != '':
cell_on_time = ys_book_sheet.cell_value(i, 3)[:10] + ' ' + ys_book_sheet.cell_value(i, 4)
cell_on_time_format = datetime.strptime(cell_on_time, "%Y-%m-%d %H:%M:%S") \
- datetime.strptime('1899-12-30', '%Y-%m-%d')
cell_on_time_number = cell_on_time_format.days + cell_on_time_format.seconds / (24 * 3600)
if 12 < cell_on_time_format.seconds / 3600 < 13:
cell_on_time_number = cell_on_time_format.days + 11.5/24
else:
cell_on_time = ys_book_sheet.cell_value(i, 3)[:10]
cell_on_time_format = datetime.strptime(cell_on_time, "%Y-%m-%d") \
- datetime.strptime('1899-12-30', '%Y-%m-%d')
cell_on_time_number = cell_on_time_format.days + cell_on_time_format.seconds / (24 * 3600) + 9/24
qj_on_flag = get_qjorwc('请假.xls', ys_book_sheet.cell_value(i, 1), cell_on_time_number)
wc_on_flag = get_qjorwc('外出.xls', ys_book_sheet.cell_value(i, 1), cell_on_time_number)
if qj_on_flag == 1 or wc_on_flag == 1:
new_ys_book_sheet.write(i, 5, '已有流程')
new_ys_book_sheet.write(i, 11, '')
# 查下班时间
if ys_book_sheet.cell_value(i, 7) in unnormal_list:
# 查是否是法定假日
dt = ys_book_sheet.cell_value(i, 3)[:10]
if get_fdjr(dt):
new_ys_book_sheet.write(i, 7, '*')
new_ys_book_sheet.write(i, 11, '')
# 查是否有流程
if ys_book_sheet.cell_value(i, 6) != '':
cell_out_time = ys_book_sheet.cell_value(i, 3)[:10] + ' ' + ys_book_sheet.cell_value(i, 6)
cell_out_time_format = datetime.strptime(cell_out_time, "%Y-%m-%d %H:%M:%S") \
- datetime.strptime('1899-12-30', '%Y-%m-%d')
cell_out_time_number = cell_out_time_format.days + cell_out_time_format.seconds / (24 * 3600)
if 12 < cell_out_time_format.seconds / 3600 < 13:
cell_out_time_number = cell_out_time_format.days + 13.5/24
else:
cell_out_time = ys_book_sheet.cell_value(i, 3)[:10]
cell_out_time_format = datetime.strptime(cell_out_time, "%Y-%m-%d") \
- datetime.strptime('1899-12-30', '%Y-%m-%d')
cell_out_time_number = cell_out_time_format.days + cell_out_time_format.seconds / (24 * 3600) + 18/24
qj_out_flag = get_qjorwc('请假.xls', ys_book_sheet.cell_value(i, 1), cell_out_time_number)
wc_out_flag = get_qjorwc('外出.xls', ys_book_sheet.cell_value(i, 1), cell_out_time_number)
if qj_out_flag == 1 or wc_out_flag == 1:
new_ys_book_sheet.write(i, 7, '已有流程')
new_ys_book_sheet.write(i, 11, '')
new_excel_name = datetime.now().strftime('%Y%m%d_%H%M%S')+'校正后.xls'
new_ys_book.save(new_excel_name)
if __name__ == '__main__':
if get_list_file():
print('开始考勤分析...')
main()
print('考勤分析结束...')
input('按任意键结束')
else:
input('因为缺少相关excel文件,考勤分析失败,退出程序,按任意键结束')
该文档仅作个人记录用
以上就是Python操作Excel表格的方法的详细内容,更多关于Python操作Excel表格的资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













