Skip to main content
 首页 » 编程设计

python之如何使用 smtp 发送 html 电子邮件内嵌的 plot.ly 图像

2025年02月15日31pander-it

我正在自动生成几个双周报告,所以我决定使用 plot.ly 创建一个线图。此线图具有不同数量的轨迹,具体取决于正在运行的报告。
我已经能够成功地创建绘图,但我发现的所有方法都无法在我的电子邮件中内联显示绘图。 这是我的代码:

SMTP_SERVER = "smtp.office365.com" 
SMTP_PORT = 587 
SMTP_USERNAME = username 
SMTP_PASSWORD = password 
EMAIL_TO = email_to 
EMAIL_FROM = email_from 
 
#here we loop through our data-set and pull out rows to make different traces 
for deal in winGraph['DEAL_IDENTIFIER'].unique(): 
    matched_rows = winGraph.loc[winGraph['DEAL_IDENTIFIER'] == deal] 
    date = matched_rows.DATE.tolist() 
    winRate = matched_rows.WIN_RATE.tolist() 
    traces.append( 
                 go.Scatter( 
                            x = date, 
                            y = winRate, 
                            name = str(deal) 
                             ) 
                  ) 
plotly.tools.set_credentials_file(username = 'username', api_key = 'api_key')                         
fig = dict(data = traces) 
 
imageURL = py.plot(fig,auto_open = False, filename = 'test' ) 
 
msg = MIMEMultipart('related') 
msg['Subject'] = Header(u"Hello", 'utf-8') 
msg['From'] = EMAIL_FROM 
msg['To'] = EMAIL_TO 
msg_alternative = MIMEMultipart('alternative') 
msg.attach(msg_alternative) 
 
msg_text =  MIMEText(u'[image: {title}]'.format(**img), 'plain', 'utf-8') 
msg_alternative.attach(msg_text) 
html = u"""\ 
<html> 
<head></head> 
<body style="background-color:#DDDDDD; font-family: calibri;"> 
<p> 
<img src="cid:{cid}" alt="{alt}"><br> 
   Hi!<br> 
   How are you?<br> 
   Below is a summary of your performance 
   <br> 
   Top 5 Deals: 
   {df} 
 
   Please review:<br> 
   The following graph represents your deals win rate over the past two weeks: 
   <br> 
   Look at attached spreadsheet for more info. <br> 
   <img src="data:image/png;base64,{image}"> 
   </a> 
   <br> 
</p> 
</body> 
</html> 
""" 
 
response = requests.get(imageURL + '.png') # request Plotly for the image 
response.raise_for_status() 
image_bytes = response.content 
image = base64.b64encode(image_bytes) 
 
html = html.format( df = topAdv.to_html(index = False, escape = False),image = image,alt=cgi.escape(img['title'], quote=True),**img) 
part2 = MIMEText(html, 'html', 'utf-8') 
 
msg_alternative.attach(part2) 
 
with open(img['path'], 'rb') as file: 
    msg_image = MIMEImage(file.read(), name=os.path.basename(img['path'])) 
    msg.attach(msg_image) 
msg_image.add_header('Content-ID', '<{}>'.format(img['cid'])) 
 
mail = smtplib.SMTP(SMTP_SERVER, SMTP_PORT) 
mail.ehlo() 
mail.starttls() 
mail.login(SMTP_USERNAME, SMTP_PASSWORD) 
mail.sendmail(EMAIL_FROM, EMAIL_TO, msg.as_string()) 
mail.quit() 

请您参考如下方法:

除了在 plotly 的服务器上渲染绘图并将其嵌入为 png,您还可以尝试将绘图直接嵌入为 HTML/SVG/JavaScript(假设现在大多数电子邮件客户端都可以处理它,因为浏览器)用于显示电子邮件的渲染引擎)使用 plotly 的离线功能。我猜人们会喜欢剧情的互动功能......

from plotly.offline import plot 
# Generate your plotly figure as fig 
div = plot( 
    fig, 
    output_type = 'div', 
    include_plotlyjs = True 
    ) 

这将为您提供一个字符串,其中包含您的绘图和包含在 div 标签中的所需 JavaScript。