We're sorry Aspose doesn't work properply without JavaScript enabled.

Free Support Forum - aspose.com

Master-Detail merge with IMailMergeDataSource not working

I am trying to do a master detail mail merge using the eval copy of Aspose Words for Java. I have a custom complex object model that has inherent master-detail relationships. The getChildDataSource method is never called when a TableStart is encountered in the document.

To illustrate the problem I created an implementation that just prints the method calls. I also attached a sample document based upon one of your sample documents from another thread. I would expect Aspose Words to call getValue for top_field and then to call getChildDataSource for Customer, but I only see the getValue call. Here's the Java code that prints the calls:

doc.getMailMerge().execute(new IMailMergeDataSource() {
        	protected boolean first=false;
			public IMailMergeDataSource getChildDataSource(String arg0) throws Exception {
			System.out.println("getChildDataSource: "+arg0);
			return null;
		}

		public String getTableName() throws Exception {
			System.out.println("getTableName");
			return "Customer";
		}

		public boolean getValue(String arg0, Object[] arg1) throws Exception {
			System.out.println("getValue: "+arg0);
			return false;
		}

		public boolean moveNext() throws Exception {
			System.out.println("moveNext");
			if (!first) {
				first=true;
				return true;
			}
			return false;
		}

    });

 

Hello

Thanks for your request. Actually your template does not contain any child regions. Also you should use executeWithRegions instead of execute. Please see the attached document and the following code:

Document doc = new Document("C:\\Temp\\in.doc");

doc.getMailMerge().executeWithRegions(new IMailMergeDataSource() {

protected boolean first=false;

public IMailMergeDataSource getChildDataSource(String arg0) throws Exception {

System.out.println("getChildDataSource: "+arg0);

return null;

}

public String getTableName() throws Exception {

System.out.println("getTableName");

return "ParentRegion";

}

public boolean getValue(String arg0, Object[] arg1) throws Exception {

System.out.println("getValue: "+arg0);

return false;

}

public boolean moveNext() throws Exception {

System.out.println("moveNext");

if (!first) {

first=true;

return true;

}

return false;

}

});

Best regards,

I understand now that you need to have the entire document wrapped in a region.

In my scenario, my top level record does not repeat. There is one master record per mail merge. This master record can have fields and also embedded collections. So, in a perfect world, the mail merge is done on that record, and then any TableStart regions found within it would be mapped to getChildDataSource.

Is this style of design supported in any way? I do not want to make my users who are designing templates to have to create a region that wraps every single template document.

Thanks for the help.

Hi Paul,

Thanks for this additional information.

Normally in this case you would merge the data from your single master record using simple mail merge instead (without regions) into fields at the start of the document. This would avoid the need to wrap the entire document in a region. However from the sounds of your data source this is not desired.

Instead it appears the only way to achieve mail merge in the way you want (by having regions call getChildDataSource) is to have the document wrapped in an outer region.

I can propose one way to have the best of both world. If it is suitable to you, you can insert an outer region into the template through code instead of requiring your users to do this. Please see the snippet below.

Document doc = new Document();<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

DocumentBuilder builder = new DocumentBuilder(doc);

builder.MoveToDocumentStart();

builder.InsertField("MERGEFIELD TableStart:MasterTable");

builder.MoveToDocumentEnd();

builder.InsertField("MERGEFIELD TableEnd:MasterTable");

Thanks,