Aspose mailmerge with JAva

Hello,

We are using aspose mailmerge with java and xml input. We have a requirement where if the table doesn’t have any records, we should not display the header. We are able to achieve this with the following code.

However, we have some tables that are with a single row and the data is populated based on the input file. With the following code it is deleting those tables as they have just one row. Could you please advise how we can achieve this functionality.

In the attached document archiveRcdText is a variable and a section heading in the template. We need that to be displayed when there is value for archived text. The table with the following headings should not be displayed when there is no data in the table. With our current code, it is deleting both tables even though we have value for archive variable and as it is a single row in the table.

Docket Text Archive ID Entry Date Entered By

Is there a better way to achieve this requirement?

JsonParser parser = new JsonParser();
JsonObject jsonInput = parser.parse(json).getAsJsonObject();

DataSet mappingData = new DataSet();

System.out.println("Converting json to XML");
InputStream xmlStream = new ByteArrayInputStream(converttoXML1(jsonInput.get("data").toString()).getBytes());
mappingData.readXml(xmlStream);

try
{

    //Document doc = new Document(xmlStream);

    Document doc = new Document("C://temp//xml//FamilyCaseJacketSummaryTemplateFN.docx");

    doc.getMailMerge().setCleanupOptions(MailMergeCleanupOptions.REMOVE_UNUSED_REGIONS | MailMergeCleanupOptions.REMOVE_UNUSED_FIELDS
            | MailMergeCleanupOptions.REMOVE_EMPTY_PARAGRAPHS | MailMergeCleanupOptions.REMOVE_CONTAINING_FIELDS |
            MailMergeCleanupOptions.REMOVE_EMPTY_TABLE_ROWS);

    doc.getMailMerge().executeWithRegions(mappingData);
    doc.getMailMerge().execute(mappingData.getTables().get("mappingdataroot"));

    // Remove empty rows from the tables.
    Iterable<Table> tables = doc.getChildNodes(NodeType.TABLE, true);
    for (Table t : tables)
    {
        // Consider row as empty if it does not have any RUN nodes.
        while (t.getLastRow() != null
                && t.getLastRow().getChildNodes(NodeType.RUN, true).getCount() == 0)
        {
            t.getLastRow().remove();
        }

        //If there are no records for a given table, remove the table and also the header from generated PDF
        if (t.getRows().getCount() == 1)
            t.remove();
    }


    //doc.save("C://temp//xml//WorkingWithXmlData.NestedMailMerge.pdf");
    doc.save("C://temp//xml//FAM.pdf");

}
catch (Exception e)
{

    e.printStackTrace();
}

Template.docx (31.9 KB)

@judiciary

To achieve the desired functionality where the header of a table is not displayed when there are no records, while still allowing for single-row tables to remain visible, you can modify your existing code slightly. The key is to check for the specific condition of the table having only one row that is not empty.

Here’s an updated version of your code snippet that includes a condition to retain tables with a single row if that row contains data:

// Remove empty rows from the tables.
Iterable<Table> tables = doc.getChildNodes(NodeType.TABLE, true);
for (Table t : tables) {
    // Consider row as empty if it does not have any RUN nodes.
    while (t.getLastRow() != null && t.getLastRow().getChildNodes(NodeType.RUN, true).getCount() == 0) {
        t.getLastRow().remove();
    }
    
    // If there are no records for a given table, remove the table and also the header from generated PDF
    // Check if the table has only one row and that row is empty
    if (t.getRows().getCount() == 1 && t.getFirstRow().getChildNodes(NodeType.RUN, true).getCount() == 0) {
        t.remove(); // Remove the table if it has only an empty row
    }
}

In this code:

  • We first check if the table has only one row.
  • Then, we check if that row is empty (i.e., it does not contain any RUN nodes).
  • If both conditions are met, we remove the table.

This way, if the table has a single row with data, it will remain, and only empty tables will be removed.

Additionally, ensure that your archiveRcdText variable is handled correctly to display the section heading when there is a value for it, regardless of the table’s content.

This approach should help you meet your requirements effectively. If you have further questions or need additional assistance, feel free to ask!

@judiciary In your case you can simply specify MailMergeCleanupOptions.REMOVE_EMPTY_TABLES.

Thank you for your response. The first solution offered is not working. However, the second option of remove empty tables works but that feature is only in the latest aspose version. For time being, we are able to use the latest version. Will reach out if we need any additional help

1 Like