Convert Emails to PDF in C# and VB.NET
With GemBox.Email you can read emails from EML, MHT, and MSG formats.
With GemBox.Document you can write documents in formats like PDF and XPS.
By combining these components, you can convert email messages to PDF files from your C# or VB.NET application.
The following example shows how you can save the body of an email as a PDF file by retrieving the MailMessage
content and creating a DocumentModel
from it.

using System.Linq;
using System.Text.RegularExpressions;
using GemBox.Document;
using GemBox.Email;
using GemBox.Email.Mime;
class Program
{
static void Main()
{
// If using Professional version, put your GemBox.Email serial key below.
GemBox.Email.ComponentInfo.SetLicense("FREE-LIMITED-KEY");
// If using Professional version, put your GemBox.Document serial key below.
GemBox.Document.ComponentInfo.SetLicense("FREE-LIMITED-KEY");
// Load an email file.
MailMessage message = MailMessage.Load("%InputFileName%");
// Create a new document.
DocumentModel document = new DocumentModel();
// Import the email's body to the document.
LoadBody(message, document);
// Save the document as PDF.
document.Save("Export.pdf");
}
static void LoadBody(MailMessage message, DocumentModel document)
{
if (!string.IsNullOrEmpty(message.BodyHtml))
// Load the HTML body to the document.
document.Content.End.LoadText(
ReplaceEmbeddedImages(message.BodyHtml, message.Attachments),
LoadOptions.HtmlDefault);
else
// Load the TXT body to the document.
document.Content.End.LoadText(
message.BodyText,
LoadOptions.TxtDefault);
}
// Replace attached CID images to inlined DATA urls.
static string ReplaceEmbeddedImages(string htmlBody, AttachmentCollection attachments)
{
var srcPattern =
"(?<=<img.+?src=[\"'])" +
"(.+?)" +
"(?=[\"'].*?>)";
// Iterate through the "src" attributes from HTML images in reverse order.
foreach (var match in Regex.Matches(htmlBody, srcPattern, RegexOptions.IgnoreCase).Cast<Match>().Reverse())
{
var imageId = match.Value.Replace("cid:", "");
Attachment attachment = attachments.FirstOrDefault(a => a.ContentId == imageId);
if (attachment != null)
{
// Create inlined image data. E.g. "data:image/png;base64,AABBCC..."
ContentEntity entity = attachment.MimeEntity;
var embeddedImage = entity.Charset.GetString(entity.Content);
var embeddedSrc = $"data:{entity.ContentType};{entity.TransferEncoding},{embeddedImage}";
// Replace the "src" attribute with the inlined image.
htmlBody = $"{htmlBody.Substring(0, match.Index)}{embeddedSrc}{htmlBody.Substring(match.Index + match.Length)}";
}
}
return htmlBody;
}
}
Imports System.Linq
Imports System.Text.RegularExpressions
Imports GemBox.Document
Imports GemBox.Email
Imports GemBox.Email.Mime
Module Program
Sub Main()
' If using Professional version, put your GemBox.Email serial key below.
GemBox.Email.ComponentInfo.SetLicense("FREE-LIMITED-KEY")
' If using Professional version, put your GemBox.Document serial key below.
GemBox.Document.ComponentInfo.SetLicense("FREE-LIMITED-KEY")
' Load an email file.
Dim message As MailMessage = MailMessage.Load("%InputFileName%")
' Create a new document.
Dim document As DocumentModel = New DocumentModel()
' Import the email's body to the document.
LoadBody(message, document)
' Save the document as PDF.
document.Save("Export.pdf")
End Sub
Sub LoadBody(message As MailMessage, document As DocumentModel)
If Not String.IsNullOrEmpty(message.BodyHtml) Then
' Load the HTML body to the document.
document.Content.End.LoadText(
ReplaceEmbeddedImages(message.BodyHtml, message.Attachments),
LoadOptions.HtmlDefault)
Else
' Load the TXT body to the document.
document.Content.End.LoadText(
message.BodyText,
LoadOptions.TxtDefault)
End If
End Sub
' Replace attached CID images to inlined DATA urls.
Function ReplaceEmbeddedImages(htmlBody As String, attachments As AttachmentCollection) As String
Dim srcPattern =
"(?<=<img.+?src=[""'])" &
"(.+?)" &
"(?=[""'].*?>)"
' Iterate through the "src" attributes from HTML images in reverse order.
For Each match In Regex.Matches(htmlBody, srcPattern, RegexOptions.IgnoreCase).Cast(Of Match)().Reverse()
Dim imageId = match.Value.Replace("cid:", "")
Dim attachment As Attachment = attachments.FirstOrDefault(Function(a) a.ContentId = imageId)
If attachment IsNot Nothing Then
' Create inlined image data. E.g. "data:image/png;base64,AABBCC..."
Dim entity As ContentEntity = attachment.MimeEntity
Dim embeddedImage = entity.Charset.GetString(entity.Content)
Dim embeddedSrc = $"data:{entity.ContentType};{entity.TransferEncoding},{embeddedImage}"
' Replace the "src" attribute with the inlined image.
htmlBody = $"{htmlBody.Substring(0, match.Index)}{embeddedSrc}{htmlBody.Substring(match.Index + match.Length)}"
End If
Next
Return htmlBody
End Function
End Module
Besides exporting only the email's body, you can also export its headers and attachments. The following example shows how you can save an email to a PDF file together with the email's image attachments by retrieving them from the MailMessage.Attachments
collection and appending them to the DocumentModel
content.

using System.Linq;
using System.Text.RegularExpressions;
using GemBox.Document;
using GemBox.Email;
using GemBox.Email.Mime;
class Program
{
static void Main()
{
// If using Professional version, put your GemBox.Email serial key below.
GemBox.Email.ComponentInfo.SetLicense("FREE-LIMITED-KEY");
// If using Professional version, put your GemBox.Document serial key below.
GemBox.Document.ComponentInfo.SetLicense("FREE-LIMITED-KEY");
// Load an email file.
MailMessage message = MailMessage.Load("%InputFileName%");
// Create a new document.
DocumentModel document = new DocumentModel();
// Import the email's content to the document.
LoadHeaders(message, document);
LoadBody(message, document);
LoadAttachments(message.Attachments, document);
// Save the document as PDF.
document.Save("Export.pdf");
}
static void LoadHeaders(MailMessage message, DocumentModel document)
{
// Create HTML content from the email headers.
var htmlHeaders = $@"
<style>
* {{ font-size: 12px; font-family: Calibri; }}
th {{ text-align: left; padding-right: 24px; }}
</style>
<table>
<tr><th>From:</th><td>{message.From[0].ToString().Replace("<", "<").Replace(">", ">")}</td></tr>
<tr><th>Sent:</th><td>{message.Date:dddd, d MMM yyyy}</td></tr>
<tr><th>To:</th><td>{message.To[0].ToString().Replace("<", "<").Replace(">", ">")}</td></tr>
<tr><th>Subject:</th><td>{message.Subject}</td></tr>
</table>
<hr>";
// Load the HTML headers to the document.
document.Content.End.LoadText(htmlHeaders, LoadOptions.HtmlDefault);
}
static void LoadBody(MailMessage message, DocumentModel document)
{
if (!string.IsNullOrEmpty(message.BodyHtml))
// Load the HTML body to the document.
document.Content.End.LoadText(
ReplaceEmbeddedImages(message.BodyHtml, message.Attachments),
LoadOptions.HtmlDefault);
else
// Load the TXT body to the document.
document.Content.End.LoadText(
message.BodyText,
LoadOptions.TxtDefault);
}
// Replace attached CID images to inlined DATA urls.
static string ReplaceEmbeddedImages(string htmlBody, AttachmentCollection attachments)
{
var srcPattern =
"(?<=<img.+?src=[\"'])" +
"(.+?)" +
"(?=[\"'].*?>)";
// Iterate through the "src" attributes from HTML images in reverse order.
foreach (var match in Regex.Matches(htmlBody, srcPattern, RegexOptions.IgnoreCase).Cast<Match>().Reverse())
{
var imageId = match.Value.Replace("cid:", "");
Attachment attachment = attachments.FirstOrDefault(a => a.ContentId == imageId);
if (attachment != null)
{
// Create inlined image data. E.g. "data:image/png;base64,AABBCC..."
ContentEntity entity = attachment.MimeEntity;
var embeddedImage = entity.Charset.GetString(entity.Content);
var embeddedSrc = $"data:{entity.ContentType};{entity.TransferEncoding},{embeddedImage}";
// Replace the "src" attribute with the inlined image.
htmlBody = $"{htmlBody.Substring(0, match.Index)}{embeddedSrc}{htmlBody.Substring(match.Index + match.Length)}";
}
}
return htmlBody;
}
static void LoadAttachments(AttachmentCollection attachments, DocumentModel document)
{
var htmlSubtitle = "<hr><p style='font: bold 12px Calibri;'>Attachments:</p>";
document.Content.End.LoadText(htmlSubtitle, LoadOptions.HtmlDefault);
foreach (Attachment attachment in attachments.Where(
a => a.DispositionType == ContentDispositionType.Attachment &&
a.MimeEntity.ContentType.TopLevelType == "image"))
{
document.Content.End.InsertRange(
new Paragraph(document, new Picture(document, attachment.Data)).Content);
}
}
}
Imports System.Linq
Imports System.Text.RegularExpressions
Imports GemBox.Document
Imports GemBox.Email
Imports GemBox.Email.Mime
Module Program
Sub Main()
' If using Professional version, put your GemBox.Email serial key below.
GemBox.Email.ComponentInfo.SetLicense("FREE-LIMITED-KEY")
' If using Professional version, put your GemBox.Document serial key below.
GemBox.Document.ComponentInfo.SetLicense("FREE-LIMITED-KEY")
' Load an email file.
Dim message As MailMessage = MailMessage.Load("%InputFileName%")
' Create a new document.
Dim document As DocumentModel = New DocumentModel()
' Import the email's content to the document.
LoadHeaders(message, document)
LoadBody(message, document)
LoadAttachments(message.Attachments, document)
' Save the document as PDF.
document.Save("Export.pdf")
End Sub
Sub LoadHeaders(message As MailMessage, document As DocumentModel)
' Create HTML content from the email headers.
Dim htmlHeaders = $"
<style>
* {{ font-size: 12px; font-family: Calibri; }}
th {{ text-align: left; padding-right: 24px; }}
</style>
<table>
<tr><th>From:</th><td>{message.From(0).ToString().Replace("<", " <").Replace(">", ">")}</td></tr>
<tr><th>Sent:</th><td>{message.Date:dddd, d MMM yyyy}</td></tr>
<tr><th>To:</th><td>{message.To(0).ToString().Replace("<", "<").Replace(">", ">")}</td></tr>
<tr><th>Subject:</th><td>{message.Subject}</td></tr>
</table>
<hr>"
' Load the HTML headers to the document.
document.Content.End.LoadText(htmlHeaders, LoadOptions.HtmlDefault)
End Sub
Sub LoadBody(message As MailMessage, document As DocumentModel)
If Not String.IsNullOrEmpty(message.BodyHtml) Then
' Load the HTML body to the document.
document.Content.End.LoadText(
ReplaceEmbeddedImages(message.BodyHtml, message.Attachments),
LoadOptions.HtmlDefault)
Else
' Load the TXT body to the document.
document.Content.End.LoadText(
message.BodyText,
LoadOptions.TxtDefault)
End If
End Sub
' Replace attached CID images to inlined DATA urls.
Function ReplaceEmbeddedImages(htmlBody As String, attachments As AttachmentCollection) As String
Dim srcPattern =
"(?<=<img.+?src=[""'])" &
"(.+?)" &
"(?=[""'].*?>)"
' Iterate through the "src" attributes from HTML images in reverse order.
For Each match In Regex.Matches(htmlBody, srcPattern, RegexOptions.IgnoreCase).Cast(Of Match)().Reverse()
Dim imageId = match.Value.Replace("cid:", "")
Dim attachment As Attachment = attachments.FirstOrDefault(Function(a) a.ContentId = imageId)
If attachment IsNot Nothing Then
' Create inlined image data. E.g. "data:image/png;base64,AABBCC..."
Dim entity As ContentEntity = attachment.MimeEntity
Dim embeddedImage = entity.Charset.GetString(entity.Content)
Dim embeddedSrc = $"data:{entity.ContentType};{entity.TransferEncoding},{embeddedImage}"
' Replace the "src" attribute with the inlined image.
htmlBody = $"{htmlBody.Substring(0, match.Index)}{embeddedSrc}{htmlBody.Substring(match.Index + match.Length)}"
End If
Next
Return htmlBody
End Function
Sub LoadAttachments(attachments As AttachmentCollection, document As DocumentModel)
Dim htmlSubtitle = "<hr><p style='font: bold 12px Calibri;'>Attachments:</p>"
document.Content.End.LoadText(htmlSubtitle, LoadOptions.HtmlDefault)
For Each attachment As Attachment In attachments.Where(
Function(a) a.DispositionType = ContentDispositionType.Attachment AndAlso
a.MimeEntity.ContentType.TopLevelType = "image")
document.Content.End.InsertRange(
New Paragraph(document, New Picture(document, attachment.Data)).Content)
Next
End Sub
End Module
It's also possible to add other email attachments to the resulting PDF, not just the images. For this, you'll need to combine other GemBox components as well.
Every GemBox component supports different types of files (for instance, GemBox.Spreadsheet supports formats like XLSX, XLS and GemBox.Presentation supports formats like PPTX, PPT). Also, every GemBox component supports PDF and images as an output format.
So, by combining GemBox components you can convert all email attachments of any supported file format to PDF or image files and append them to the resulting PDF file.