I had a project where I needed to generate some draft emails programmatically in Outlook.
Inserting the company logo and some content related images took some googling to sort through. Ideally I wanted to encode the images as Base64 strings, but Outlook does not allow this.
The code below has some html I took from an existing email. Interpolating strings into html and, worse, hand editing it, is probably not best practice, but for purposes of this demo, it works. Also, there may be more abstracted tools and libraries for working with Outlook. I'm used to using win32com, so that is my general go-to tool for Microsoft Office and other historically significant desktop Windows apps.
Screenshot of draft email that script generates:
Code:
"""
Demo of how to embed a picture in a Microsoft Outlook email.
"""
import win32com.client as win32
PR_ATTACH_CONTENT_ID = 'http://schemas.microsoft.com/mapi/proptag/0x3712001F'
PR_ATTACHMENT_HIDDEN = 'http://schemas.microsoft.com/mapi/proptag/0x7FFE000B'
PICLOC = r'C:\Users\carl.trachte\Documents\paintbrush.png'
BODYFORMAT = """
<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv=Content-Type content="text/html; charset=us-ascii">
<meta name=Generator content="Microsoft Word 15 (filtered medium)">
<!--[if !mso]>
<style>v\:* {{behavior:url(#default#VML);}}
o\:* {{behavior:url(#default#VML);}}
w\:* {{behavior:url(#default#VML);}}
.shape {{behavior:url(#default#VML);}}
</style>
<![endif]-->
<style>
<!--
/* Font Definitions */
@font-face
{{font-family:"Cambria Math";
panose-1:2 4 5 3 5 4 6 3 2 4;}}
@font-face
{{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;}}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{{margin:0in;
font-size:11.0pt;
font-family:"Calibri",sans-serif;}}
span.EmailStyle17
{{mso-style-type:personal-compose;
font-family:"Calibri",sans-serif;
color:windowtext;}}
.MsoChpDefault
{{mso-style-type:export-only;
font-family:"Calibri",sans-serif;}}
@page WordSection1
{{size:8.5in 11.0in;
margin:1.0in 1.0in 1.0in 1.0in;}}
div.WordSection1
{{page:WordSection1;}}
-->
</style>
<!--[if gte mso 9]>
<xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml>
<![endif]--><!--[if gte mso 9]>
<xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout>
</xml>
<![endif]-->
</head>
<body lang=EN-US link="#0563C1" vlink="#954F72" style='word-wrap:break-word'>
<div class=WordSection1>
<table class=MsoNormalTable border=0 cellspacing=0 cellpadding=0 style='margin-left:-1.5pt;border-collapse:collapse'>
<tr style='height:14.5pt'>
</tr>
</table>
{0:s}
<p class=MsoNormal>
<o:p> </o:p>
</p>
<p class=MsoNormal>
<o:p> </o:p>
</p>
</div>
</div>
</body>
</html>"""
GRAPHICFRAME = """
<div class=WordSection1>
<p class=MsoNormal>
<o:p> </o:p>
</p>
<p class=MsoNormal>
<o:p> </o:p>
</p>
<p class=MsoNormal>
<b>
<o:p> </o:p>
</b>
</p>
<p class=MsoNormal>
<o:p> </o:p>
</p>
<p class=MsoNormal>
<img width=410 height=410 style='width:4.2666in;height:4.2666in' id="Picture_x0020_2" src="cid:{0:s}" alt="Chart Description automatically generated">
<o:p></o:p>
</p>
<p class=MsoNormal>
<o:p> </o:p>
</p>
<p class=MsoNormal>
<o:p> </o:p>
</p>
"""
def getoutlook():
"""
Return Outlook object.
"""
return win32.gencache.EnsureDispatch('outlook.application')
def makeemail(outlookobject, text, subject, recipient):
"""
Return e-mail object
"""
mail = outlookobject.CreateItem(0)
mail.To = recipient
mail.Subject = subject
mail.HTMLBody = text
return mail
def addlogoshow(mailobject):
"""
Embed cid image in e-mail.
Save e-mail and bring up in window.
"""
attachmnt = mailobject.Attachments.Add(PICLOC, win32.constants.olByValue, 0, 'paintbrush.png')
attachmnt.PropertyAccessor.SetProperty(PR_ATTACH_CONTENT_ID, 'paintbrush.png')
attachmnt.PropertyAccessor.SetProperty(PR_ATTACHMENT_HIDDEN, False)
mailobject.Save()
mailobject.Display()
mailobject.Save()
outlook = getoutlook()
htmlbody = BODYFORMAT.format(GRAPHICFRAME.format('paintbrush.png'))
mail = makeemail(outlook, htmlbody, 'blah', 'XXXXXXXX@gmail.com')
addlogoshow(mail)