Template guide
Tables
Generate table rows automatically from a collection of data.
How it works
Create a table in your .odt template with placeholder cells. ODF-Report clones the template row for each item in your collection, replacing the placeholders in each clone.
Naming a table
To use a table with ODF-Report, it needs a name:
- In LibreOffice Writer, right-click on the table
- Select Table Properties...
- Type a name in the Name field (e.g.,
EMPLOYEES)
Basic usage
Given a template table named EMPLOYEES with cells containing [NAME] and [EMAIL]:
report = ODFReport::Report.new("template.odt") do |r|
r.add_table("EMPLOYEES", @employees) do |t|
t.add_column(:name)
t.add_column(:email)
end
end
This creates one row for each employee in @employees, with the placeholders replaced by the corresponding values.
add_column is an alias
add_column is just an alias for add_field. They work exactly the same way — use whichever reads better in context.
Column values
Columns support the same value resolution as fields:
r.add_table("ITEMS", @items) do |t|
# Method name matches placeholder name
t.add_column(:description)
# Different method name
t.add_column(:item_id, :id)
# Block transform
t.add_column(:price) { |item| format("$%.2f", item.price) }
end
Header rows
If your table has a header row, pass header: true to preserve it. The first row will be left untouched and only subsequent rows are used as templates:
r.add_table("ITEMS", @items, header: true) do |t|
t.add_column(:description)
t.add_column(:quantity)
t.add_column(:price)
end
| Description | Qty | Price |
|---|---|---|
| [DESCRIPTION] | [QUANTITY] | [PRICE] |
The header row ("Description", "Qty", "Price") stays as-is. The second row is the template.
Auto-detected headers
If your table uses the ODF table:table-header-rows element (set via Table Properties > Text Flow > Repeat heading), the header option is automatically detected and the header: true parameter is not needed.
Removing empty tables
Use skip_if_empty: true to remove the entire table when the collection is empty or nil:
r.add_table("OPTIONAL_DATA", @items, skip_if_empty: true) do |t|
t.add_column(:name)
end
Without this option, an empty collection would leave the template row (with unresolved placeholders) in the document.
Zebra rows (alternating styles)
If your template table has multiple rows below the header, they are cycled for each data item. This is useful for alternating row styles (e.g., different background colors):
| Header 1 | Header 2 |
|-------------|-------------|
| [COL1] | [COL2] | ← row style A
| [COL1] | [COL2] | ← row style B
ODF-Report alternates between the two template rows as it generates output, producing a zebra-striped table.
Formatting
Any formatting applied to the placeholder cells in the template is preserved. Font, size, color, alignment, cell borders, and background colors all carry over to the generated rows.