How can I run an "empty" Mail Merge and remove unused MergeFields?

I have a Word template on which we run MailMerge to generate tables of dynamic size.
Sometimes, the MailMerge input data is “empty”, that means we want to generate a document without any data in the table.
In this case, I would like to run an “empty” MailMerge operation, that is without any input data and then clean-up/ remove the unsued MergeFields in the document.

I tried so with the following code:

private void insertMultiTables(Document doc, Map<String, List<Map<String, String>>> lists) throws Exception {

    log.debug("Provided table names: {}", lists);
    log.debug("Document table names: {}", getTableNames(doc));

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

    if (lists == null || lists.isEmpty()) {
        // No input data. Run mail merge with cleanup options to remove unused fields and tables
        doc.getMailMerge().execute(new String[]{"FullName", "Company", "Address", "Address2", "City"},
                new Object[]{"James Bond", "MI5 Headquarters", "Milbank", "", "London"});
    } else {

        for (Map.Entry<String, List<Map<String, String>>> tableEntry : lists.entrySet()) {

            String tableName = tableEntry.getKey();
            List<Map<String, String>> tableValues = tableEntry.getValue();

            Collection<String> columns = getTableColumns(tableValues);
            DataTable dataTable = new DataTable(tableName);
            columns.forEach(e -> dataTable.getColumns().add(e));

            for (Map<String, String> listEntry : tableValues) {
                dataTable.getRows().add(listEntry.values().toArray());
            }

            long overload = countTableOverload(doc);
            for (int i = 0; i < overload; i++) {
                doc.getMailMerge().executeWithRegions(dataTable);
            }
        }
    }
    doc.updateFields();
}

My input document looks like this:

cleanup-mailmerge.docx (52.1 KB)

If I provide data for “kontoinhaber-table” I would expect to see one row for each entry.
If I dont have data for “kontoinhaber-table”, I would like the table “kontoinhaber-table” to be completely removed from the document.

@kerner Could you please attach your sample template, current and expected output documents (in MS Word format)? We will check the issue and provide you more information.

1 Like

Of course, sample file attached, thank you+

@kerner To remove unused regions you should execute mail merge with regions with an empty data. For example see the following code:

Document doc = new Document("C:\\Temp\\in.docx");
doc.getMailMerge().setCleanupOptions(MailMergeCleanupOptions.REMOVE_UNUSED_REGIONS);
doc.getMailMerge().executeWithRegions(new DataTable());
doc.save("C:\\Temp\\out.docx");

To remove remaining merge fields, you can use doc.getMailMerge().deleteFields();