Customising Tables with the [Table.MergeRows:] macro

Customising Tables: Introducing Table.MergeRows in ReportMagic 4.2

ReportMagic 4.2 introduces a powerful new macro - [Table.MergeRows:] - that lets you horizontally merge adjacent cells within table rows. Whether you’re consolidating repeating quarter headers, grouping identical status cells, or cleaning up data-heavy reports, this macro gives you fine-grained control over horizontal cell merging with full formatting preservation.

What Does It Do?

[Table.MergeRows:] scans one or more rows in a table and merges adjacent cells that match a given criteria. By default, it merges cells with identical text, but it also supports pattern-based matching using Contains, NotContains, and Regex modes.

The leftmost cell’s style (background colour, font, borders) is always preserved, and you have full control over what content the merged cell should contain.

How It Works

[Table.MergeRows:] operates on the previous table in the document - it doesn’t create a table itself. In practice, that table might already exist in your Word or HTML document, or it might have been generated by any of the many table-producing macros such as [Jira.Table:], [LogicMonitor.DeviceTable:], [Database.Table:], [Web.Table:], and others.

In the examples below, we use [List.Table:] as a quick way to create inline tables for demonstration purposes only.

Quick Start

At its simplest, just place the macro after a table and it will merge all adjacent identical cells in every data row (the header row is skipped by default):

[List.Table: values=Status^Q1^Q2^Q3^Q4;Sales^Good^Good^Good^Poor;Support^OK^OK^OK^OK]
[Table.MergeRows:]

Result:

Status Q1 Q2 Q3 Q4
Sales Good (colspan=3) Poor
Support OK (colspan=4)

The three “Good” cells merge into one spanning 3 columns, and all four “OK” cells merge into one spanning 4 columns.

Parameters at a Glance

Parameter Default Description
ignoreHeaderRow true Whether to skip the header (first) row
rowIndices (all rows) Specific 1-based row indices to process (semicolon-separated)
rowIndexFrom / rowIndexTo (all rows) A range of rows to process
startColumnIndex 1 The 1-based leftmost column to consider
endColumnIndex (last) The 1-based rightmost column to consider
matchType Identical How cells are matched: Identical, Contains, NotContains, or Regex
matchText The text or regex pattern to match (required for Contains/NotContains/Regex)
mergeValue First What the merged cell should contain: First, Last, Empty, Joined, or MatchText
joinDelimiter , Delimiter when using mergeValue=Joined
skipMergedCells true Skip cells that are already part of a merge

Note: rowIndices and rowIndexFrom/rowIndexTo are mutually exclusive - use one approach or the other.

Examples

1. Basic Identical Merge

Merge adjacent cells with the same text across all data rows:

[List.Table: values=Name^Mon^Tue^Wed^Thu^Fri;Alice^Office^Office^Office^Remote^Remote;Bob^Remote^Remote^Office^Office^Office;Carol^Office^Office^Office^Office^Office]
[Table.MergeRows:]

Result:

Name Mon-Fri
Alice Office (x3)
Bob Remote (x2)
Carol Office (x5)

2. Merge the Header Row

By default the header row is skipped. Set ignoreHeaderRow=false to include it:

[List.Table: values=2025 Q1^2025 Q2^2025 Q3^2026 Q1^2026 Q2;100^200^300^400^500]
[Table.MergeRows: ignoreHeaderRow=false, matchType=Contains, matchText=2025, mergeValue=MatchText]

The three “2025” headers merge into a single cell displaying “2025” (colspan=3), while the 2026 headers remain separate.

3. Target Specific Rows

Use rowIndices to merge only the header row (row 1):

[List.Table: values=Region^Q1 2025^Q2 2025^Q3 2025^Q1 2026^Q2 2026;North^10^20^30^40^50;South^60^70^80^90^100]
[Table.MergeRows: rowIndices=1, matchType=Contains, matchText=2025, mergeValue=MatchText]

Only row 1 (the header) is processed. The three “2025” columns merge into one cell labelled “2025”, while data rows remain untouched.

4. Merge a Range of Rows

Use rowIndexFrom and rowIndexTo to process a specific range:

[List.Table: values=Name^Mon^Tue^Wed^Thu^Fri;Alice^x^x^x^y^y;Bob^a^a^b^b^b;Carol^z^z^z^z^z;Dave^p^q^r^s^t]
[Table.MergeRows: rowIndexFrom=2, rowIndexTo=4, startColumnIndex=2, endColumnIndex=6]

Only rows 2-4 are processed (Dave’s row is untouched), and only columns 2-6 participate in the merge.

5. Restrict Columns with startColumnIndex

Skip the first column (e.g. a label column) so it’s never merged:

[List.Table: values=Team^Sprint 1^Sprint 2^Sprint 3^Sprint 4;Alpha^Done^Done^Done^In Progress;Beta^Blocked^Blocked^Done^Done]
[Table.MergeRows: startColumnIndex=2]

Column 1 (“Team”) is excluded. Only the sprint columns participate in the merge.

6. Contains Match with MatchText Value

Merge cells whose text contains a keyword, and replace the merged content with the match text:

[List.Table: values=Category^Jan 2025^Feb 2025^Mar 2025^Jan 2026^Feb 2026;Revenue^1000^2000^3000^4000^5000]
[Table.MergeRows: rowIndices=1, matchType=Contains, matchText=2025, mergeValue=MatchText]

The three “2025” header cells merge into one cell displaying just “2025”.

7. NotContains Match

Merge cells that do not contain a specific value - useful for grouping everything except totals or separators:

[List.Table: values=C1^C2^C3^C4^C5;Total^100^200^Total^300]
[Table.MergeRows: rowIndices=2, matchType=NotContains, matchText=Total, mergeValue=Joined, joinDelimiter= + ]

Result: The “Total” cells act as barriers. Cells “100” and “200” merge into “100 + 200”, and “300” stays alone.

8. Regex Match

Use a regular expression to match cells. This example merges cells starting with “Q” followed by a digit:

[List.Table: values=Q1 Sales^Q2 Sales^H1 Sales^Q3 Sales;10^20^30^40]
[Table.MergeRows: rowIndices=1, matchType=Regex, matchText=^Q\d, mergeValue=First]

“Q1 Sales” and “Q2 Sales” merge (keeping “Q1 Sales”). “H1 Sales” breaks the group (doesn’t match). “Q3 Sales” stands alone.

9. Joined Merge Value

Instead of keeping just the first or last value, join all merged cell values with a delimiter:

[List.Table: values=Department^Role 1^Role 2^Role 3^Role 4;Engineering^Dev^Dev^Dev^QA;Operations^Ops^Ops^SRE^SRE]
[Table.MergeRows: mergeValue=Joined, joinDelimiter= / ]

Result:

Department Roles
Engineering Dev / Dev / Dev (x3)
Operations Ops / Ops (x2)

10. Empty Merge Value

Clear the content of merged cells entirely - useful when you want the visual merge without any text:

[List.Table: values=H1^H2^H3;a^a^b;c^c^c]
[Table.MergeRows: mergeValue=Empty]

Adjacent identical cells are merged, but the resulting merged cell is empty.

11. Merging from a Specific Row to the End

Use rowIndexFrom without rowIndexTo to process from a given row to the last row:

[List.Table: values=H1^H2^H3;a^a^b;c^c^c;d^d^e;f^f^f]
[Table.MergeRows: rowIndexFrom=4]

Rows 2-3 are untouched. Only rows 4 and 5 are processed.

12. Preserving Formatting

When cells have styling (background colours, bold text, font sizes), [Table.MergeRows:] preserves the formatting of the leftmost cell in each merge group. This works in both Word and HTML output - your carefully styled tables stay beautiful.

Tips and Best Practices

  • Start simple - use [Table.MergeRows:] with no parameters to merge identical adjacent cells in all data rows. Add parameters as needed.
  • Header rows - remember ignoreHeaderRow defaults to true. Set it to false when you need to merge header cells.
  • Column scope - use startColumnIndex and endColumnIndex to protect label columns from being merged.
  • Pre-merged cells - cells that already have a colspan or rowspan are skipped by default (skipMergedCells=true). Set to false if you want an error when this occurs.
  • Row targeting - rowIndices and rowIndexFrom/rowIndexTo are mutually exclusive. Use rowIndices for specific rows and the range parameters for contiguous blocks.
  • Works everywhere - [Table.MergeRows:] works in Word (.docx) and HTML output. PowerPoint is not supported.

Conclusion

[Table.MergeRows:] fills a long-requested gap in ReportMagic’s table manipulation toolkit. Combined with existing macros like [Table.MergeCells:] (vertical merging) and [Table.Style:], you now have complete control over both horizontal and vertical cell merging - making it easy to produce clean, professional reports with properly structured headers and consolidated data cells.

Look out for this feature in ReportMagic 4.2, coming soon!


Have questions or feedback? Let us know in the comments below.

1 Like