IMailMergeDataSourceRootGetDataSource Method |
Namespace: Aspose.Words.MailMerging
When the Aspose.Words mail merge engines populates a document with data and encounters MERGEFIELD TableStart:TableName, it invokes GetDataSource(String) on this object. Your implementation needs to return a new data source object. Aspose.Words will use the returned data source to populate the mail merge region.
If a data source (table) with the specified name does not exist, your implementation should return null.
public void CustomDataSourceRoot() { // Create a document with two mail merge regions named "Washington" and "Seattle" Document doc = CreateSourceDocumentWithMailMergeRegions(new string[] { "Washington", "Seattle" }); // Create two data sources EmployeeList employeesWashingtonBranch = new EmployeeList(); employeesWashingtonBranch.Add(new Employee("John Doe", "Sales")); employeesWashingtonBranch.Add(new Employee("Jane Doe", "Management")); EmployeeList employeesSeattleBranch = new EmployeeList(); employeesSeattleBranch.Add(new Employee("John Cardholder", "Management")); employeesSeattleBranch.Add(new Employee("Joe Bloggs", "Sales")); // Register our data sources by name in a data source root DataSourceRoot sourceRoot = new DataSourceRoot(); sourceRoot.RegisterSource("Washington", new EmployeeListMailMergeSource(employeesWashingtonBranch)); sourceRoot.RegisterSource("Seattle", new EmployeeListMailMergeSource(employeesSeattleBranch)); // Since we have consecutive mail merge regions, we would normally have to perform two mail merges // However, one mail merge source data root call every relevant data source and merge automatically doc.MailMerge.ExecuteWithRegions(sourceRoot); doc.Save(ArtifactsDir + "MailMergeCustom.CustomDataSourceRoot.docx"); } /// <summary> /// Create document that contains consecutive mail merge regions, with names designated by the input array, /// for a data table of employees. /// </summary> private static Document CreateSourceDocumentWithMailMergeRegions(string[] regions) { Document doc = new Document(); DocumentBuilder builder = new DocumentBuilder(doc); foreach (string s in regions) { builder.Writeln("\n" + s + " branch: "); builder.InsertField(" MERGEFIELD TableStart:" + s); builder.InsertField(" MERGEFIELD FullName"); builder.Write(", "); builder.InsertField(" MERGEFIELD Department"); builder.InsertField(" MERGEFIELD TableEnd:" + s); } return doc; } /// <summary> /// An example of a "data entity" class in your application. /// </summary> private class Employee { public Employee(string aFullName, string aDepartment) { FullName = aFullName; Department = aDepartment; } public string FullName { get; } public string Department { get; } } /// <summary> /// An example of a typed collection that contains your "data" objects. /// </summary> private class EmployeeList : ArrayList { public new Employee this[int index] { get { return (Employee)base[index]; } set { base[index] = value; } } } /// <summary> /// Data source root that can be passed directly into a mail merge which can register and contain many child data sources. /// These sources must all implement IMailMergeDataSource, and are registered and differentiated by a name /// which corresponds to a mail merge region that will read the respective data. /// </summary> private class DataSourceRoot : IMailMergeDataSourceRoot { public IMailMergeDataSource GetDataSource(string tableName) { EmployeeListMailMergeSource source = mSources[tableName]; source.Reset(); return mSources[tableName]; } public void RegisterSource(string sourceName, EmployeeListMailMergeSource source) { mSources.Add(sourceName, source); } private readonly Dictionary<string, EmployeeListMailMergeSource> mSources = new Dictionary<string, EmployeeListMailMergeSource>(); } /// <summary> /// Custom mail merge data source. /// </summary> private class EmployeeListMailMergeSource : IMailMergeDataSource { public EmployeeListMailMergeSource(EmployeeList employees) { mEmployees = employees; mRecordIndex = -1; } /// <summary> /// A standard implementation for moving to a next record in a collection. /// </summary> public bool MoveNext() { if (!IsEof) mRecordIndex++; return (!IsEof); } private bool IsEof { get { return (mRecordIndex >= mEmployees.Count); } } public void Reset() { mRecordIndex = -1; } /// <summary> /// The name of the data source. Used by Aspose.Words only when executing mail merge with repeatable regions. /// </summary> public string TableName { get { return "Employees"; } } /// <summary> /// Aspose.Words calls this method to get a value for every data field. /// </summary> public bool GetValue(string fieldName, out object fieldValue) { switch (fieldName) { case "FullName": fieldValue = mEmployees[mRecordIndex].FullName; return true; case "Department": fieldValue = mEmployees[mRecordIndex].Department; return true; default: // A field with this name was not found, // return false to the Aspose.Words mail merge engine fieldValue = null; return false; } } /// <summary> /// Child data sources are for nested mail merges. /// </summary> public IMailMergeDataSource GetChildDataSource(string tableName) { throw new System.NotImplementedException(); } private readonly EmployeeList mEmployees; private int mRecordIndex; }