人力资源部每个月发工资条,以前靠人工手动一条一条的复制,200多号员工,差不多需要耗费一天时间。

用python写个脚本,分分钟的事情就可以全部发送完。

我这边工资表如下图

姓名在C列,邮箱在B列。

发送完,这样显示

收到的邮件是这样

还有这样

# !/usr/bin/env python
# -*- coding:utf-8 -*-
# Author:Hiuhung Wan from openpyxl import load_workbook
from email.mime.text import MIMEText # 邮件正文
from email.header import Header # 邮件头
import smtplib, time # 登录
def login(smtp_server, ssl_port, sender, passwd):
smtp_obj = smtplib.SMTP_SSL(smtp_server, ssl_port)
smtp_obj.login(sender, passwd)
return smtp_obj # 发邮件
def send_email(smtp_obj, sender, rec_list, msg):
smtp_obj.sendmail(sender, rec_list, msg) def op_excel(smtp_obj, filename:str):
# 加载excel文件 data_only=True,自动计算公式
wb = load_workbook(filename, data_only=True) # 使用xlsx文件,不要使用xls
sheet = wb.active # 先取列名
table_col_name = []
for row in sheet.rows:
for cell in row:
# print(cell.value)
table_col_name.append(cell.value)
break # 循环excel
for row in sheet.iter_rows(min_row=2):
table_col_html = '<thead>' # 表头
row_text = '<tr>' # 开始一行
list_del = [] # 准备减掉的字段
list_finally = table_col_name[:] # 最终的字段
for cell in row:
# print(cell.value, type(cell.value)) # None <class 'NoneType'> 0 <class 'int'>
if cell.value == None or cell.value == 0: # 数据为零或空
# print(cell.col_idx) # 列数,从1开始数
list_del.append(table_col_name[cell.col_idx - 1])
else:
row_text += f'<td>{cell.value}</td>'
row_text += '</tr>' # 结束一行 # 去掉值为零或空的字段
for i in list_del:
list_finally.remove(i) # 重写首行
for i in list_finally:
table_col_html += f'<th>{i}</th>'
table_col_html += '</thead>' # 员工姓名
name = row[2].value # 从0开始数,第2列
staff_email = row[1].value # 员工邮箱地址 从0开始数,第1列 mail_body_context = f'''<h3>{name}:你好!</h3>
<p>请查收你2020年5月的工资条。</p>
<table border="1px solid black">
{table_col_html}
{row_text}
</table>
'''
msg = MIMEText(mail_body_context, 'html', 'utf-8') msg['From'] = Header('HHHH人力资源部', 'utf-8') # 发送者
msg['To'] = Header('HHHH员工', 'utf-8') # 接收者
msg['Subject'] = Header('HHHH 2020年5月工资条', 'utf-8') # 主题 # 发邮件
try:
send_email(smtp_obj, sender, [staff_email], msg.as_string())
print(f'成功发送工资条到{staff_email}--{name}...')
except smtplib.SMTPException as e:
print('Error:无法发送邮件.Case:%s' % e) if __name__ == '__main__':
time_start = time.time() smtp_server = 'smtp.qq.com' # SMTP服务器
ssl_port = 465 # SMTP端口
sender = '123456789@qq.com' # 发件人邮箱
passwd = '**********' # 发件人密码
filename = "2020年5月员工工资表.xlsx" smtp_obj = login(smtp_server, ssl_port, sender, passwd)
op_excel(smtp_obj, filename)
time_end = time.time()
print('脚本执行完毕,耗时%.3f秒。' % (time_end - time_start))

  支持自动去掉值为空或为零的列。如奖金、请假等。

当然,也可以竖向排列工资条。

需要修改一下op_excel方法

def op_excel(smtp_obj, filename: str):                   # 操作表格
# 加载excel文件 data_only=True,自动计算公式
wb = load_workbook(filename, data_only=True) # 使用xlsx文件,不要使用xls
sheet = wb.active # 先取列名
table_col_name = []
for row in sheet.rows:
for cell in row:
# print(cell.value)
table_col_name.append(cell.value)
break # 循环excel
for row in sheet.iter_rows(min_row=2):
# table_col_html = '<thead>' # 表头
row_text = ''
list_del = [] # 准备减掉的字段
list_finally = table_col_name[:] # 最终的字段
list_money = [] # 金额
for cell in row:
# print(cell.value, type(cell.value)) # None <class 'NoneType'>
# 0 <class 'int'>
if cell.value is None or cell.value == 0: # 数据为零或空
# print(cell.col_idx) # 列数,从1开始数
list_del.append(table_col_name[cell.col_idx - 1])
else:
list_money.append(cell.value) # 去掉值为零或空的字段
for i in list_del:
list_finally.remove(i) # 员工姓名
name = row[1].value # 从0开始数,第2列
staff_email = row[2].value # 员工邮箱地址 从0开始数,第1列 # <tr>添充
for index in range(len(list_finally)):
# print(list_finally[index],list_money[index])
row_text += '<tr>' # 开始一行
row_text += f'<td>{list_finally[index]}</td>'
row_text += f'<td>{list_money[index]}</td>'
row_text += '</tr>' # 结束一行 mail_body_context = f'''<h3>{name}:你好!</h3>
<p>请查收你2020年5月的工资条。</p>
<table border="1px solid black">
<thead>
<th>项目</th>
<th>值</th>
</thead>
{row_text}
</table>
'''
msg = MIMEText(mail_body_context, 'html', 'utf-8') msg['From'] = Header('HHHH人力资源部', 'utf-8') # 发送者
msg['To'] = Header('HHHH员工', 'utf-8') # 接收者
msg['Subject'] = Header('HHHH 2020年5月工资条', 'utf-8') # 主题 # 发邮件
try:
send_email(smtp_obj, sender, [staff_email], msg.as_string())
print(f'成功发送工资条到{staff_email}--{name}...')
except smtplib.SMTPException as e:
print('Error:无法发送邮件.Case:%s' % e)

  效果如下

源码参考了alex在B站的分享。

https://www.bilibili.com/video/BV1UK4y1t7Ui?t=1395

  

使用python自动发放员工工资条到个人邮箱的更多相关文章

  1. Python自动补全

    转自:http://blog.linuxeye.com/324.html Python自动补全有vim编辑下和python交互模式下,下面分别介绍如何在这2种情况下实现Tab键自动补全. 一.vim ...

  2. linux终端python自动提示

    linux终端python自动提示 很多时候,在linux下编写python时, 都懒得去vi一个新文件,直接就新开一个终端, 进入python命令行模式,然后就可以写一些测试代码. 不过最悲剧的就是 ...

  3. 从用python自动生成.h的头文件集合和类声明集合到用python读写文件

    最近在用python自动生成c++的类.因为这些类会根据需求不同产生不同的类,所以需要用python自动生成.由于会产生大量的类,而且这些类是变化的.所以如果是在某个.h中要用include来加载这些 ...

  4. python自动安装mysql5.7

    python自动安装mysql5.7 python版本:python2.6 centos版本:centos6.9 mysql版本:mysql5.7.19 安装目录路径和数据目录路径都是固定,当然也可以 ...

  5. python 自动发现Java端口

    python 自动发现Java端口 #!/usr/bin/env python #encoding: utf8 import subprocess try: import json except Im ...

  6. 用Python自动发送邮件

    用Python自动发送邮件     最近需要在服务器上处理一些耗时比较长的任务,因此想到利用python写一个自动发送邮件的脚本,在任务执行完毕后发送邮件通知我.以下代码以163邮箱为例: 开通163 ...

  7. python自动安装mysql5.7【转】

    #!/usr/bin/env python import os import sys import re base_dir = '/opt/software/mysql-5.7.17-linux-gl ...

  8. Python 自动补全(vim)

    一.vim python自动补全插件:pydiction 可以实现下面python代码的自动补全: 1.简单python关键词补全 2.python 函数补全带括号 3.python 模块补全 4.p ...

  9. Python自动发布Image service的实现

    使用Python自动发布地图服务已经在上一篇博客中讲到,使用Python创建.sd服务定义文件,实现脚本自动发布ArcGIS服务,下面是利用Python自动发布Image service的实现. -- ...

随机推荐

  1. python使用泛型

    所谓的泛型, 就是将数据类型作为参数进行传递, 即在我们用的时候确定数据类型, 这是一种在面向对象语言中经常使用的特性 一般类使用 以SQLAlchemy举例 比如: 我们统一写个将数据保存到数据库的 ...

  2. JAVA8学习——新的时间日期API&Java8总结

    JAVA8-时间日期API java8之前用过的时间日期类. Date Calendar SimpleDateFormat 有很多致命的问题. 1.没有时区概念 2.计算麻烦,实现困难 3.类是可变的 ...

  3. Spring的AOP的底层实现原理?

    aop是ioc的一个扩展功能,先有的ioc,再有的aop,只是在ioc的整个流程中新增的一个扩展点而已:BeanPostProcessor 底层实现用的是动态代理 AOP应用场景 场景一: 记录日志 ...

  4. pytest--fixture基本使用(主要用来进行测试环境的初始化和清理,fixture中的params参数还可以用来进行参数化)

    fixture fixture修饰器来标记固定的工厂函数,在其他函数,模块,类或整个工程调用它时会被激活并优先执行,通常会被用于完成预置处理和重复操作. 方法: fixture(scope=" ...

  5. 巧用 CSS 把图片马赛克化

    一.image-rendering 介绍 CSS 中有一个有趣的特性叫 image-rendering,它可以通过算法来更好地显示被缩放的图片. 假设我们有一张尺寸较小的二维码截图(下方左),将其放大 ...

  6. C# Semaphore 信号量 锁 简单理解

    信号量(Semaphore) Semaphore 一般译作 信号量,它也是一种线程同步工具,主要用于多个线程对共享资源进行并行操作的一种工具类.它代表了一种许可的概念,是否允许多线程对同一资源进行操作 ...

  7. 数据结构与算法入门系列教程-C#

    数据结构与算法入门系列教程 (一)为啥要学习数据结构与算法 曾经我也以为自己很牛逼,工作中同事也觉得我还可以,领导也看得起我,啥啥啥都好,就这样过了几年,忽然发现自己学新东西没劲.时代都变了,而我还只 ...

  8. Solon 1.6.30 发布,更现代感的应用开发框架

    相对于 Spring Boot 和 Spring Cloud 的项目 启动快 5 - 10 倍 qps 高 2- 3 倍 运行时内存节省 1/3 ~ 1/2 打包可以缩小到 1/2 ~ 1/10(比如 ...

  9. Python中的dotenv的详细用法

    最简单和最常见的用法是在应用程序启动时调用load_dotenv,从当前目录或其父目录中的.env文件或指定的路径加载环境变量,然后你可以调用os.getenv提供的与环境相关的方法. .env 文件 ...

  10. 题目要求:传入数组 内容为[['lisi','男','27'],['wangwu','男',18],['zhaoliu','男','30']],将此二维数组转化为一维数组,创建自定义函数完成

    //自定义函数 function getOne($arr){ $str = ''; //定义空的字符串,用来接收值 foreach ($arr as $key=>$value){ //循环遍历数 ...