[Build 1.1.3] fix: 优化日期格式处理并修复数据校验问题

- 统一日期输出格式为"YYYY.MM"
- 添加对整数字段的校验处理
- 合并部门和职务列显示
- 修复模板路径和输出文件名格式
- 添加数据格式说明文档
This commit is contained in:
Miu Li 2025-05-27 19:16:11 +08:00
parent 013fa0c3fd
commit a2c5a7179e
3 changed files with 80 additions and 28 deletions

60
main.py
View File

@ -25,8 +25,13 @@ BaseData = pd.read_excel("原数据.xlsx", sheet_name="入职信息")
Promote = pd.read_excel("原数据.xlsx", sheet_name="职务变动") # Promote = pd.read_excel("原数据.xlsx", sheet_name="职务变动") #
Level_Limit = pd.read_excel("原数据.xlsx", sheet_name="职位规则",usecols="A:B", skiprows=2, names=["limit","role"]) Level_Limit = pd.read_excel("原数据.xlsx", sheet_name="职位规则",usecols="A:B", skiprows=2, names=["limit","role"])
BaseData = BaseData.drop(0)
BaseData = BaseData.reset_index(drop=True)
Promote = Promote.drop(0)
Promote = Promote.reset_index(drop=True)
for index, row in BaseData.iterrows(): for index, row in BaseData.iterrows():
for col in ["出生年月","任职年月","参加工作时间","入职时间", "二档起始", "五档起始", "日期2"]: for col in ["出生年月","任职年月","原职时间","参加工作时间","入职时间", "二档起始", "五档起始", "日期2"]:
BaseData.at[index, col] = custom_date_parser(row[col]) BaseData.at[index, col] = custom_date_parser(row[col])
for index, row in Promote.iterrows(): for index, row in Promote.iterrows():
@ -122,22 +127,31 @@ def role_limit(role:str):
logging.warning(f"职位[{role}]不存在职级上限规则") logging.warning(f"职位[{role}]不存在职级上限规则")
return -1 return -1
def format_time(dt):
try:
return dt.strftime("%Y.%m")
except:
return dt
def to_int(x):
try:
return int(x)
except:
return 0
BaseData["工龄调增"] = BaseData["工龄调增"].apply(to_int)
BaseData["工龄调减"] = BaseData["工龄调减"].apply(to_int)
max_promote = 0 max_promote = 0
max_history = 0 max_history = 0
def fill_basic_info(ws, row):# 填充基本信息 def fill_basic_info(ws, row):# 填充基本信息
ws.cell(row=2, column=2, value=row["部门"]) ws.cell(row=2, column=1, value=f"部门:{row['部门']} 职务:{row['职务']}")
ws.cell(row=2, column=7, value=row["职务"])
ws.cell(row=3, column=2, value=row["姓名"]) ws.cell(row=3, column=2, value=row["姓名"])
ws.cell(row=3, column=4, value=row["性别"]) ws.cell(row=3, column=4, value=row["性别"])
ws.cell(row=3, column=6, value=row["民族"]) ws.cell(row=3, column=6, value=row["民族"])
ws.cell(row=3, column=8, value=row["出生年月"])
ws.cell(row=3, column=10, value=row["参加工作时间"])
ws.cell(row=5, column=2, value=row["现职"]) ws.cell(row=5, column=2, value=row["现职"])
ws.cell(row=5, column=4, value=row["任职年月"])
ws.cell(row=5, column=6, value=row["任职年限"]) ws.cell(row=5, column=6, value=row["任职年限"])
ws.cell(row=6, column=2, value=row["原职"]) ws.cell(row=6, column=2, value=row["原职"])
ws.cell(row=6, column=4, value=row["原职时间"])
ws.cell(row=6, column=6, value=row["原职年限"]) ws.cell(row=6, column=6, value=row["原职年限"])
ws.cell(row=7, column=2, value=row["学历"]) ws.cell(row=7, column=2, value=row["学历"])
ws.cell(row=7, column=4, value=row["学龄"]) ws.cell(row=7, column=4, value=row["学龄"])
@ -147,6 +161,10 @@ def fill_basic_info(ws, row):# 填充基本信息
ws.cell(row=7, column=9, value=row["级别工资"]) ws.cell(row=7, column=9, value=row["级别工资"])
ws.cell(row=7, column=10, value=row["职务工资金额"]) ws.cell(row=7, column=10, value=row["职务工资金额"])
ws.cell(row=17, column=1, value=row["个人评价结果"]) ws.cell(row=17, column=1, value=row["个人评价结果"])
ws.cell(row=3, column=8, value=format_time(row["出生年月"]))
ws.cell(row=3, column=10, value=format_time(row["参加工作时间"]))
ws.cell(row=5, column=4, value=format_time(row["任职年月"]))
ws.cell(row=6, column=4, value=format_time(row["原职时间"]))
def fill_prompt_info(ws, promote):# 填充晋升信息 def fill_prompt_info(ws, promote):# 填充晋升信息
for index, prow in promote.iterrows(): for index, prow in promote.iterrows():
@ -155,7 +173,7 @@ def fill_prompt_info(ws, promote):# 填充晋升信息
max_promote = max(max_promote, promote.shape[0]) max_promote = max(max_promote, promote.shape[0])
break break
try: try:
ws.cell(row=P_START+index, column=1, value=prow["任职时间"].strftime("%Y.%m")) ws.cell(row=P_START+index, column=1, value=prow["任职时间"])
except: except:
logging.warning(f"晋升时间格式错误:{prow['任职时间']}") logging.warning(f"晋升时间格式错误:{prow['任职时间']}")
ws.cell(row=P_START+index, column=2, value=prow["变动批注"]) ws.cell(row=P_START+index, column=2, value=prow["变动批注"])
@ -184,8 +202,8 @@ for index, row in BaseData.iterrows():
try: try:
logging.info(f"台账:第[{index+1}]共[{BaseData.shape[0]}]现在是[{row['身份证号码']}]") logging.info(f"台账:第[{index+1}]共[{BaseData.shape[0]}]现在是[{row['身份证号码']}]")
BaseData.at[index, "Latest_Role"] = row["初始职务"] BaseData.at[index, "Latest_Role"] = row["初始职务"]
BaseData.at[index, "Latest_Prom"] = row["入职时间"].strftime("%Y.%m") BaseData.at[index, "Latest_Prom"] = row["入职时间"]
wb = load_workbook("个人台账.xlsx") wb = load_workbook("模板/个人台账.xlsx")
ws = wb.active ws = wb.active
fill_basic_info(ws, row)# 填充基本信息 fill_basic_info(ws, row)# 填充基本信息
@ -194,10 +212,10 @@ for index, row in BaseData.iterrows():
if not promote.empty: if not promote.empty:
promote = promote.sort_values(by="任职时间", ascending=False).reset_index(drop=True) promote = promote.sort_values(by="任职时间", ascending=False).reset_index(drop=True)
BaseData.at[index, "Latest_Role"] = promote.iloc[0]["新职务"] BaseData.at[index, "Latest_Role"] = promote.iloc[0]["新职务"]
BaseData.at[index, "Latest_Prom"] = promote.iloc[0]["任职时间"].strftime("%Y.%m") BaseData.at[index, "Latest_Prom"] = promote.iloc[0]["任职时间"]
if promote.shape[0] > 1: if promote.shape[0] > 1:
BaseData.at[index, "职务2"] = promote.iloc[1]["新职务"] BaseData.at[index, "职务2"] = promote.iloc[1]["新职务"]
BaseData.at[index, "日期2"] = promote.iloc[1]["任职时间"].strftime("%Y.%m") BaseData.at[index, "日期2"] = promote.iloc[1]["任职时间"]
promote = promote.sort_values(by="任职时间").reset_index(drop=True) promote = promote.sort_values(by="任职时间").reset_index(drop=True)
fill_prompt_info(ws, promote)# 填充晋升信息 fill_prompt_info(ws, promote)# 填充晋升信息
@ -256,37 +274,37 @@ for index, row in BaseData.iterrows():
# 计算工资 # 计算工资
History_pd.at[index, "工资额1"] = role_salary(History_pd.iloc[index]["职务"], hrow["时间"]) History_pd.at[index, "工资额1"] = role_salary(History_pd.iloc[index]["职务"], hrow["时间"])
History_pd.at[index, "工资额2"] = level_salary(History_pd.iloc[index]["级别档次"], hrow["时间"]) History_pd.at[index, "工资额2"] = level_salary(History_pd.iloc[index]["级别档次"], hrow["时间"])
History_pd.at[index, "工资合计"] = History_pd.iloc[index]["工资额1"] + History_pd.iloc[index]["工资额2"] History_pd.at[index, "工资合计"] = to_int(History_pd.iloc[index]["工资额1"]) + to_int(History_pd.iloc[index]["工资额2"])
fill_history_info(ws, History_pd)# 填充历史记录 fill_history_info(ws, History_pd)# 填充历史记录
wb.save(f"./output/{row['姓名']}_{row['身份证号码']}.xlsx") wb.save(f"个人台账/{row['身份证号码']}_{row['姓名']}.xlsx")
except Exception as e: except Exception as e:
logging.error(f"{row['身份证号码']}:{e}") logging.error(f"{row['身份证号码']}:{e}")
wb = load_workbook("./汇总.xlsx") wb = load_workbook("模板/汇总名册.xlsx")
ws = wb.active ws = wb.active
for index, row in BaseData.iterrows(): # 汇总 for index, row in BaseData.iterrows(): # 汇总
try: try:
logging.info(f"汇总:第[{index+1}]共[{BaseData.shape[0]}]现在是[{row['身份证号码']}]") logging.info(f"汇总:第[{index+1}]共[{BaseData.shape[0]}]现在是[{row['身份证号码']}]")
for col in range(1,16): for col in range(1,16):
ws.cell(row=3+index, column=col)._style = ws.cell(row=3, column=col)._style ws.cell(row=6+index, column=col)._style = ws.cell(row=6, column=col)._style
ws.cell(row=6+index, column=1, value=index+1) ws.cell(row=6+index, column=1, value=index+1)
ws.cell(row=6+index, column=2, value=row["姓名"]) ws.cell(row=6+index, column=2, value=row["姓名"])
ws.cell(row=6+index, column=3, value=row["性别"]) ws.cell(row=6+index, column=3, value=row["性别"])
ws.cell(row=6+index, column=4, value=row["出生年月"])
ws.cell(row=6+index, column=5, value=row["参加工作时间"])
ws.cell(row=6+index, column=6, value=row["学历"]) ws.cell(row=6+index, column=6, value=row["学历"])
ws.cell(row=6+index, column=7, value=relativedelta(nowtime, row["入职时间"]).years+row["工龄调增"]-row["工龄调减"]+1) ws.cell(row=6+index, column=7, value=relativedelta(nowtime, row["入职时间"]).years+row["工龄调增"]-row["工龄调减"]+1)
ws.cell(row=6+index, column=8, value=relativedelta(nowtime, row["入职时间"]).years) ws.cell(row=6+index, column=8, value=relativedelta(nowtime, row["入职时间"]).years)
ws.cell(row=6+index, column=9, value=row["工龄调增"]) ws.cell(row=6+index, column=9, value=row["工龄调增"])
ws.cell(row=6+index, column=10, value=row["工龄调减"]) ws.cell(row=6+index, column=10, value=row["工龄调减"])
ws.cell(row=6+index, column=11, value=row["Latest_Role"]) ws.cell(row=6+index, column=11, value=row["Latest_Role"])
ws.cell(row=6+index, column=12, value=row["Latest_Prom"])
ws.cell(row=6+index, column=13, value=row["职务2"]) ws.cell(row=6+index, column=13, value=row["职务2"])
ws.cell(row=6+index, column=14, value=row["日期2"]) ws.cell(row=6, column=8, value=format_time(row["出生年月"]))
ws.cell(row=6, column=10, value=format_time(row["参加工作时间"]))
ws.cell(row=6+index, column=12, value=format_time(row["Latest_Prom"]))
ws.cell(row=6+index, column=14, value=format_time(row["日期2"]))
except Exception as e: except Exception as e:
logging.error(f"{row['身份证号码']}:{e}") logging.error(f"{row['身份证号码']}:{e}")
wb.save("./名册.xlsx") # 保存汇总 wb.save("汇总名册.xlsx") # 保存汇总
if max_promote > 0: if max_promote > 0:
logging.warning(f"最多有[{max_promote}]条晋升信息,需要调整模板。记得同时调整薪资历史的起始行和个人评价结果。") logging.warning(f"最多有[{max_promote}]条晋升信息,需要调整模板。记得同时调整薪资历史的起始行和个人评价结果。")

View File

@ -1,4 +1,37 @@
## 打包成 .exe 文件
## 1. 数据格式
### 1.1 需要为整数的字段
入职信息:
- 工龄调增
- 工龄调减
### 1.2需要为日期格式的字段(所有日期相关的字段):
入职信息:
- 出生年月
- 参加工作时间
- 任职年月
- 原职时间
- 入职时间
- 二档起始
- 五档起始
- 日期2
职务变动:
- 任职时间
- 工资执行时间
接受的日期格式:
- Excel接受的日期格式即在Excel中被格式化为为日期的
- 格式如“yyyy-mm-dd”的字符串
统一的输出格式:
所有日期在输出时会被格式化为“yyyy.mm”所以在填写的时候可以虚拟一个“日”但是请保留以保证是日期格式。
## 2. 打包成 .exe 文件
本程序使用Win7兼容的**Python 3.8.10**,需要在电脑上使用此版本,并确保打包的环境是此版本。 本程序使用Win7兼容的**Python 3.8.10**,需要在电脑上使用此版本,并确保打包的环境是此版本。

View File

@ -11,16 +11,17 @@
- [x] feat: 职位名称变化 [completion:: 2025-05-27] - [x] feat: 职位名称变化 [completion:: 2025-05-27]
新增名称变化规则,起始、终止时间内自动替换 新增名称变化规则,起始、终止时间内自动替换
- [ ] fix: 原数据模版(带校验数据值填写规范提示) - [x] fix: 原数据模版(带校验数据值填写规范提示) [completion:: 2025-05-27]
- [x] 兼容 yyyy-mm-dd格式 [completion:: 2025-05-27] - [x] 兼容 yyyy-mm-dd格式 [completion:: 2025-05-27]
- [ ] 有一行数据样例,展示数据格式,实际不生成。 - [x] 有一行数据样例,展示数据格式,实际不生成。 [completion:: 2025-05-27]
需要特定格式的 需要特定格式的
- [ ] 带输入格式检测(修正、提示) - [x] 带输入格式检测(修正、提示) [completion:: 2025-05-27]
用报错的方式实现了
- [x] doc: 打包成exe教程 [completion:: 2025-05-27] - [x] doc: 打包成exe教程 [completion:: 2025-05-27]
- [x] feat: 【赠送】输出log到文件 [completion:: 2025-05-27] - [x] feat: 【赠送】输出log到文件 [completion:: 2025-05-27]
- [x] fix: 工龄列改为学龄,不参与任何计算。 [completion:: 2025-05-27] - [x] fix: 工龄列改为学龄,不参与任何计算。 [completion:: 2025-05-27]
汇总工龄 = 当年年份-参加工作时间年份+工龄调增-工龄调减+1 汇总工龄 = 当年年份-参加工作时间年份+工龄调增-工龄调减+1
- [ ] feat【赠送】新增fall-back逻辑 - [x] feat【赠送】新增fall-back逻辑 [completion:: 2025-05-27]
- [x] 职务2 优先计算结果 [completion:: 2025-05-27] - [x] 职务2 优先计算结果 [completion:: 2025-05-27]
- [ ] feat合并部门和职务列 - [x] feat合并部门和职务列 [completion:: 2025-05-27]
- [ ] fix检查日期输出格式全部放在输出位置更改除了时间2 - [x] fix检查日期输出格式全部放在输出位置更改 [completion:: 2025-05-27]