DoConure

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:

RowContents
HeadersDescription | 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.