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

Free Support Forum - aspose.com

Nested Mail Merge - Is IMailMergeDataSource really supported?

Hi,

We need to use nested mail merge with IMailMergeDataSource, as DataSet doesn’t fit into our system. We tried Aspose Words for Java 13.5.0 (with temporary license) on two of our products, both are web applications, and they simply don’t work: the mail merge fields are not merged at all, and no errors threw in the system.

Please see attached mail merge file and relevant java source codes. Please note that fields in the outer table Employee are resolved by display name in the system, while the fields in the inner table ReviewHistory are resolved by field name in the java class.

Could anyone in your team let us know that, Is IMailMergeDataSource really supported in nested mail merge? If the answer is yes, could anyone tell us what might be wrong in the attached files?

Thanks very much.

Mark

Hi Mark,

Thanks for your inquiry. You can find sample code for implementing IMailMergeDataSource with a child data source in the following article. Please read the section 'Creating Relations between IMailMergeDataSource Objects'.
http://www.aspose.com/docs/display/wordsjava/How+to++set+up+relations+for+use+in+nested+mail+merge+with+regions

Hope this helps you.

Hi Mark,

<o:p> </o:p>

The following code example use IMailMergeDataSource for nested mail merge regions. Please find the sample input and output documents in attachment. Hope this helps you. Please let us know if you have any more queries. <o:p></o:p>

<o:p> </o:p>


public void Test001() throws Exception {<o:p></o:p>

// Prepare data.<o:p></o:p>

ArrayList parents = new ArrayList();<o:p></o:p>

for(int i=0; i<10; i++)<o:p></o:p>

{<o:p></o:p>

Parent parent = new Parent(String.format(“Parent_#%d”, i));<o:p></o:p>

for(int j=0; j<5; j++)<o:p></o:p>

parent.Children.add(new Child(String.format(“Child_#%d_%d”, i, j)));<o:p></o:p>

parents.add(parent);<o:p></o:p>

}<o:p></o:p>

// Open tempalte<o:p></o:p>

Document doc = new Document(“C:\Temp\in.doc”);<o:p></o:p>

// Create a datasource.<o:p></o:p>

MailMergeDataSource ds = new MailMergeDataSource(parents, “Parents”);<o:p></o:p>

// Execute mail merge with regions.<o:p></o:p>

doc.getMailMerge().executeWithRegions(ds);<o:p></o:p>

// Save output.<o:p></o:p>

doc.save(“C:\Temp\out.doc”);<o:p></o:p>

}<o:p></o:p>

private static class Parent<o:p></o:p>

{<o:p></o:p>

public Parent(String name)<o:p></o:p>

{<o:p></o:p>

Name = name;<o:p></o:p>

Children = new ArrayList();<o:p></o:p>

}<o:p></o:p>

public final ArrayList Children;<o:p></o:p>

public final String Name;<o:p></o:p>

}<o:p></o:p>

private static class Child<o:p></o:p>

{<o:p></o:p>

public Child(String name)<o:p></o:p>

{<o:p></o:p>

Name = name;<o:p></o:p>

}<o:p></o:p>

public final String Name;<o:p></o:p>

}<o:p></o:p>

private class MailMergeDataSource implements IMailMergeDataSource{<o:p></o:p>

public MailMergeDataSource(List items, String tableName)<o:p></o:p>

{<o:p></o:p>

mItems = items;<o:p></o:p>

mTableName = tableName;<o:p></o:p>

// When the data source is initialized, it must be positioned before the first record.<o:p></o:p>

mRecordIndex= -1;<o:p></o:p>

}<o:p></o:p>

///

<o:p></o:p>

/// The name of the data source. Used by Aspose.Words only when executing mail merge with repeatable regions.<o:p></o:p>

/// <o:p></o:p>

public String getTableName()<o:p></o:p>

{<o:p></o:p>

return mTableName;<o:p></o:p>

}<o:p></o:p>

///

<o:p></o:p>

/// Aspose.Words call this to get a value for every data field.<o:p></o:p>

/// <o:p></o:p>

public boolean getValue(String fieldName, Object[] fieldValue)<o:p></o:p>

{<o:p></o:p>

fieldValue[0] = getFieldValue(fieldName);<o:p></o:p>

return fieldValue[0]!=null;<o:p></o:p>

}<o:p></o:p>

public IMailMergeDataSource getChildDataSource(String childName) throws Exception {<o:p></o:p>

Object childData = getFieldValue(childName);<o:p></o:p>

if(childData!=null && List.class.isInstance(childData))<o:p></o:p>

return new MailMergeDataSource((List)childData, childName);<o:p></o:p>

return null;<o:p></o:p>

}<o:p></o:p>

///

<o:p></o:p>

/// A standard implementation for moving to a next record in a collection.<o:p></o:p>

/// <o:p></o:p>

public boolean moveNext()<o:p></o:p>

{<o:p></o:p>

if (isEof())<o:p></o:p>

return false;<o:p></o:p>

mRecordIndex++;<o:p></o:p>

return (!isEof());<o:p></o:p>

}<o:p></o:p>

private boolean isEof()<o:p></o:p>

{<o:p></o:p>

return (mRecordIndex >= mItems.size());<o:p></o:p>

}<o:p></o:p>

private Object getFieldValue(String fieldName)<o:p></o:p>

{<o:p></o:p>

// Get value of the appropriate field usign reflection.<o:p></o:p>

Object item = mItems.get(mRecordIndex);<o:p></o:p>

Class itemClass =item.getClass();<o:p></o:p>

java.lang.reflect.Field field = null;<o:p></o:p>

try{<o:p></o:p>

field = itemClass.getField(fieldName);<o:p></o:p>

} catch(Exception ex){}<o:p></o:p>

if(field!=null)<o:p></o:p>

{<o:p></o:p>

try{<o:p></o:p>

return field.get(item);<o:p></o:p>

} catch(Exception ex){}<o:p></o:p>

return true;<o:p></o:p>

}<o:p></o:p>

return null;<o:p></o:p>

}<o:p></o:p>

private List mItems;<o:p></o:p>

private int mRecordIndex;<o:p></o:p>

private String mTableName;<o:p></o:p>

}

Hi Tahir,

I was calling getMailMerge().execute(), while I need to call getMailMerge().executeWithRegions() - that’s all the issue.

Many thanks for the help.

Mark

Hi Mark,


Thanks for your feedback. Please feel free to ask if you have any question about Aspose.Words, we will be happy to help you.