Dynamic flat data source

Hi

I’m using (testing) Aspose.Words for Java 10.0.0, but as I understand it, the API is the same as the .Net version.

My question is, how do I create a data source that isn’t a list like IMailMergeDataSource is (i.e. flat data source), but is create “on the fly”?

I know this approach:

doc.MailMerge.Execute(new string[]
    {
        "FullName",
        "Company",
        "Address",
        "Address2",
        "City"
    },
    new object[]
    {
        "James Bond",
        "MI5 Headquarters",
        "Milbank",
        "",
        "London"
    });

But then the data is create up from, I only wish to find the data, if the template has the mergefield and I want a loose coupling between my data supplier and my templates.

I could of course use IFieldMergingCallback as a data supplier, but that seems like a hack, and if doing so, I cannot have others callback that format the object by its type, because the only way to insert data is by setTest(String text) - but then the type info is always String.

Regards,
Morten

Hi Morten,
Thanks for your request. But I think you can use ImailMergeDataSource to achieve what you need. In IMailMereDataSource.getValue method you can implement your own logic to get a value for the particular field in the document. This method is called when Aspose.Words reporting engine requests a value for a particular field. So I think this is what you are looking for.
Best regards,

Hi

Thanks for you response.

Yes it could be used, but I would think that it would require that I have a mergefield:starttabel:root element at the top of the document and a mergefield:endtabel:root at the end of the doment. And the return “root” in IMailMereDataSource.getTableName?

Best regards,
Morten

Hi
Thank you for additional information. No you do not need these mergefields at the beginning and at the end of the document. You can just return null in getTableName method. This value is needed only if you use Mail Merge With Regions. But in your case, I suppose, you are using simple mail Merge.
Best regards,

Thank you for the reply - it works…

Regards,
Morten

Hi again

What if I need to use “merge with regions”?

Lets say that I have a data structure like this:

Customer
-name
.orderLines
–itemName
–price

And I want to create a document with mergefields looking like this:
{mergefield name}
{mergefield tablestart:orderLines}
- {mergefield itemName}
- {mergefield price}
{mergefield tableend:orderLines}

This I cannot get to work.

Best regards
Morten

Hello,
Thank you for your request.
The answer to your question is very well described here in an article in our documentation. Look, please, if you have difficulty, please fell free to ask.
Hope this helps.

Also please look at an example of using Interface IMailMergeDataSource. This is likely what you are looking for.

Hi

Thanks for your reply. My problem is that I do not have a list as the “root element”, but an object containing attributes and some of these is a list. So I can choose to create a list containing only this root object, which would be okay - but I still would have to wrap the entire word document inside a tablestart/end mergefield - this is what I’m trying to avoid.

Regards
Morten

Hello

Thank you for additional information. Please see the following link:
https://docs.aspose.com/words/net/nested-mail-merge-with-regions/
This article details the steps of how to set up a working nested mail merge application to generate a collection of invoices where each contains multiple items. If I correctly understand you, it is the same what you are looking for.
If it does not help you, could you please attach your Data Source and expected output document? I will check them and provide you more information.
Also I created some simple code example for you. Please see the following code:

// Open template.
Document doc = new Document("C:\\Temp\\in.doc");
// Execute mail merge with regions.
doc.MailMerge.ExecuteWithRegions(GetDataForMailMerge());
// Save output document.
doc.Save("C:\\Temp\\out.doc");
//
/// Returns dummy datasource, which contaion two tables with parent-child relationships.
/// The first table name is "ParentRegion", the child table name is "ChildRegion".
///
private static DataSet GetDataForMailMerge()
{
    DataSet ds = new DataSet();
    // Create two tables and add them into the data set.
    DataTable parent = new DataTable("ParentRegion");
    parent.Columns.Add("id");
    parent.Columns.Add("Name");
    DataTable child = new DataTable("ChildRegion");
    child.Columns.Add("parnetId"); // this column is needed to create relationshoip between tables.
    child.Columns.Add("ItemName");
    child.Columns.Add("Price");
    // Add tables into the data set and add relationship.
    ds.Tables.Add(parent);
    ds.Tables.Add(child);
    ds.Relations.Add(parent.Columns["id"], child.Columns["parnetId"]);
    // Structure of our datasource is ready. Let's add some dummy data.
    Random rnd = new Random();
    for (int i = 0; i < 10; i++)
    {
        parent.Rows.Add(new object[]
        {
        i,
        string.Format("Name #{0}", i)
        });
        for (int j = 0; j < rnd.Next(1, 15); j++)
        {
            child.Rows.Add(new object[]
            {
            i,
            string.Format("Item Name {0} {1}", i, j),
            string.Format("Item Price {0} {1}", i, j)
            });
        }
    }
    return ds;
}

The input and the output documents are attached.
Best regards,