Lists and repeating rows
When the JSON holds an array, you usually want one table row per element. How you write it depends on the format.
In Word
Use a table with two marker rows around the row that repeats:
| Row | Contents |
|---|---|
| Headers | Description | Qty | Total |
| Open | {%tr for r in lines %} in the first cell, rest empty |
| Data | {{ r.description }} | {{ r.quantity }} | {{ r.total }} |
| Close | {%tr endfor %} in the first cell, rest empty |
The open and close rows do not appear in the PDF: they are
consumed. The data row is duplicated once per element. The name after
for is yours to choose and is what you use in the data row.
If the table can grow long, mark the header row as repeating. In Word: right-click the row → Table properties → Row tab → tick Repeat as header row at the top of each page.
Without it, once the table crosses a page the second page starts with data rows and no column names. It is the most common oversight when a table that used to hold one row becomes repeating.
In HTML
<tbody>
{% for r in lines %}
<tr>
<td>{{ r.description }}</td>
<td>{{ r.quantity }}</td>
<td>{{ r.total }}</td>
</tr>
{% endfor %}
</tbody>
Put the header row in a <thead> and it repeats across pages
by itself.
A long table: fix its layout
By default a browser, and our renderer, measures every cell of a table before placing the first row, so that each column is as wide as its longest value. On a table of a few hundred rows that measuring is most of the work. Tell it the widths instead and it lays the table out row by row:
<table style="table-layout: fixed; width: 100%">
<colgroup>
<col style="width: 60%"><col style="width: 15%"><col style="width: 25%">
</colgroup>
...
On a 300-row table this makes the PDF about a quarter faster, with the same content. A value longer than its column wraps inside it instead of widening the column. Validate reminds you when a table with a repeating row has no fixed layout.
In Excel
In column A of the row that opens the block write {% row for r in sales %}, and in column A of the closing row {% endrow %}. The rows between are cloned per element.
A1: Sales report
A3: {% row for s in sales %}
A4: {{ s.product }} B4: {{ s.quantity }} C4: {{ s.total }}
A5: {% endrow %}
An empty array produces zero rows, and the markers disappear either way.
Whole-page feature matrix by format: What each format can do.