MailMergeExecuteWithRegions Method (DataTable)

Performs mail merge from a DataTable into the document with mail merge regions.

Namespace:  Aspose.Words.MailMerging
Assembly:  Aspose.Words (in Aspose.Words.dll) Version: 20.3
Syntax
public void ExecuteWithRegions(
	DataTable dataTable
)

Parameters

dataTable
Type: System.DataDataTable
Data source for the mail merge operation. The table must have its TableName property set.
Remarks

The document must have a mail merge region defined with name that matches DataTable.TableName.

If there are other mail merge regions defined in the document they are left intact. This allows to perform several mail merge operations.

Examples
Shows how to use regions to execute two separate mail merges in one document.
Document doc = new Document();
DocumentBuilder builder = new DocumentBuilder(doc);

// If we want to perform two consecutive mail merges on one document while taking data from two tables
// that are related to each other in any way, we can separate the mail merges with regions
// A mail merge region starts and ends with "TableStart:[RegionName]" and "TableEnd:[RegionName]" MERGEFIELDs
// These regions are separate for unrelated data, while they can be nested for hierarchical data
builder.Writeln("\tCities: ");
builder.InsertField(" MERGEFIELD TableStart:Cities");
builder.InsertField(" MERGEFIELD Name");
builder.InsertField(" MERGEFIELD TableEnd:Cities");
builder.InsertParagraph();

// Both MERGEFIELDs refer to a same column name, but values for each will come from different data tables
builder.Writeln("\tFruit: ");
builder.InsertField(" MERGEFIELD TableStart:Fruit");
builder.InsertField(" MERGEFIELD Name");
builder.InsertField(" MERGEFIELD TableEnd:Fruit");

// Create two data tables that aren't linked or related in any way which we still want in the same document
DataTable tableCities = new DataTable("Cities");
tableCities.Columns.Add("Name");
tableCities.Rows.Add(new object[] { "Washington" });
tableCities.Rows.Add(new object[] { "London" });
tableCities.Rows.Add(new object[] { "New York" });

DataTable tableFruit = new DataTable("Fruit");
tableFruit.Columns.Add("Name");
tableFruit.Rows.Add(new object[] { "Cherry"});
tableFruit.Rows.Add(new object[] { "Apple" });
tableFruit.Rows.Add(new object[] { "Watermelon" });
tableFruit.Rows.Add(new object[] { "Banana" });

// We will need to run one mail merge per table
// This mail merge will populate the MERGEFIELDs in the "Cities" range, while leaving the fields in "Fruit" empty
doc.MailMerge.ExecuteWithRegions(tableCities);

// Run a second merge for the "Fruit" table
// We can use a DataView to sort or filter values of a DataTable before it is merged
DataView dv = new DataView(tableFruit);
dv.Sort = "Name ASC";
doc.MailMerge.ExecuteWithRegions(dv);

doc.Save(ArtifactsDir + "MailMerge.ExecuteWithRegionsConcurrent.docx");
Examples
Demonstrates how to implement custom logic in the MergeField event to apply cell formatting.
public void AlternatingRows()
{
    Document doc = new Document(MyDir + "Mail merge destination - Northwind suppliers.docx");

    // Add a handler for the MergeField event
    doc.MailMerge.FieldMergingCallback = new HandleMergeFieldAlternatingRows();

    // Execute mail merge with regions
    DataTable dataTable = GetSuppliersDataTable();
    doc.MailMerge.ExecuteWithRegions(dataTable);

    doc.Save(ArtifactsDir + "MailMergeEvent.AlternatingRows.docx");
}

private class HandleMergeFieldAlternatingRows : IFieldMergingCallback
{
    /// <summary>
    /// Called for every merge field encountered in the document.
    /// We can either return some data to the mail merge engine or do something
    /// else with the document. In this case we modify cell formatting.
    /// </summary>
    void IFieldMergingCallback.FieldMerging(FieldMergingArgs args)
    {
        if (mBuilder == null)
            mBuilder = new DocumentBuilder(args.Document);

        // This way we catch the beginning of a new row
        if (args.FieldName.Equals("CompanyName"))
        {
            // Select the color depending on whether the row number is even or odd
            Color rowColor = IsOdd(mRowIdx) ? Color.FromArgb(213, 227, 235) : Color.FromArgb(242, 242, 242);

            // There is no way to set cell properties for the whole row at the moment,
            // so we have to iterate over all cells in the row
            for (int colIdx = 0; colIdx < 4; colIdx++)
            {
                mBuilder.MoveToCell(0, mRowIdx, colIdx, 0);
                mBuilder.CellFormat.Shading.BackgroundPatternColor = rowColor;
            }

            mRowIdx++;
        }
    }

    void IFieldMergingCallback.ImageFieldMerging(ImageFieldMergingArgs args)
    {
        // Do nothing
    }

    private DocumentBuilder mBuilder;
    private int mRowIdx;
}

/// <summary>
/// Returns true if the value is odd; false if the value is even.
/// </summary>
private static bool IsOdd(int value)
{
    // The code is a bit complex, but otherwise automatic conversion to VB does not work
    return (value / 2 * 2).Equals(value);
}

/// <summary>
/// Create DataTable and fill it with data.
/// In real life this DataTable should be filled from a database.
/// </summary>
private static DataTable GetSuppliersDataTable()
{
    DataTable dataTable = new DataTable("Suppliers");
    dataTable.Columns.Add("CompanyName");
    dataTable.Columns.Add("ContactName");
    for (int i = 0; i < 10; i++)
    {
        DataRow datarow = dataTable.NewRow();
        dataTable.Rows.Add(datarow);
        datarow[0] = "Company " + i;
        datarow[1] = "Contact " + i;
    }

    return dataTable;
}
See Also