好友
阅读权限10
听众
最后登录1970-1-1
|
本帖最后由 ytfty 于 2023-9-2 11:29 编辑
声明本人学python 不过几周,程序写的很烂,但这个程序确实己应用于生产环境中。。。。。而且很好使。
原创区发不上去,我太懒了,连图都不想去截屏。
说一下功能吧:
第一、用程序读 一张excel 表(里面是所有人的工资) 然后根据每行最后对定的邮箱 发送当前行的数据。重新编写为 html格式的(发附件也行需要改程序,不如这个简单效率高,这个高指的是不用管理员去更新程序,理论上用多少年都没问题)。
第二、发完了抄自己一份证明谁发了谁没发,还可以从发送目录里找txt的记录核对。
说一下注意事项吧
第一、test.xlsx 里面的列不可更改,如更改需要对应更改程序。每行最后一个邮箱一定要根同行的人保证对了,不然你发错工资条出了问题,可别怪我没提醒。
第二 、win7 系统会提示缺少很多组件,我的解决办法是更换了win10系统。主要是懒。所以你们财务要是说这个不行,您了慢慢折腾。
第三、程序可以使用 pyinstaller -c -i favicon -F sentpay.py 命令打包成 exe格式 favicon.ico 可以换成自己的图标。
本人干工程的,就是工地搬砖那种,要是谁嫌这个LOW谁自己改去,主打就是一个凑合能用就行。
我想弄一个测试邮箱,126是真不行,我们用的是QQ的,所以我又去申请了个QQ,结果,哎~! 14天后才能开启。上传附件不能超3M,只放了源文件上来。
所以就不放测试了
[Python] 纯文本查看 复制代码 #引用系统操作模块
import os
# 导入邮件发送方法
import smtplib
from email.mime.text import MIMEText # 邮件正⽂
from email.header import Header # 邮件头
# 引入时间方法
import datetime
import time
now_time = datetime.datetime.now() # 获得当前时间
pay_month = datetime.datetime.now() - datetime.timedelta(28)
sent_time = time.time()
#声明文件
print(f'''
****************************************************************************************
使用说明:
1、用于财务部门发送工资条。
2、Excel模板 文件名和文件格式不能更改(不能加列可以加行,不能出现合并单元格)
3、执行完成后会自动退出,并生成log.log 日志文件和 X年X月记录X.xls文件。
生成文件目的是用于记录和检测正确性,可以删除或移走备份。
4、使用过程中如有问题请联系管理员 ytfty
Create by ytfty
****************************************************************************************
''')
# 引入openpyxl 模块 加载 excel (只读)
from openpyxl import load_workbook
#判断文件是否存在 请把test.xlsx 换成自己的
if os.path.exists("test.xlsx"):
wb = load_workbook("test.xlsx", data_only=True)
sheet = wb.active
else:
input("数据文件 test.xlsl 不存在,请检查后重新运行本程序,程序结束,按回车退出程序")
exit()
# 登录邮件服务器
smtp_obj = smtplib.SMTP_SSL("smtp.exmail.qq.com", 465) # 发件⼈邮箱中的SMTP服务器这里我们用的是QQ企业邮箱,可以换成自己的,端⼝是25
smtp_obj.login("财务邮箱或专门发工资的人的邮箱@企业邮箱.com", "授权码") # 括号中对应的是发件⼈邮箱账号、邮箱密码,现在大部分邮箱要求使用授权码而不是密码。
# 从第2行开始按行循环遍历数据到内存
for row in sheet.iter_rows(min_row=2):
row_text = "" # 初始化一条空的行数据
mail_content = "" # 初始化邮件内容为空值,防止带错数据。
for cell in row:
#绑定内容单元格
num = row[0] # 序号
department = row[1] # 部门
name = row[2] # 姓名
join_time = row[3] # 入职时间
join_time_day = join_time.value # 取入职时间年月日
work_age = row[4] # 工龄
work_leve = row[5] # 岗位级别
base_pay = row[6] # 底薪
age_pay = row[7] # 工龄工资
job_subsidy = row[8] # 岗位津贴
skills_subsidy = row[9] # 技能津贴
mangement_subsidy = row[10] # 管理津贴
full_subsidy = row[11] # 全勤津贴
cert_subsidy = row[12] # 证书补助
computer_subsidy = row[13] # 电脑补助
whit_personal_leave = row[14] # 事假扣发
buckle_perfect_attendance = row[15] # 全勤扣发
gross_salary = row[16] # 税前应发
accumulation_fund_base = row[17] # 公积金基数
insurance_base = row[18] # 保险基数
whitholding_accumulation = row[19] # 代扣公积金
whitholding_pension_insurance = row[20] # 代扣养老保险
whitholding_medical_insurance = row[21] # 代扣医疗保险
whitholding_unemployment_insurance = row[22] # 代扣待业保险
withholding_large_amount_of_medical_treatment = row[23] # 代扣大额医疗
whitholding_total = row[24] # 扣发合计金额
temporary_bonuses = row[25] # 临时奖金
tax_base = row[26] # 个税基数
personal_income_tax = row[27] # 个人所得税
adjust = row[28] # 调整
trade_union_dues = row[29] # 工会会费
real_wages = row[30] # 实发工资
email = row[31] # 邮箱
personal_email = row[31].value
# 构建邮件内容
mail_content = f'''
<p> {name.value} 你好!{pay_month.year}年{pay_month.month}月工资表 </p>
<table width="95%" style="border-collapse: collapse; margin: 0 auto; text-align: center ">
<caption>
<h2> {name.value}{pay_month.year}年{pay_month.month}月工资表</h2>
</caption>
<thead>
<tr style="background: #3271AE; color: #FFF; font-size: 16px;">
<th style="border: 1px solid #cad9ea; height: 30px;">
序号
</th>
<th style="border: 1px solid #cad9ea; height: 30px;">
部门
</th>
<th style="border: 1px solid #cad9ea; height: 30px;">
姓名
</th>
<th style="border: 1px solid #cad9ea; height: 30px;">
入职时间
</th>
<th style="border: 1px solid #cad9ea; height: 30px;">
工龄
</th>
<th style="border: 1px solid #cad9ea; height: 30px;">
岗位级别
</th>
<th style="border: 1px solid #cad9ea; height: 30px;">
底薪
</th>
<th style="border: 1px solid #cad9ea; height: 30px;">
工龄工资
</th>
<th style="border: 1px solid #cad9ea; height: 30px;">
岗位津贴
</th>
<th style="border: 1px solid #cad9ea; height: 30px;">
技能津贴
</th>
<th style="border: 1px solid #cad9ea; height: 30px;">
管理津贴
</th>
<th style="border: 1px solid #cad9ea; height: 30px;">
全勤津贴
</th>
<th style="border: 1px solid #cad9ea; height: 30px;">
证书补助
</th>
<th style="border: 1px solid #cad9ea; height: 30px;">
电脑补助
</th>
<th style="border: 1px solid #cad9ea; height: 30px;">
事假扣发
</th>
<th style="border: 1px solid #cad9ea; height: 30px;">
全勤扣发
</th>
<th style="border: 1px solid #cad9ea; height: 30px;">
税前应发总额
</th>
<th style="border: 1px solid #cad9ea; height: 30px;">
公积金基数
</th>
<th style="border: 1px solid #cad9ea; height: 30px;">
保险基数
</th>
<th style="border: 1px solid #cad9ea; height: 30px;">
代扣公积金
</th>
<th style="border: 1px solid #cad9ea; height: 30px;">
代扣养老保险
</th>
<th style="border: 1px solid #cad9ea; height: 30px;">
代扣医疗保险
</th>
<th style="border: 1px solid #cad9ea; height: 30px;">
代扣待业保险
</th>
<th style="border: 1px solid #cad9ea; height: 30px;">
代扣大额医疗
</th>
<th style="border: 1px solid #cad9ea; height: 30px;">
扣发合计金额
</th>
<th style="border: 1px solid #cad9ea; height: 30px;">
临时奖金
</th>
<th style="border: 1px solid #cad9ea; height: 30px;">
个税基数
</th>
<th style="border: 1px solid #cad9ea; height: 30px;">
个人所得税
</th>
<th style="border: 1px solid #cad9ea; height: 30px;">
调整
</th>
<th style="border: 1px solid #cad9ea; height: 30px;">
工会会费
</th>
<th style="border: 1px solid #cad9ea; height: 30px;">
实发工资
</th>
</tr>
</thead>
<tr>
<td style="border: 1px solid #cad9ea; height: 30px;">
{num.value}
</td>
<td style="border: 1px solid #cad9ea; height: 30px;">
{department.value}
</td>
<td style="border: 1px solid #cad9ea; height: 30px;">
{name.value}
</td>
<td style="border: 1px solid #cad9ea; height: 30px;">
{join_time_day.year}-{join_time_day.month}-{join_time_day.day}
</td>
<td style="border: 1px solid #cad9ea; height: 30px;">
{work_age.value}
</td>
<td style="border: 1px solid #cad9ea; height: 30px;">
{work_leve.value}
</td>
<td style="border: 1px solid #cad9ea; height: 30px;">
{base_pay.value}
</td>
<td style="border: 1px solid #cad9ea; height: 30px;">
{age_pay.value}
</td>
<td style="border: 1px solid #cad9ea; height: 30px;">
{job_subsidy.value}
</td>
<td style="border: 1px solid #cad9ea; height: 30px;">
{skills_subsidy.value}
</td>
<td style="border: 1px solid #cad9ea; height: 30px;">
{mangement_subsidy.value}
</td>
<td style="border: 1px solid #cad9ea; height: 30px;">
{full_subsidy.value}
</td>
<td style="border: 1px solid #cad9ea; height: 30px;">
{cert_subsidy.value}
</td>
<td style="border: 1px solid #cad9ea; height: 30px;">
{computer_subsidy.value}
</td>
<td style="border: 1px solid #cad9ea; height: 30px;">
{whit_personal_leave.value}
</td>
<td style="border: 1px solid #cad9ea; height: 30px;">
{buckle_perfect_attendance.value}
</td>
<td style="border: 1px solid #cad9ea; height: 30px;">
{gross_salary.value}
</td>
<td style="border: 1px solid #cad9ea; height: 30px;">
{accumulation_fund_base.value}
</td>
<td style="border: 1px solid #cad9ea; height: 30px;">
{insurance_base.value}
</td>
<td style="border: 1px solid #cad9ea; height: 30px;">
{whitholding_accumulation.value}
</td>
<td style="border: 1px solid #cad9ea; height: 30px;">
{whitholding_pension_insurance.value}
</td>
<td style="border: 1px solid #cad9ea; height: 30px;">
{whitholding_medical_insurance.value}
</td>
<td style="border: 1px solid #cad9ea; height: 30px;">
{whitholding_unemployment_insurance.value}
</td>
<td style="border: 1px solid #cad9ea; height: 30px;">
{withholding_large_amount_of_medical_treatment.value}
</td>
<td style="border: 1px solid #cad9ea; height: 30px;">
{whitholding_total.value}
</td>
<td style="border: 1px solid #cad9ea; height: 30px;">
{temporary_bonuses.value}
</td>
<td style="border: 1px solid #cad9ea; height: 30px;">
{tax_base.value}
</td>
<td style="border: 1px solid #cad9ea; height: 30px;">
{personal_income_tax.value}
</td>
<td style="border: 1px solid #cad9ea; height: 30px;">
{adjust.value}
</td>
<td style="border: 1px solid #cad9ea; height: 30px;">
{trade_union_dues.value}
</td>
<td style="border: 1px solid #cad9ea; height: 30px;">
{real_wages.value}
</td>
</tr>
</table>
'''
# 设置邮件头信息
msg = MIMEText(mail_content, "html", "utf-8")
msg["From"] = Header("财务发件人名", "utf-8") # 发件人可以是人名可以是代号比如财务
msg["To"] = Header(f"{personal_email}", "utf-8") # 收件人
msg["Cc"] = Header("这里写财务或是老板的邮箱@qq.com", "utf-8") # 抄送 主要是核实是否会因为机器卡顿而发送不成功。
msg["Subject"] = Header(f"{name.value} {pay_month.year}年{pay_month.month}月份工资条", "utf-8") # 主题
# 发送邮件
smtp_obj.sendmail("财务邮箱@qq.com", [personal_email,'抄送人的邮箱@qq.com'], msg.as_string()) #可以抄送给多人
# 写日志
f = open(file='sentlog.log', mode='a', encoding='utf-8')
f.write(f"发送时间:{now_time} 收件人:{name.value} 邮件地址:{personal_email} 邮件主题:{pay_month.year}年{pay_month.month}月份工资表记录 己发送\n")
f.close()
print(f'''发送时间 {now_time} 收件人:{name.value} 邮件地址:{personal_email} 邮件主题:{pay_month.year}年{pay_month.month}月份工资表记录 己发送''')
#另存一份记录
wb.save(f"{pay_month.year}年{pay_month.month}月份工资表记录{sent_time}.xlsx")
wait = input("程序执行完毕,按回车键退出!")
|
免费评分
-
查看全部评分
|
发帖前要善用【论坛搜索】功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。 |
|
|
|
|