public interface IMailMergeDataSourceRoot
Example:
public void customDataSourceRoot() throws Exception
{
// 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();
employeesWashingtonBranch.add(new Employee("John Cardholder", "Management"));
employeesWashingtonBranch.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.getMailMerge().executeWithRegions(sourceRoot);
doc.save(getArtifactsDir() + "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) throws Exception
{
Document doc = new Document();
DocumentBuilder builder = new DocumentBuilder(doc);
for (String s : 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 static class Employee
{
public Employee(String aFullName, String aDepartment)
{
mFullName = aFullName;
mDepartment = aDepartment;
}
public String getFullName() { return mFullName; };
private String mFullName;
public String getDepartment() { return mDepartment; };
private String mDepartment;
}
/// <summary>
/// An example of a typed collection that contains your "data" objects.
/// </summary>
private static class EmployeeList extends ArrayList
{
public Employee get(int index) { return (Employee)super.get(index); }
public void set(int index, Employee value) { super.set(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 static class DataSourceRoot implements IMailMergeDataSourceRoot
{
public IMailMergeDataSource getDataSource(String tableName)
{
EmployeeListMailMergeSource source = mSources.get(tableName);
source.reset();
return mSources.get(tableName);
}
public void registerSource(String sourceName, EmployeeListMailMergeSource source)
{
mSources.put(sourceName, source);
}
private HashMap<String, EmployeeListMailMergeSource> mSources = new HashMap<>();
}
/// <summary>
/// Custom mail merge data source.
/// </summary>
private static class EmployeeListMailMergeSource implements IMailMergeDataSource
{
public EmployeeListMailMergeSource(EmployeeList employees)
{
mEmployees = employees;
mRecordIndex = -1;
}
/// <summary>
/// A standard implementation for moving to a next record in a collection.
/// </summary>
public boolean moveNext()
{
if (!isEof())
mRecordIndex++;
return (!isEof());
}
private boolean isEof() { return (mRecordIndex >= mEmployees.size()); }
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 getTableName() { return "Employees"; }
/// <summary>
/// Aspose.Words calls this method to get a value for every data field.
/// </summary>
public boolean getValue(String fieldName, Ref<Object> fieldValue)
{
switch (fieldName)
{
case "FullName":
fieldValue.set(mEmployees.get(mRecordIndex).getFullName());
return true;
case "Department":
fieldValue.set(mEmployees.get(mRecordIndex).getDepartment());
return true;
default:
// A field with this name was not found,
// return false to the Aspose.Words mail merge engine
fieldValue.set(null);
return false;
}
}
/// <summary>
/// Child data sources are for nested mail merges.
/// </summary>
public IMailMergeDataSource getChildDataSource(String tableName)
{
throw new UnsupportedOperationException();
}
private EmployeeList mEmployees;
private int mRecordIndex;
}
Method Summary | ||
---|---|---|
abstract IMailMergeDataSource | getDataSource(java.lang.String tableName) | |
The Aspose.Words mail merge engine invokes this method when it encounters a beginning of a top-level mail merge region. |
Method Detail |
---|
getDataSource | |
public abstract IMailMergeDataSource getDataSource(java.lang.String tableName) throws java.lang.Exception |
When the Aspose.Words mail merge engines populates a document with data and encounters MERGEFIELD TableStart:TableName,
it invokes
If a data source (table) with the specified name does not exist, your implementation should return null
.
tableName
- The name of the mail merge region as specified in the template document. Case-insensitive.Example:
Performs mail merge from a custom data source with master-detail data.public void customDataSourceRoot() throws Exception { // 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(); employeesWashingtonBranch.add(new Employee("John Cardholder", "Management")); employeesWashingtonBranch.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.getMailMerge().executeWithRegions(sourceRoot); doc.save(getArtifactsDir() + "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) throws Exception { Document doc = new Document(); DocumentBuilder builder = new DocumentBuilder(doc); for (String s : 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 static class Employee { public Employee(String aFullName, String aDepartment) { mFullName = aFullName; mDepartment = aDepartment; } public String getFullName() { return mFullName; }; private String mFullName; public String getDepartment() { return mDepartment; }; private String mDepartment; } /// <summary> /// An example of a typed collection that contains your "data" objects. /// </summary> private static class EmployeeList extends ArrayList { public Employee get(int index) { return (Employee)super.get(index); } public void set(int index, Employee value) { super.set(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 static class DataSourceRoot implements IMailMergeDataSourceRoot { public IMailMergeDataSource getDataSource(String tableName) { EmployeeListMailMergeSource source = mSources.get(tableName); source.reset(); return mSources.get(tableName); } public void registerSource(String sourceName, EmployeeListMailMergeSource source) { mSources.put(sourceName, source); } private HashMap<String, EmployeeListMailMergeSource> mSources = new HashMap<>(); } /// <summary> /// Custom mail merge data source. /// </summary> private static class EmployeeListMailMergeSource implements IMailMergeDataSource { public EmployeeListMailMergeSource(EmployeeList employees) { mEmployees = employees; mRecordIndex = -1; } /// <summary> /// A standard implementation for moving to a next record in a collection. /// </summary> public boolean moveNext() { if (!isEof()) mRecordIndex++; return (!isEof()); } private boolean isEof() { return (mRecordIndex >= mEmployees.size()); } 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 getTableName() { return "Employees"; } /// <summary> /// Aspose.Words calls this method to get a value for every data field. /// </summary> public boolean getValue(String fieldName, Ref<Object> fieldValue) { switch (fieldName) { case "FullName": fieldValue.set(mEmployees.get(mRecordIndex).getFullName()); return true; case "Department": fieldValue.set(mEmployees.get(mRecordIndex).getDepartment()); return true; default: // A field with this name was not found, // return false to the Aspose.Words mail merge engine fieldValue.set(null); return false; } } /// <summary> /// Child data sources are for nested mail merges. /// </summary> public IMailMergeDataSource getChildDataSource(String tableName) { throw new UnsupportedOperationException(); } private EmployeeList mEmployees; private int mRecordIndex; }