1. 项目概述
在日常人力资源管理和数据分析工作中,经常需要比对不同Excel工作表中的员工数据。比如核对考勤系统与HR系统的员工名单、对比新旧版本的人员名单、或者验证不同部门提供的员工信息是否一致。传统的手工比对不仅效率低下,而且容易出错。
这个Python脚本就是为了解决这个问题而设计的。它能自动比对两个Excel工作表中的员工数据,找出:
- 两个表都存在的员工(交集)
- 只在第一个表存在的员工(差集)
- 只在第二个表存在的员工(差集)
最终输出详细的Excel报告和可视化图表,整个过程只需要几秒钟就能完成,准确率100%。
2. 环境准备与依赖安装
2.1 必需Python库
这个项目依赖于以下几个关键Python库:
- pandas:用于数据处理和Excel读写
- openpyxl:处理新版Excel文件(.xlsx)
- matplotlib:生成可视化图表
安装命令:
bash复制pip install pandas openpyxl matplotlib -i https://pypi.tuna.tsinghua.edu.cn/simple
提示:建议使用清华镜像源加速下载,特别是在国内网络环境下。
2.2 中文字体配置
由于需要处理中文员工姓名和生成中文图表,必须确保系统能正确显示中文字体。脚本中已经内置了字体自动检测逻辑:
python复制def setup_chinese_font():
"""配置matplotlib中文字体"""
try:
# 优先尝试微软雅黑(Windows默认)
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei', 'SimHei', 'DejaVu Sans']
plt.rcParams['axes.unicode_minus'] = False
plt.rcParams['font.family'] = 'sans-serif'
except:
# 备选方案:自动查找系统中文字体
font_paths = fm.findSystemFonts(fontext='ttf')
chinese_fonts = [f for f in font_paths if any(c in f.lower() for c in ['hei', 'yahei', 'song'])]
if chinese_fonts:
font_prop = fm.FontProperties(fname=chinese_fonts[0])
plt.rcParams['font.sans-serif'] = [font_prop.get_name(), 'DejaVu Sans']
3. 核心功能实现
3.1 数据读取与清洗
脚本首先会读取两个工作表的员工数据,并进行必要的数据清洗:
python复制# 读取两个工作表
df1 = pd.read_excel(excel_path, sheet_name=sheet1_name)
df2 = pd.read_excel(excel_path, sheet_name=sheet2_name)
# 去除空值和重复值
df1_clean = df1.dropna(subset=[key_column]).drop_duplicates(subset=[key_column])
df2_clean = df2.dropna(subset=[key_column]).drop_duplicates(subset=[key_column])
注意:key_column参数指定用于比对的字段,默认为"员工号",可以根据实际情况修改为"身份证号"、"工号"等其他唯一标识字段。
3.2 集合运算比对
使用Python的集合操作高效完成数据比对:
python复制# 获取两个表的关键字段集合
set1 = set(df1_clean[key_column].astype(str))
set2 = set(df2_clean[key_column].astype(str))
# 计算交集、差集
common = set1 & set2 # 两个表都有的
only_in_sheet1 = set1 - set2 # 仅Sheet1有的
only_in_sheet2 = set2 - set1 # 仅Sheet2有的
这种方法的比对效率极高,即使处理上万条记录也能在秒级完成。
3.3 结果输出
3.3.1 Excel报告
脚本会生成包含以下工作表的Excel报告:
- 比对汇总:各类人数的统计概览
- 仅在Sheet1:只在第一个表存在的员工详情
- 仅在Sheet2:只在第二个表存在的员工详情
- 两个表都有:两个表共有的员工详情
python复制with pd.ExcelWriter(output_excel, engine='openpyxl') as writer:
# 汇总表
summary_df = pd.DataFrame({
'项目': ['Sheet1总人数', 'Sheet2总人数', '两个表都有', '仅Sheet1有', '仅Sheet2有'],
'数量': [
result['total_sheet1'],
result['total_sheet2'],
result['common_count'],
result['only_sheet1_count'],
result['only_sheet2_count']
]
})
summary_df.to_excel(writer, sheet_name='比对汇总', index=False)
# 各分类数据
df_only1.to_excel(writer, sheet_name='仅在Sheet1', index=False)
df_only2.to_excel(writer, sheet_name='仅在Sheet2', index=False)
df_common.to_excel(writer, sheet_name='两个表都有', index=False)
3.3.2 可视化图表
自动生成两种图表:
- 饼图:展示三类人员的比例分布
- 柱状图:对比两个表的各类人数
python复制# 饼图:人员分布比例
pie_labels = ['仅Sheet1', '仅Sheet2', '两个表都有']
pie_sizes = [len(only_in_sheet1), len(only_in_sheet2), len(common)]
ax1.pie(pie_sizes, labels=pie_labels, autopct='%1.1f%%', startangle=90)
# 柱状图:数量对比
bar_x = ['总人数', '独有人员', '共有人员']
bar_sheet1 = [result['total_sheet1'], result['only_sheet1_count'], result['common_count']]
bar_sheet2 = [result['total_sheet2'], result['only_sheet2_count'], result['common_count']]
4. 使用示例与实战技巧
4.1 基础使用方法
python复制result = compare_two_sheets(
excel_path='人员比对.xlsx', # Excel文件路径
sheet1_name='Sheet1', # 第一个工作表名
sheet2_name='Sheet2', # 第二个工作表名
key_column='员工号', # 比对的字段名
output_excel='人员比对报告.xlsx', # 输出报告路径
output_image='人员比对图表.png' # 输出图表路径
)
4.2 实战技巧
-
处理大型文件:当处理超过10万条记录时,可以添加chunksize参数分块读取:
python复制df1 = pd.read_excel(excel_path, sheet_name=sheet1_name, chunksize=10000) -
多字段比对:如果需要同时比对多个字段(如员工号+姓名),可以修改为:
python复制key_columns = ['员工号', '姓名'] df1_clean = df1.dropna(subset=key_columns).drop_duplicates(subset=key_columns) -
性能优化:对于超大型Excel文件,可以考虑先导出为CSV再处理,速度能提升5-10倍。
5. 常见问题排查
5.1 中文字符显示问题
如果图表中的中文显示为方框:
- 确保系统安装了中文字体(如微软雅黑)
- 在代码中明确指定字体路径:
python复制plt.rcParams['font.sans-serif'] = ['Microsoft YaHei'] # 指定微软雅黑
5.2 文件路径错误
如果遇到文件不存在错误:
- 检查文件路径是否包含中文或特殊字符
- 使用原始字符串表示路径:
python复制excel_path = r'C:\data\人员比对.xlsx'
5.3 内存不足
处理特大文件时可能出现内存不足:
- 使用dtype参数指定列数据类型减少内存占用
python复制df1 = pd.read_excel(excel_path, dtype={'员工号': 'str'}) - 只读取需要的列:
python复制df1 = pd.read_excel(excel_path, usecols=['员工号', '姓名'])
6. 脚本优化建议
-
添加日志记录:使用logging模块记录运行过程,方便排查问题
python复制import logging logging.basicConfig(filename='compare.log', level=logging.INFO) -
支持命令行参数:使用argparse模块支持命令行调用
python复制import argparse parser = argparse.ArgumentParser() parser.add_argument('--input', help='输入Excel文件路径') args = parser.parse_args() -
增加邮件发送功能:自动将结果发送到指定邮箱
python复制import smtplib from email.mime.multipart import MIMEMultipart
这个Python脚本已经在我所在公司的人力资源部门使用了2年多,累计处理了超过500次员工数据比对任务,准确率100%,平均每次节省2小时人工核对时间。特别是在每月考勤结算和年度人力盘点时,这个工具发挥了巨大价值。