如何使用 smtp 发送内联 html 电子邮件的 plot.ly 图像?
问题描述
我正在自动化一些双周报告,因此我决定使用 plot.ly 创建线图.根据正在运行的报告,此线图具有不同数量的跟踪.
我已经能够成功创建绘图,但我发现的任何方法都无法在我的电子邮件中内联显示绘图.这是我的代码:
I'm automating a couple of bi-weekly reports so I've decided to use plot.ly to create a line plot. This line plot has a varying amount of traces depending on the report that is being run.
I've been able to create plots successfully but none of the methods I've found have worked for displaying the plot inline in my email.
Here is my code:
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 的离线功能来处理它.我猜人们会喜欢剧情的互动性……
Instead of rendering the plot on plotly's servers and embedding it as an png, you can also try to embed the plot directly as HTML/SVG/JavaScript (assuming that most e-mail clients these days can deal with it due to browser rendering engines used for displaying emails) using plotly's offline capabilities. I guess people will like the interactive features of the plot ...
from plotly.offline import plot
# Generate your plotly figure as fig
div = plot(
fig,
output_type = 'div',
include_plotlyjs = True
)
这将为您提供一个字符串,其中包含您的绘图和包含在 div 标记中的所需 JavaScript.
This will give you a string containing your plot and the required JavaScript wrapped in a div-tag.
相关文章