Mail Merge with DataTable and Object

The following example shows how to use the GemBox.Email library to perform a mail merge to generate multiple personalized emails, using DataTable as a data source.

using GemBox.Email;
using System.Collections.Generic;
using System.Data;

class Program
{
    static void Main()
    {
        // If using the Professional version, put your serial key below.
        ComponentInfo.SetLicense("FREE-LIMITED-KEY");

        // Create template message.
        MailMessage template = new MailMessage("sender@example.com");
        template.Subject = "%FirstName%, check our new offer!";
        template.BodyHtml =
@"<div>
Dear <strong>%Title% %LastName%</strong><br/><br/>
Check out our new offer on this <a href=""%link%"">link</a>.<br/>
<span style=""color:red;font-size:90%"">Visit us today and get additional %discount%% discount!</span><br/><br/>
Sincerely Yours,<br/>
Special Store<br/><br/>
<span style=""color:gray;font-size:80%"">This email was sent to <a href=""mailto:%To%"">%To%</a>.</span>
</div>";

        // Create data source.
        DataTable data = new DataTable();
        data.Columns.Add("To", typeof(string));
        data.Columns.Add("Title", typeof(string));
        data.Columns.Add("FirstName", typeof(string));
        data.Columns.Add("LastName", typeof(string));
        data.Columns.Add("Discount", typeof(int));
        data.Columns.Add("Link", typeof(string));

        // Fill data source with some data.
        data.Rows.Add("jonh@example.com", "Mr.", "John", "Doe", 10, "https://example.com/check.html?name=John");
        data.Rows.Add("jane@example.com", "Mrs.", "Jane", "Doe", 20, "https://example.com/check.html?name=Jane");
        data.Rows.Add("joe@example.com", "Mr.", "Joe", "Unknown", 15, "https://example.com/check.html?name=Joe");

        // Perform mail merge operation.
        IList<MailMessage> messages = MailMerge.Merge(template, data);

        // Save mail messages.
        for (int i = 0; i < messages.Count; i++)
            messages[i].Save($"Message_{i}.eml");
    }
}
Imports GemBox.Email
Imports System.Collections.Generic
Imports System.Data

Module Program

    Sub Main()

        ' If using the Professional version, put your serial key below.
        ComponentInfo.SetLicense("FREE-LIMITED-KEY")

        ' Create template message.
        Dim template As New MailMessage("sender@example.com")
        template.Subject = "%FirstName%, check our new offer!"
        template.BodyHtml =
"<div>
Dear <strong>%Title% %LastName%</strong><br/><br/>
Check out our new offer on this <a href=""%link%"">link</a>.<br/>
<span style=""color:red;font-size:90%"">Visit us today and get additional %discount%% discount!</span><br/><br/>
Sincerely Yours,<br/>
Special Store<br/><br/>
<span style=""color:gray;font-size:80%"">This email was sent to <a href=""mailto:%To%"">%To%</a>.</span>
</div>"

        ' Create data source.
        Dim data As New DataTable()
        data.Columns.Add("To", GetType(String))
        data.Columns.Add("Title", GetType(String))
        data.Columns.Add("FirstName", GetType(String))
        data.Columns.Add("LastName", GetType(String))
        data.Columns.Add("Discount", GetType(String))
        data.Columns.Add("Link", GetType(String))

        ' Fill data source with some data.
        data.Rows.Add("jonh@example.com", "Mr.", "John", "Doe", 10, "https://example.com/check.html?name=John")
        data.Rows.Add("jane@example.com", "Mrs.", "Jane", "Doe", 20, "https://example.com/check.html?name=Jane")
        data.Rows.Add("joe@example.com", "Mr.", "Joe", "Unknown", 15, "https://example.com/check.html?name=Joe")

        ' Perform mail merge operation.
        Dim messages As IList(Of MailMessage) = GemBox.Email.MailMerge.Merge(template, data)

        ' Save mail messages.
        For i As Integer = 0 To messages.Count - 1
            messages(i).Save($"Message_{i}.eml")
        Next
    End Sub
End Module
Generating unique emails with mail merge in C# and VB.NET
Screenshot of unique emails created with mail merge

Mail merge is a process of creating multiple personalized email messages based on a single message template and a data source. The template message contains fixed text, which will be the same in every output message, and variables, which represent placeholders that values from a data source will replace.

You can execute a mail merge by using the MailMerge.Merge method. Once started, the template message is cloned for every DataRow in the DataTable data source, but with the variables replaced by values from the current row.

It's also possible to use the MailMessage object as a template message, where MailMessage.Subject, MailMessage.BodyText, MailMessage.BodyHtml, and body of any MailMessage.MimeEntity.Headers can contain fixed text and variables.

Variables are defined as %<ValueName>%. The value name can contain letters or digits, without any whitespace, and must start and end with the '%' character.

%To%, %Cc%, %Bcc% and %ReplyTo% are predefined value names you can use to set the corresponding properties in the output message. All predefined names are optional except %To% since it represents the recipient's email address.

Mail Merge with Object

The following example shows how to use the GemBox.Email library to perform a mail merge to generate multiple personalized emails using a custom object as a data source.

using GemBox.Email;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        // If using the Professional version, put your serial key below.
        ComponentInfo.SetLicense("FREE-LIMITED-KEY");

        // Create template message.
        MailMessage template = new MailMessage("sender@example.com");
        template.Subject = "%FirstName%, check our new offer!";
        template.BodyHtml =
@"<div>
Dear <strong>%Title% %LastName%</strong><br/><br/>
Check out our new offer on this <a href=""%link%"">link</a>.<br/>
<span style=""color:red;font-size:90%"">Visit us today and get additional %discount%% discount!</span><br/><br/>
Sincerely Yours,<br/>
Special Store<br/><br/>
<span style=""color:gray;font-size:80%"">This email was sent to <a href=""mailto:%To%"">%To%</a>.</span>
</div>";

        // Create data source.
        List<DataObject> data = new List<DataObject>()
        {
            new DataObject("jonh@example.com", "Mr.", "John", "Doe", 10, "https://example.com/check.html?name=John"),
            new DataObject("jane@example.com", "Mrs.", "Jane", "Doe", 20, "https://example.com/check.html?name=Jane"),
            new DataObject("joe@example.com", "Mr.", "Joe", "Unknown", 15, "https://example.com/check.html?name=Joe")
        };

        // Perform mail merge.
        IList<MailMessage> messages = MailMerge.Merge(template, data);

        // Save mail messages.
        for (int i = 0; i < messages.Count; i++)
            messages[i].Save($"Message_{i}.eml");
    }

    // Custom data source type.
    class DataObject
    {
        public string To { get; }
        public string Title { get; }
        public string FirstName { get; }
        public string LastName { get; }
        public int Discount { get; }
        public string Link { get; }

        public DataObject(string to, string title, string firstName, string lastName, int discount, string link)
        {
            this.To = to;
            this.Title = title;
            this.FirstName = firstName;
            this.LastName = lastName;
            this.Discount = discount;
            this.Link = link;
        }
    }
}
Imports GemBox.Email
Imports System.Collections.Generic

Module Program

    Sub Main()
        ' If using the Professional version, put your serial key below.
        ComponentInfo.SetLicense("FREE-LIMITED-KEY")

        ' Create template message.
        Dim template As New MailMessage("sender@example.com")
        template.Subject = "%FirstName%, check our new offer!"
        template.BodyHtml =
"<div>
Dear <strong>%Title% %LastName%</strong><br/><br/>
Check out our new offer on this <a href=""%link%"">link</a>.<br/>
<span style=""color:red;font-size:90%"">Visit us today and get additional %discount%% discount!</span><br/><br/>
Sincerely Yours,<br/>
Special Store<br/><br/>
<span style=""color:gray;font-size:80%"">This email was sent to <a href=""mailto:%To%"">%To%</a>.</span>
</div>"

        ' Create data source.
        Dim data As New List(Of DataObject) From
        {
            New DataObject("jonh@example.com", "Mr.", "John", "Doe", 10, "https://example.com/check.html?name=John"),
            New DataObject("jane@example.com", "Mrs.", "Jane", "Doe", 20, "https://example.com/check.html?name=Jane"),
            New DataObject("joe@example.com", "Mr.", "Joe", "Unknown", 15, "https://example.com/check.html?name=Joe")
        }

        ' Perform mail merge operation.
        Dim messages As IList(Of MailMessage) = GemBox.Email.MailMerge.Merge(template, data)

        ' Save mail messages.
        For i As Integer = 0 To messages.Count - 1
            messages(i).Save($"Message_{i}.eml")
        Next
    End Sub

    Class DataObject
        Public ReadOnly Property [To] As String
        Public ReadOnly Property Title As String
        Public ReadOnly Property FirstName As String
        Public ReadOnly Property LastName As String
        Public ReadOnly Property Discount As Integer
        Public ReadOnly Property Link As String

        Public Sub New([to] As String, title As String, firstName As String, lastName As String, discount As Integer, link As String)
            Me.To = [to]
            Me.Title = title
            Me.FirstName = firstName
            Me.LastName = lastName
            Me.Discount = discount
            Me.Link = link
        End Sub
    End Class

End Module
Generating unique emails with mail merge in C# and VB.NET
Screenshot of unique emails created with mail merge

GemBox.Email uses reflection to retrieve values for variable replacement.

To avoid reflection usage, you can wrap your custom type with the IMailMergeDataSource interface implementation and use a wrapper object as the mail merge data source instead of your original object. In that case, the mail merge engine will only use members from your IMailMergeDataSource implementation to retrieve the required values.

See also


Next steps

GemBox.Email is a .NET component that enables you to read, write, receive, and send emails from your .NET applications using one simple API.

Download Buy