7. Tables
A table prints one row for each item in a list, such as the lines of an order, the handling units on a BOL or the items in a report. Tables grow with the data, split cleanly across pages, repeat their header row, and can sort, group and subtotal.

Create a table
There are two ways:
- From the Fields tab (recommended): drag a list, such as items or lines, onto the Body. A table appears with one column for each field of the
list items. Headers come from the field titles, and values are pre-bound (
{{ item.sku | APP-TS-1001 }}). - From the Insert tab: drag Table onto the Body, then set Properties → Table → Data to the list's path (for example
items) and edit the columns.
To add a column later, drag a field of the list items from the Fields tab onto the table, or click Add in the Columns section.
Table settings
| Setting | Meaning |
|---|---|
| Data | The list to print: a bare expression such as items, lines or shipment.handlingUnits |
| Header row | Print the column headings |
| Repeat on each page | Print the header row again at the top of every page the table continues on (recommended) |
| Footer row (totals) | Print a footer row after the last row. Each column's Footer text goes in it |
| Header, Row, Footer | Minimum heights in points. Data rows grow automatically when a cell's text wraps |
| Min. rows | Always print at least this many rows, adding blank ones (for paper forms that need empty lines to write on) |
| Alternate rows | Fill color for every other row (zebra striping) |
| Grid lines | Width and color of the cell borders. Set the width to 0 for no grid |
| Header fill, Header text, Bold header | Header row colors and weight |
| Cell font size | Font size of the data rows |
| Table font | Font, size, color and padding for the whole table (the Style section) |
The column editor
The Columns section lists the columns in order. For each column:
| Setting | Meaning |
|---|---|
| Header | The heading text (can contain bindings) |
| Value | What to print in each row. Use item. for the current row's fields: {{ item.qty }} |
| Footer | Text for the footer row, typically a total. Shown when Footer row (totals) is on |
| Group footer | Text for the group subtotal row. Shown when grouping is set up (see below) |
| Width | Column width. The columns are laid out from left to right |
| Alignment | Align left, Center, Align right. Applies to the header, cells and footer. Right-align numbers |
The buttons on each column move it (Move left, Move right) or delete it (Remove column). Fit scales all columns so that together they are exactly as wide as the table.
Tip: After you resize the table on the canvas, click Fit so the columns fill the new width.
Cell values
Each cell is template text evaluated for one row. Inside it, item is the row, index is its position (from 0), and $ is the top of the data.
{{ item.sku }} → APP-TS-1001
{{ index + 1 }} → 1
{{ formatNumber(item.weight, 2) }} → 0.40
{{ formatCurrency(item.qty * item.unitCost, 'USD') }} → $116.40
{{ item.hazmat ? 'X' : '' }} → (empty)
{{ item.sku }} · {{ item.location }} → APP-TS-1001 · A-02-A-01
Footer totals
In the Footer of a column, rows is the whole list:
{{ sum(rows, 'qty') }} → 82
{{ formatNumber(sum(rows, 'weight'), 2) }} → 1.63
{{ count(rows) }} lines → 3 lines
Put a label like "Grand total" in the footer of the first column, and the totals under the number columns.
Forms with blank lines: Min. rows
A paper BOL has room for a fixed number of lines whether or not they are filled. Set Min. rows to that number, for example 8. The table always prints
8 rows, with blank rows added after the data. With more than 8 items, it simply prints them all.
How tables break across pages
- A table splits between rows, never in the middle of a row.
- With Repeat on each page on, the header row prints again at the top of every continued page.
- The footer row prints once, after the last row.
- Elements below the table are pushed down and follow the table onto the last page (chapter 4).
Warning: A single row taller than the whole body area of a page can't be split, and it is cut off. This happens only with very long wrapped text. Use Ellipsis (…) overflow for long descriptions in narrow columns.
Sorting and grouping with subtotals
In Properties → Sorting & grouping:
| Setting | Meaning |
|---|---|
| Sort by | An expression per row that sets the order, e.g. item.location. Numbers sort numerically and text alphabetically. Empty values go last |
| Descending | Reverse the order |
| Group by | An expression per row. Consecutive rows with the same value form a group, e.g. item.category |
| Group header | The text of the full-width row that starts each group. Default {{ group.key }} |
| Group header, Group footer (heights) | Row heights in points |
| Group fill | Background color of the group header row |
| Repeat group header after a page break | When a group continues on the next page, repeat its header there (on by default) |
| Group footer row (subtotals) | Print a subtotal row at the end of each group, built from each column's Group footer |
| Start each group on a new page | Every group after the first starts on a new page |
Warning: Rows with the same group value must be next to each other. Set Sort by to the same expression as Group by (or start with it, as in
item.category + ' ' + item.sku). Otherwise the same group can appear twice.
Inside group headers and group footers, group.key is the group's value, group.count the number of rows, group.index the group number (from 0),
and rows the rows of that group:
{{ group.key }} · {{ group.count }} items → Apparel · 2 items
{{ formatNumber(sum(rows, 'qty'), 0) }} → 82
Worked example: an Item Master Report grouped by category
- Start from the gallery's Item Master Report, or drag the items list onto the Body of a landscape Letter page.
- Select the table. Set Sort by to
item.category + ' ' + item.skuand Group by toitem.category. - Set Group header to
{{ group.key | Apparel }} · {{ group.count | 12 }} items. - Turn on Group footer row (subtotals). In the column editor, set the Group footer of the SKU column to
Subtotal, and of the Unit cost column toAvg {{ formatCurrency(avg(rows, 'unitCost'), 'USD') }}. - Turn on Footer row (totals) for the grand total, and set the footers in the same way, using
rowsfor all rows. - Click Preview PDF. The preview shows two placeholder groups with two rows each.

One page per group. For an inventory report where each zone goes to a different team, turn on Start each group on a new page.
Tables and the designer canvas
On the canvas, a table shows its header, three sample rows (or a group header, rows and group footer when grouped) and its footer, using the preview text of each cell. The real number of rows is only known when the document renders. Use Preview PDF to see the true length.