基于Python的高校勤工俭学工资管理系统
1 需求概述
1.1 需求分析
勤工俭学是指学校组织的或学生个人从事的有酬劳动,用以助学。在我国,许多高校借以对学生进行劳动技术教育,培养正确的劳动观点和态度,养成自立、自强、艰苦奋斗等良好思想作风;加强理论与实际联系,掌握一定的生产知识和劳动技能,而学生以个人所得劳动报酬弥补和解决部分学习与生活费用。
目前,部分高校对于勤工俭学的工资发放依旧采用excel表格记录操作,以纸质版时长登记表登记时长,统计工资。
基于高校勤工俭学工资管理系统的需求,简约excel表格的登记操作,为此开发出基于Python的高校勤工俭学工资管理系统,实现以系统图形界面对excel表格直接操作,实现办公自动化。
此项目满足需求如下:
- 统一友好的操作界面,具有良好的用户体验。
- 系统操作简单化,将程序打包成可直接操作的可执行软件。
- 用户可以通过选择操作模板表格,对表格进行功能实现操作。
- 用户可以通过图形界面实现对excel表格的增删改查操作。
- 用户可以通过系统实现自动化办公。
- 用户可以通过系统实现邮件的发送。
- 系统运行安全稳定且响应及时。
1.2 功能结构
为了方便管理,将每个重要的功能需求方向确定为一个子系统。根据不同的功能需求方向,将软件划分为以下七个子系统功能模块:
- 信息汇总功能
- 读取信息功能
- 添加与删除员工功能
- 修改员工时薪
- 增加工资明细项
- 生成年度工资汇总表
- 自动化发送邮件
2 系统(模块)设计
2.1 Excel表格模板设计
为了统一勤工工资管理的excel表格模板,在工资总表中引入4个sheet子表,分别为“总表”、“值班工作量”“加班工作量”“活动工作量”。
1、 sheet1——总表:用于保存员工信息以及工资类目、工资统计,如图1所示。
2、 sheet2——值班工作量:用于保存员工每天的值班工作量信息,如图2所示。
3、 sheet3——加班工作量:用于保存员工每天的加班工作量信息,如图3所示。
4、 sheet4——活动工作量:用于保存员工每天的活动工作量信息,如图4所示。
2.2 计算公式设计
- 值班总时长 = sum (每月1~31日的值班时长)
- 加班总时长 = sum (每月1~31日的加班时长)
- 活动总时长 = sum (每月1~31日的活动时长)
- 业务工作量 = 值班总时长 + 加班总时长
- 总工资 = 业务工作量 * 实际工资薪资 + 活动总时长 *
- 活动工资薪资 + 附加工资类目
2.3 七大功能模块设计
2.3.1 信息汇总功能
分别从值班、加班、活动工作量表中读取值班总时长、加班总时长、活动总时长的信息,填充到总表中,实现信息的汇总。
2.3.2 读取信息功能
从选择操作的excel表格中读取员工的信息和工作记录,并显示出来,实现信息的读取。
2.3.3 添加与删除员工功能
添加功能:从选择操作的excel表格中读取表格的总行数,选择所要添加员工的位置,通过对员工信息的编辑添加,实现对总表、值班工作量表格、加班工作量表格、活动工作量表格的同步操作。
删除功能:从选择操作的excel表格中读取员工的姓名,通过姓名索引匹对,对员工所有信息进行删除操作,实现对总表、值班工作量表格、加班工作量表格、活动工作量表格的同步操作。
2.3.4 修改员工时薪
修改日常工作时薪:对选择操作的excel表格的日常工作时薪进行修改编辑操作,实现对所有员工薪资的统一更改。
修改活动工作时薪:对选择操作的excel表格的活动工作时薪进行修改编辑操作,实现对所有员工薪资的统一更改。
2.3.5 增加工资明细项
对选择操作的excel表格的活动进行工资明细项的增加操作,实现对所有员工工资类目的修改以及薪资统计。
2.3.6 生成年度工资汇总表
生成年度工资汇总表:对选择操作的excel表格进行信息提取操作,实现对所有员工信息的提取,并生成年度工资汇总表。
月度工资汇总:对选择操作的excel表格的活动进行工资汇总操作,实现对所有员工工资的薪资统计,并提取信息填充年度工资汇总表的每个月度员工工资。
2.3.7 自动化发送邮件
提取员工的员工工资条,并自动发送到员工邮箱中。
2.4 GUI图形界面设计
为了统一友好的操作界面,使用户具有良好的体验,开发中实现了代码的GUI图形界面操作,将七大功能模块通过图形界面实现。
Python对跨平台的GUI工具集Qt的包装实现了440个类以及6000个函数或者方法,PyQt5是作为Python的插件实现的,是比较流行的一个Tkinter的替代品,功能非常强大,可以用PyQt5开发多么漂亮的界面。
鉴于跨平台的支持性与界面美观性,系统的GUI图形界面设计使用PyQt5开发。以主窗口(Main Window)作为应用程序的框架,在主窗口上添加widget,添加菜单,以及使用网格布局(QGridLayout)将窗口分割成行和列的网格来进行排列。
菜单栏包含操作:开始、操作、编辑、更新、帮助、退出,具体层次如图5所示。
3 系统实现
3.1 系统环境搭建
-
系统操作环境:Windows 10 10.0
Python开发版本:Python 3.7.2
JRE环境: 1.8.0_152-release-1343-b28 amd64
JVM版本: OpenJDK 64-Bit Server VM by JetBrains s.r.o -
开发工具:
亿图图示9.2
PyCharm 2018.3.5 (Professional Edition)
Qt Designer 5.11.2 -
使用Python的第三方库:
PyInstaller 3.4
xlwings 0.15.8 (execl开发库)
PyQt5 5.11.3 (GUI图形界面库)
pyqt5-tools 5.11.3.1.4
3.2 设计实现流程
利用xlwings库对execl表格进行操作,根据项目需求设计源代码,实现窗口命令行操作(index_cmd.py)。
通过PyQt5设计GUI图形界面,利用Qt Designer设计好窗口布局,生成.ui文件(C语言),通过PyUIC将UI文件转换成.py文件(Python语言),最后对代码进行整改,生成图形界面操作代码文件(index_qt5.py)。
最后通过pyinstaller将项目打包生成.exe可执行文件(index_qt5.exe),项目完成,进行后期维护。
5 总结
在确定做基于Python的高校勤工俭学工资管理系统课题项目后,便对项目的需求进行分析,确定的具体实现的功能与模块设计。首先要确定开发最基本的功能库——实现对execl的操作功能。目前处理excel得python包十分多,主流代表有:xlwings、openpyxl、pandas、win32com、Xlsxwriter、DataNitro、xlutils等。
win32com 不仅仅是excel,可以处理office;
xlwings 简单强大,可替代VBA
xlsxwriter 丰富多样的特性,直接创造一份美观大方的excel,代码即一切;
DataNitro 作为插件内嵌到excel中,可替代VBA,在excel中优雅的使用python
pandas 使用需要结合其他库,数据处理是pandas立身之本
openpyxl 简单易用,功能广泛
xlutils 结合xlrd/xlwt,老牌python包,需要注意的是你必须同时安装这三个库
基于项目本身的需求性,我决定利用xlwings库对execl表格进行操作,根据项目需求设计源代码,实现窗口命令行操作(index_cmd.py)。
在安装pyinstaller的过程中,出现安装失败的问题,通过查阅资料,4003跟6163的错误最简单的解决方法是:pip install --no-use-pep517 pyinstaller。
最后通过pyinstaller将项目打包生成.exe可执行文件(index_qt5.exe),在这个过程中,会出现部分库无法调用,最简单的方法是在命令行窗口直接用“pip install ***”安装最新的库,因为在Pycharm里安装的库在外部有时候无法调用。
从零基础入门的第一个项目,很多功能不完成,代码的结构也很混乱,仅供参考,不可直接抄袭使用!
6 附录1
6.1 命令窗口实现源代码(index_cmd.py)
# index_cmd.py
def
import xlwings as excel
import pandas as pd
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.header import Header
wb = excel.App(visible=False,add_book=False).books.open(r"D:\python\untitled\工资总表.xlsx")
#系统操作选择
def work():
print("系统操作:")
print("1、从值班、加班、活动工作量表中读取信息,填充总表")
print("2、从excel中读取员工信息,工作记录等")
print("3、添加与删除员工")
print("4、修改员工工资")
print("5、增加工资明细项")
print("6、生成年度工资汇总表(2019年度工资汇总表.xls,……)")
print("7、提取员工工资条,并自动发送到员工邮箱中")
print("8、保存所有操作")
#表格操作
def start():
sheet01 = excel.sheets["总表"]
sheet02 = excel.sheets["值班工作量"]
sheet03 = excel.sheets["加班工作量"]
sheet04 = excel.sheets["活动工作量"]
# 表格sheet01的总行数、总列数
nrows01 = sheet01.used_range.last_cell.row
ncols01 = sheet01.used_range.last_cell.column
# 表格sheet02的总行数、总列数
nrows02 = sheet02.used_range.last_cell.row
ncols02 = sheet02.used_range.last_cell.column
# 表格sheet03的总行数、总列数
nrows03 = sheet03.used_range.last_cell.row
ncols03 = sheet03.used_range.last_cell.column
# 表格sheet03的总行数、总列数
nrows04 = sheet04.used_range.last_cell.row
ncols04 = sheet04.used_range.last_cell.column
# excel表格列操作数组
arr = (
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'V', 'W','X','Y', 'Z', 'AA', 'AB', 'AC', 'AD', 'AE', 'AF', 'AG', 'AH')
def restart():
work()
operation = input("请选择您的操作:")
# 操作1、从值班、加班、活动工作量表中读取信息,填充总表
if eval(operation) == 1:
#从值班工作量表中读取信息,填充总表
list02=sheet02.range('AH1').expand('down').value
sheet01.range('F1').options(transpose=True).value =list02
# 从加班工作量表中读取信息,填充总表
list03 = sheet03.range('AH1').expand('down').value
sheet01.range('G1').options(transpose=True).value = list03
#从值活动工作量表中读取信息,填充总表
list04=sheet04.range('AH1').expand('down').value
sheet01.range('K1').options(transpose=True).value =list04
print("操作完成")
print("\n")
wb.save()
restart()
#操作2、从excel中读取员工信息,工作记录等
elif eval(operation) == 2:
for j in range(0, ncols01):
b = str(sheet01.range(arr[j] + str(1)).value)
print("{0:<8}".format(b),end="")
print("\n")
for i in range(2,nrows01+1):
for j in range(0,ncols01):
a = str(sheet01.range(arr[j] + str(i)).value)
print("{0:{1}<8s}".format(a,chr(12288)),end="")
print("\n")
print("操作完成")
print("\n")
#表格输出操作可用下行代码:
# print(sheet01.range('A1').options(pd.DataFrame, expand='table').value)
restart()
# 3.添加与删除员工;
elif eval(operation) == 3:
def work3():
print("添加与删除员工操作:")
print("1、添加员工")
print("2、删除员工")
print("请选择您的操作;")
op2 = input()
#添加员工2
if eval(op2) == 1:
print("请输入工资序号:")
add01 = input()
sheet01.range('A'+str(nrows01+1)).value = add01
sheet02.range('A' + str(nrows02 + 1)).value = add01
sheet03.range('A' + str(nrows03 + 1)).value = add01
sheet04.range('A' + str(nrows04 + 1)).value = add01
print("请输入员工姓名:")
add02 = input()
sheet01.range('B' + str(nrows01 + 1)).value = add02
sheet02.range('B' + str(nrows02 + 1)).value = add02
sheet03.range('B' + str(nrows03 + 1)).value = add02
sheet04.range('B' + str(nrows04 + 1)).value = add02
for o in range(2,ncols01):
print("请输入_{}:".format(sheet01.range(arr[o] + str(1)).value))
add03 = input()
sheet01.range(arr[o] + str(nrows01 + 1)).value = add03
for j in range(0, ncols01):
b = str(sheet01.range(arr[j] + str(1)).value)
print("{0:<8}".format(b), end="")
print("\n")
for i in range(0, ncols01-2):
shuchu = str(sheet01.range(arr[i] + str(nrows01+1)).value)
print("{0:^8}".format(shuchu), end="")
print("\n")
wb.save()
# 删除员工
elif eval(op2) == 2:
print("请输入您要删除的员工名字")
name = input()
for k in range(2, nrows01+1):
if sheet01.range('B' + str(k)).value is None:
break
else:
string = sheet01.range('B' + str(k)).value
if string.find(name):
continue
else:
sheet01.api.Rows(k).Delete()
sheet02.api.Rows(k).Delete()
sheet03.api.Rows(k).Delete()
sheet04.api.Rows(k).Delete()
else:
print("您的选择有误,请从新选择")
work3()
work3()
print("操作完成")
print("\n")
wb.save()
restart()
# 4.修改员工工资;
elif eval(operation) == 4:
def work4():
print("修改员工工资操作:")
print("1、修改日常工作时薪")
print("2、修改活动工作时薪")
print("3、更新修改后的工资总额")
print("请选择您的操作;")
op4 = input()
# 修改日常工作时薪
if eval(op4) == 1:
output01=str(sheet01.range('I' + str(2)).value)
print("现在的日常工作时薪是:"+output01)
print("请输入修改的日常工作时薪是:")
add01 = input()
for j in range(2,nrows01+1):
sheet01.range('I' + str(j)).value = add01
try:
sheet01.range('J' + str(j)).value = float(sheet01.range('H' + str(j)).value) * float(sheet01.range('I' + str(j)).value)
except:
continue
# 修改活动工作时薪
elif eval(op4) == 2:
output02 = str(sheet01.range('L' + str(2)).value)
print("现在的活动工作时薪是:" + o