Skip to content

jx:repeat

jx:repeat is the simplest looping command. It repeats a template area N times — no collection needed. Perfect for blank rows, fixed layouts, and padding.

jx:repeat(count="5" lastCell="C1")
jx:repeat(count="numRows" var="i" lastCell="C1")
jx:repeat(count="3" var="i" direction="RIGHT" lastCell="A1")
AttributeRequiredDescription
countYesNumber of repetitions. Can be a literal ("5") or an expression ("numRows")
lastCellYesBottom-right corner of the area to repeat
varNoVariable name for the 0-based iteration index. Available as ${i} in the area
directionNo"DOWN" (default) or "RIGHT"
ScenarioUse
You have data to loop overjx:each
You need N blank rows (e.g., invoice line padding)jx:repeat
You need numbered rows without datajx:repeat with var
You need N identical columnsjx:repeat with direction="RIGHT"

The key difference: jx:each iterates over a collection (employees, orders, etc.), while jx:repeat just repeats N times. No dummy slices needed.

Invoices often need a fixed number of line rows regardless of how many items exist. Instead of creating a dummy slice in Go:

jx:repeat(count="extraLines" var="i" lastCell="D1")

With ${i+1} in a cell, the output shows numbered blank rows. Your Go code simply provides:

data := map[string]any{
"extraLines": 10,
}

Generate columns dynamically:

jx:repeat(count="4" var="i" direction="RIGHT" lastCell="A1")

With ${i} in cell A1, produces columns 0 | 1 | 2 | 3 across A1:D1.

If count evaluates to 0 or negative, the command produces no output — no error, no empty rows. This is useful for conditional padding:

data := map[string]any{
"extraLines": max(0, 10 - len(lineItems)),
}

For data-driven loops, see the workhorse command:

jx:each →