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.

Convert body of an email message to PDF file in C# and VB.NET
Screenshot of an email body saved as a PDF file
Upload your file (Drag file here)
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.

Convert email body, headers and attachments to PDF file in C# and VB.NET
Screenshot of email content saved as a PDF file
Upload your file (Drag file here)
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("<", "&lt;").Replace(">", "&gt;")}</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("<", "&lt;").Replace(">", "&gt;")}</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("<", " &lt;").Replace(">", "&gt;")}</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("<", "&lt;").Replace(">", "&gt;")}</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.

Want more?

Next example GitHub

Check the next example or select an example from the menu. You can also download our examples from the GitHub.


Like it?

Download Buy

If you want to try the GemBox.Email yourself, you can download the free version. It delivers the same performance and set of features as the professional version, but with some operations limited. To remove the limitation, you need to purchase a license.