Class TemplateMarkers

java.lang.Object
io.keikai.axyra.sheets.template.TemplateMarkers

public final class TemplateMarkers extends Object
Data binding via template markers — a lightweight reporting layer built entirely on the public read/write API.

A marker is ${...} inside a text cell:

  • Scalar / nested path — ${name} or ${a.b.c}. Each hop resolves through a Map key, a record component, a JavaBean getter, or a public field; a null anywhere along the chain renders as a blank cell. A cell that is exactly one marker keeps the value's type (number/boolean/text); a marker embedded in other text yields text.
  • List — ${people.name} marks a template row bound to the list data.get("people") (a List of maps, records, or beans). The row is repeated once per record, inserting rows as needed, each record's fields substituted. Static text/values and formulas on the template row are copied to every record row; formula cells get Excel fill-down semantics (row-relative references shift by the record offset, $-anchored and sheet-qualified references stay untouched).
  • Aggregate — ${people.age:sum} (also :avg, :count, :min, :max) evaluates over the whole list and may sit in any non-template-row cell. :count counts non-null values of any type; the numeric aggregates render blank when the field has no numeric values.
  • Grouping — ${people.dept:group} on a template row groups the records by that field (stable first-appearance key order, original record order inside each group). An optional subtotal row immediately below the template row — recognized by ${people.age:subtotal-sum}-style markers (also -avg/-count/-min/-max) or ${people.dept:groupname} (the group's key) — is emitted once per group with that group's aggregate.
  • Image — ${image:logo} (or ${image:people.photo} on a template row) resolves to a byte[] that is inserted as a picture anchored at the cell (one-cell anchor, default 1×0.75 inch); the cell itself is blanked. Non-byte[] values just blank the cell.

Unknown markers resolve to empty. One list binds per template row (the first ${list.field} marker whose leading segment is a List wins). A subtotal row is recognized only under a grouped template row. Cell styles are not copied to inserted rows.

  • Method Details

    • process

      public static void process(Sheet sheet, Map<String,Object> data)
      Process every ${...} marker in the sheet against data.