python发送excel表格的邮件,python发送电子邮件

本篇文章给大家谈谈python邮件正文表格怎么编辑,以及python发送excel表格的邮件,希望对各位有所帮助,不要忘了收藏本站喔。

【需求】

日常工作中,经常需要制作excel报表,并通过邮件发送出去。

【设计思路】

1、利用Python生成excel及发送邮件;
2、建立一张邮件发送配置表,用来配置所有需要发送的邮件基本信息;再建立一张邮件发送内容表,通过读取配置表数据来生成发送内容表学python编程的书
邮件发送配置表(REP_SEND_CONF):

关键字段说明:
REP_NAME:报表名称                   
EMAIL_TITLE:邮件主题                   
EMAIL_RECEIVER:收件人,多个以逗号分隔                     
EMAIL_CC:抄送人,多个以逗号分隔                     
FREQ:报表发送频率类型,D:天;W:周;M:月;R:按规则。按规则的意思是说报表发送时间不固定,例如需要每周一、三、五发邮件
NUM:报表发送频率间隔,例如每天发邮件,这里就填1           
PROC_BEGIN_TIME:报表生成时间段开始时间,格式:hh24:mi,例如需要每天7:00后才发送邮件,这里就填07:00
PROC_END_TIME :报表生成时间段结束时间,格式:hh24:mi 
LATEST_EXEC_TIME:最近一次生成报表时间       
NEXT_EXEC_TIME:下次生成报表时间。每次生成报表后,根据报表发送频率类型计算下次生成报表的时间,然后每天只处理报表配置表中下次生成报表时间为当天的报表。         
PROC_NAME:调用程序名称。调用数据库存储过程生成邮件正文的HTML,这个字段填存储过程名。               
ERR_MSG:程序运行异常日志           
SEND_CONDITION:报表生成前置条件。这个字段配置一段SQL,返回值为Y或N,标识前置条件是否满足。           
IS_HOLIDAY_SEND:节假日及周末是否发送,Y:是;N:否 
EMAIL_CONTENT:邮件附件文件地址,多个以逗号分隔 
STATUS:状态,Y:有效;N:无效。标识该配置项是否有效。     
OS_TYPE:操作系统类型:Windows,Linux。如果有生成excel,则只能在Windows机器,否则可以在Linux。
PICTURE_ADD:正文图片地址,多个以逗号分隔。邮件正文里面的excel表格数据,全部从excel中截图贴到正文。 
COPY_EMAIL_RECEIVER:复制邮件收件人。同一封邮件,如果需要再重复发一次给不同的人,在这里配置。
COPY_EMAIL_CC:复制邮件抄送人             
NEXT_EXEC_TIME_RULE:下一次运行时间(针对发送频率为按规则发送的报表)

邮件发送内容表(REP_SEND_CONTENT):

关键字段说明:
REP_SEND_CONF_ID:配置表ID。通过此字段与邮件发送配置表关联。         
EMAIL_TITLE:邮件主题。来自于邮件发送配置表。            
EMAIL_RECEIVER :收件人。来自于邮件发送配置表。            
EMAIL_CC:抄送人。来自于邮件发送配置表。                   
EMAIL_TEXT:邮件正文。HTML格式。             
EMAIL_ATTACHMENT:邮件附件地址。多个以逗号分隔。             
SEND_FLAG:发送标记,Y:已发送;N:未发送。初始为N,邮件发送后置为Y。 
OS_TYPE:操作系统类型:Windows,Linux 
PICTURE_ADD:邮件正文引用图片地址,多个以逗号分隔。 

【代码】

1、生成邮件正文HTML(Oracle存储过程)

create or replace procedure rcas.p_get_html(str_l_html out varchar2)
    /**********************************************************************************
    * 名称:p_get_html
    * 功能:生成邮件正文
    **********************************************************************************/
as
    str_l_html_content clob;
begin
    str_l_html_content := '<p>Dear All,</p><p>以下为×××项目日报,请查收,谢谢!</p>
              <p>简报如下:</p><p></p>
              <p>一:日报项一</p>
              <span><img src="cid:p1" /></span>
              <p>明细1</p>
              <span><img src="cid:p2" /></span>
              <p>明细2</p>
              <span><img src="cid:p3" /></span>
              <p>二:日报项二</p>
              <span><img src="cid:p4" /></span>
              <p>明细1</p>
              <span><img src="cid:p5" /></span>
              <p>明细2</p>
              <span><img src="cid:p6" /></span>
              <p>三:日报项三</p>
              <span><img src="cid:p7" /></span>
              <p>四:日报项四</p>
              <span><img src="cid:p8" /></span>
              <p>五:日报项五</p>
              <span><img src="cid:p9" /></span>
              <p>本邮件为自动发送,如有疑问,请与×××联系。</p>';
    str_l_html := str_l_html_content;
   
-- 异常捕获
exception
    when others then
        rollback;
        dbms_output.put_line(sqlerrm);
end p_get_html;

2、读取邮件发送配置表,生成邮件发送内容表数据。(Oracle存储过程)

procedure p_rep_send_content
/**********************************************************************************
* 名称:p_rep_send_content
* 功能:生成报表发送内容
**********************************************************************************/    
as
    str_l_msg_body clob;      -- 邮件正文HTML
    str_l_sql varchar2(100);  -- 执行SQL
    dt_l_next_exec_time date; -- 下一次运行时间
    str_l_flag varchar(32);   -- 前置条件是否满足的标记
begin         
    for c in (select * 
                from rep.rep_send_conf t 
               where t.status = 'Y'
                 and sysdate between to_date(to_char(t.next_exec_time, 'yyyy-mm-dd')|| ' '||t.proc_begin_time,'yyyy-mm-dd hh24:mi:ss')
                 and to_date(to_char(t.next_exec_time, 'yyyy-mm-dd')|| ' '||t.proc_end_time,'yyyy-mm-dd hh24:mi:ss') and t.next_exec_time is not null) loop
        -- 判断前置条件是否满足
        str_l_flag :='Y';                
        if c.send_condition is not null then
            execute immediate c.send_condition into str_l_flag;
        end if;
            
        -- 满足前置条件才发邮件
        if str_l_flag ='Y' then 
            str_l_sql := 'begin '||c.proc_name||'; end;';
            -- 生成邮件正文HTML
            execute immediate str_l_sql using out str_l_msg_body;
            
            -- 邮件正文生成成功的情况下,向邮件发送表写数据
            if str_l_msg_body not like 'Err,%' then                    
                if str_l_msg_body <> 'Not need send' then
                    insert into rep.rep_send_content
                           (REP_SEND_CONF_ID,
                           EMAIL_TITLE,
                           EMAIL_RECEIVER,
                           EMAIL_CC,
                           EMAIL_BCC,
                           EMAIL_TEXT,
                           EMAIL_ATTACHMENT,
                           SEND_FLAG,
                           OS_TYPE,
                           picture_add)
                    values (c.id,
                           c.email_title,
                           c.email_receiver,
                           c.email_cc,
                           c.email_bcc,
                           str_l_msg_body,
                           replace(c.email_content,'$sysdate$',to_char(sysdate,'yyyy-mm-dd')),
                           'N',
                           c.os_type,
                           c.picture_add);
                        
                    -- 复制邮件发送
                    if c.copy_email_receiver is not null then
                        insert into rep.rep_send_content
                               (REP_SEND_CONF_ID,
                               EMAIL_TITLE,
                               EMAIL_RECEIVER,
                               EMAIL_CC,
                               EMAIL_BCC,
                               EMAIL_TEXT,
                               EMAIL_ATTACHMENT,
                               SEND_FLAG,
                               OS_TYPE,
                               picture_add)
                        values (c.id,
                               c.email_title,
                               c.copy_email_receiver,
                               c.copy_email_cc,
                               null,
                               str_l_msg_body,
                               replace(c.email_content,'$sysdate$',to_char(sysdate,'yyyy-mm-dd')),
                               'N',
                               c.os_type,
                               c.picture_add);    
                    end if;
                end if;
                    
                -- 计算下一次执行日期
                -- 按天发送的情况
                if c.freq = 'D' then 
                    -- 判断是否节假日发送
                    if c.is_holiday_send = 'Y' then
                        -- 计算节假日发送情况下的下一次执行日期
                        dt_l_next_exec_time := c.next_exec_time + c.num;
                    else
                        -- 计算节假日不发送情况下的下一次执行日期
                        select nvl(min(t1.days),dt_l_next_exec_time)
                          into dt_l_next_exec_time
                          from rep.bse_calendar t1
                         where t1.days >= c.next_exec_time + c.num
                           and t1.is_holiday = 'N';
                    end if;   
                -- 按规则指定日期发送的情况    
                elsif c.freq = 'R' then
                    execute immediate c.next_exec_time_rule 
                       into dt_l_next_exec_time;                       
                end if; 
                
                -- 更新下一次执行日期
                update rep.rep_send_conf t 
                   set t.next_exec_time = dt_l_next_exec_time,
                       t.latest_exec_time = sysdate,
                       t.err_msg = null
                 where t.id = c.id;
                commit;
            else
                -- 邮件正文生成失败的情况下,记录异常信息
                update rep.rep_send_conf t 
                   set t.err_msg = str_l_msg_body,
                       t.latest_exec_time = sysdate
                 where t.id = c.id;    
                commit;
            end if; 
        end if;                
    end loop;        

-- 异常捕获
exception
    when others then
        rollback;
        dbms_output.put_line(sqlerrm);
end p_rep_send_content;

3、读取邮件发送内容表数据发送Email(Python脚本)

import cx_Oracle
import os
import smtplib #邮件模块
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.image import MIMEImage

#连接Oracle数据库
v_username = '
数据库用户名' #数据库用户名
v_password = '
数据库密码' #数据库密码
v_tns = cx_Oracle.makedsn('
数据库IP', 端口号 , 'SID') #配置Oracle监听
conn = cx_Oracle.connect(v_username, v_password, v_tns)  #连接到Oracle

#获取数据
cursor = conn.cursor()
sql = "select ID,EMAIL_TITLE,EMAIL_RECEIVER,EMAIL_CC,EMAIL_BCC,EMAIL_TEXT,EMAIL_ATTACHMENT,picture_add,'156' from
邮件发送内容表 where os_type = 'Windows' and send_flag = \'N\'"
cursor.execute(sql)
datas = cursor.fetchall()

for d in datas:
    #发送邮件
    s = smtplib.SMTP_SSL("
smtp邮件发送服务器地址",端口号)  # 连接smtp邮件服务器,端口默认是25
    _user = "
发件人邮箱"  # 发件人邮箱
    _pwd = "
发件人邮箱密码"  # 发件人邮箱密码
    s.login(_user, _pwd)  # 登陆服务器
    
    v_subject = d[1] #邮件标题
    v_receiver = d[2] #收件人邮箱,多人用逗号分隔
    v_acc = d[3] #抄送人邮箱,多人用逗号分隔
    v_bcc = d[4] #密送人邮箱,多人用逗号分隔
    v_content = d[5] #邮件正文
    v_attachment = d[6] #邮件附件    
    v_picture = d[7] #邮件正文图片

    # 如名字所示multipart就是分多个部分
    msg = MIMEMultipart('related')
    msg["Subject"] = str(v_subject)  #邮件主题
    msg["From"] = str(_user) #邮件发件人
    msg["To"] = str(v_receiver)+'' #邮件收件人
    msg["Cc"] = str(v_acc)+'' #邮件抄送人
   
    msgAlternative = MIMEMultipart('alternative')
    msg.attach(msgAlternative)    
    content = str(v_content) # 邮件内容,\n是换行符
    msgText = (MIMEText(content,'html','utf-8'))
    msgAlternative.attach(msgText)
    
    #添加图片
    picutre_list = v_picture.split(',')    
    for i in range (0,len(picutre_list)):
        fp  = open(picutre_list[i], 'rb')
        msgImage = MIMEImage(fp.read())
        fp.close()
        msgImage.add_header('Content-ID', '<p'+str(i+1)+'>')
        msg.attach(msgImage)     
    
    #添加附件
    if v_attachment:
        part = MIMEText(open(v_attachment, 'rb').read(), 'base64', 'utf-8')
        part["Content-Type"] = 'application/octet-stream'
        basename = os.path.basename(v_attachment)
        part.add_header('Content-Disposition', 'attachment', filename=('gbk', '', basename) ) #解决中文附件名不能发送的问题,不过目录还是不能为中文
        msg.attach(part)
    
    if not v_acc :
        if not v_bcc:
            s.sendmail(_user, v_receiver.split(','), msg.as_string())
        else:
            s.sendmail(_user, v_receiver.split(',')+v_bcc.split(','), msg.as_string())
    else:
        if not v_bcc:
            s.sendmail(_user, v_receiver.split(',')+ v_acc.split(','), msg.as_string())
        else:
            s.sendmail(_user, v_receiver.split(',')+ v_acc.split(',')+v_bcc.split(','), msg.as_string())

    print('邮件发送成功')
    
    sql = 'update
邮件发送内容表 set send_flag = \'Y\' where id = '+str(d[0])
    cursor.execute(sql)
    conn.commit()
    print('修改成功')
    
    s.close()

if conn:
    #无论如何,连接记得关闭
    conn.close()

完毕。
 

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 要发送邮件给一列中的多个邮箱地址,可以使用 Python 中的 smtplib 和 email 库。以下是一个示例代码,可以发送邮件Excel 表格中的所有收件人。 首先,需要安装 openpyxl 库来读取 Excel 文件。可以使用以下命令进行安装: ``` pip install openpyxl ``` 然后,可以使用以下代码来发送邮件: ```python import openpyxl import smtplib from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart from email.mime.application import MIMEApplication # 邮件参数 smtp_server = 'smtp.xxx.com' # 邮箱SMTP服务器地址 smtp_port = 25 # SMTP服务器端口 email_from = 'sender@example.com' # 发件人邮箱地址 email_pwd = 'password' # 发件人邮箱密码 email_subject = '邮件主题' # 邮件主题 # 读取Excel文件 wb = openpyxl.load_workbook('file.xlsx') ws = wb.active # 遍历Excel表格中的邮箱地址列 for row in ws.iter_rows(min_row=2, max_col=1, values_only=True): email_to = row[0] # 收件人邮箱地址 email_content = '邮件内容' # 邮件内容 # 创建邮件对象 msg = MIMEMultipart() msg['From'] = email_from msg['To'] = email_to msg['Subject'] = email_subject # 添加邮件正文 text = MIMEText(email_content, 'html', 'utf-8') msg.attach(text) # 添加附件 filename = 'attachment.pdf' # 附件文件名 with open(filename, 'rb') as f: attachment = MIMEApplication(f.read(), _subtype='pdf') attachment.add_header('Content-Disposition', 'attachment', filename=filename) msg.attach(attachment) # 发送邮件 server = smtplib.SMTP(smtp_server, smtp_port) server.login(email_from, email_pwd) server.sendmail(email_from, email_to, msg.as_string()) server.quit() ``` 在上面的代码中,将邮件参数替换为实际值,然后将文件名和附件名替换为实际文件名。遍历 Excel 表格中的邮箱地址列时,可以根据需要修改行号和列号。 ### 回答2: 根据Excel中的一列邮箱地址,我们可以借助电子邮件客户端或编程语言的邮件发送功能来发送邮件给对应的收件人。 首先,我们需要访问Excel文件并提取邮箱地址列的数据。可以使用Python的pandas库来读取Excel文件并获取对应列的数据。使用pandas库的read_excel函数可以读取Excel文件并将其转换为DataFrame格式进行进一步操作。 接下来,我们需要使用SMTP协议来发送邮件。SMTP(Simple Mail Transfer Protocol)是用于在网络上发送电子邮件的标准协议。可以使用Python的smtplib库来实现邮件发送功能。 首先,我们需要连接到邮箱的SMTP服务器。这可以通过指定SMTP服务器的主机名和端口号来实现。一般情况下,常用的SMTP服务器是Gmail、Outlook、163等。根据所选SMTP服务器,您需要提供SMTP服务器的主机名和端口号,并使用smtplib库的SMTP函数建立与服务器的连接。 接下来,在连接成功之后,我们需要登录到邮箱账户。您需要提供用于登录的邮箱地址和密码,并使用SMTP对象的login函数进行登录验证。 然后,我们可以通过使用SMTP对象的sendmail函数来发送邮件。我们需要提供发件人、收件人、主题和正文信息。收件人的邮箱地址可以从Excel中获取。 最后,我们需要关闭与SMTP服务器的连接。使用smtplib库的quit函数即可关闭连接。 综上所述,根据Excel其中一列邮箱地址发送邮件给对应人的步骤是:读取Excel文件,提取邮箱地址列数据;连接到SMTP服务器;登录到邮箱账户;使用sendmail发送邮件;关闭与SMTP服务器的连接。 ### 回答3: 根据Excel中的一列邮箱地址发送邮件给对应人是一个常见的应用需求。在Excel中,我们可以通过以下步骤来实现这个目标。 第一步,确保Excel中的邮箱地址列是完整且正确的。如果有任何错误或缺失,需要先进行修正或补全。 第二步,打开一个电子邮件客户端,如Outlook或Gmail。确保你拥有一个有效的发件邮箱。在电子邮件客户端中创建一个新的邮件。 第三步,回到Excel中,选中邮箱地址列的第一个单元格(发件人的邮箱地址)。然后,将该单元格中的邮箱地址复制到剪贴板中。 第四步,回到电子邮件客户端中的新邮件页面,将刚刚复制的邮箱地址粘贴到收件人字段中。 第五步,编写邮件内容,可以根据需要添加附件或格式化文本。确保邮件内容与收件人相关,并以礼貌和明确的方式表达。 第六步,点击发送按钮,将邮件发送给当前的收件人。 第七步,回到Excel中,选中邮箱地址列的下一个单元格(下一个收件人的邮箱地址)。重复第三至第六步,将邮件依次发送给每个收件人。直到所有邮箱地址都发送邮件。 最后,确认所有的邮件都已发送成功。在Excel中,可以标记已发送的邮箱地址或记录已发送的日期和时间,以便于日后追踪和管理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值