Skip to content

Word, Excel and HTML Templates

All template tags work the same in every format. What differs is how you lay out tables, where you put images and which elements you can remove with conditions. This page collects the tips for each format.

FeatureWordExcelHTML
Values, loops, formatters, conditions✓✓✓
Totals and set✓✓✓
Images and barcodes✓ alt text✓ alt text✓ src attribute
Links✓✓ path without braces✓ href attribute
drop / keepall elementsrow, coltable, row, col, p, div, span
Dynamic colours✓✗✓ via CSS
html formatted text✓✗✓
imageFit✓✗use CSS

Word (DOCX)

Word is the best choice for classic quotes and offers: multi-page documents with headers, footers, page numbers, a table of contents and long terms and conditions.

Build the layout with Word features

Use what Word already does well and only add tags where data is needed:

  • Use styles for headings and body text, so the generated document looks consistent.
  • Put your logo, company details and page numbers in the header and footer.
  • Use tables for product lists. Put each loop in its own table.
  • Use Word’s own page number fields. They keep working in the generated PDF.

Tables and loops

  • Put the [i] tags in one table row and the [i+1] tag in the row below. For nested loops, add one end row per level (see BoM price table).
  • Style the [i] row exactly as you want every product row to look. The [i+1] row is removed, so its styling doesn’t matter.
  • To repeat the table heading on every page, select the heading row → Table Properties → Row → Repeat as header row at the top of each page.
  • To avoid a product row being split over two pages, uncheck Allow row to break across pages for that row.

Headers and footers

The header, body and footer are separate parts of the document. You can use any single value in a header or footer, for example:

Quote {d.id}-{d.revision_number} · {d.name} · {d.created_at:formatD('DD-MM-YYYY')}

A loop must start and end in the same part. You can’t start a loop in the body and end it in the footer. Totals (aggSum, aggStr) are single values, so they work in headers and footers too.

Merged cells

Merged cells inside a looped row are not preserved. If you need a merged cell next to repeated rows, place the repeated rows in a nested table inside a cell of an outer table. Set the inner table’s cell margins to 0 so the nesting is invisible.

Images and text boxes

  • Set images inside loops to In line with text. Floating images, shapes and text boxes inside loops can produce an invalid document.
  • Put the tag for a dynamic image in the image’s alternative text. See Product images.

Page breaks in loops

To start every item on a new page without an empty page at the end, don’t add a manual page break at the end of the block. Instead, select the first paragraph of the repeated block → Paragraph → Line and Page Breaks → enable Page break before.

Styling tags

  • The output takes the formatting of the first { of the tag.
  • To keep the template readable, set the font size of the rest of a long tag to 1 pt.
  • Switch off smart quotes before typing tags. See Editor setup.

Excel (XLSX)

Excel templates are ideal for price lists, BoM exports and calculations that customers want to continue working with.

Numbers must be real numbers

Excel only applies number formats (currency, percentage, thousands separators) to cells that contain a real number. Add formatN to every tag that outputs a number, so the value is written as a number instead of text:

TagCell formatResult in Excel
{d.conf_total:formatN}#,##0.00 "kr"516,551.00 kr (a number you can calculate with)
{d.conf_total}#,##0.00 "kr"516551 (can be stored as text, so the format is ignored)

In Excel templates, the number of decimals comes from the cell format, not from the formatter. formatN, formatN(0) and formatN(2) all write the same number.

Loops in Excel

Put the [i] tags in one row and the [i+1] tag in the row below, just like a Word table:

ABC
1DescriptionArticle No.Price
2{d.form_submissions[0].form.data.elements[i].options[i, price!=0].label}{d.form_submissions[0].form.data.elements[i].options[i, price!=0].slug}{d.form_submissions[0].form.data.elements[i].options[i, price!=0].price:formatN}
3{d.form_submissions[0].form.data.elements[i].options[i+1, price!=0]}
4{d.form_submissions[0].form.data.elements[i+1]}
5Total{d.form_submissions[0].form.data.elements[].options[].price:aggSum:formatN}

Formulas

Tags and Excel formulas must be in separate cells. Because loops add rows, a normal =SUM(C2:C3) doesn’t grow with the data. Use one of these options for totals below a loop:

  • Use a total tag: {d.form_submissions[0].form.data.elements[].options[].price:aggSum:formatN}.

  • Use a formula that sums everything from the first data row to the row above the total:

    =SUM(INDIRECT("C2:C" & ROW()-1))

Limitations

  • drop and keep only support row and col.
  • Dynamic colours, html and imageFit are not available.
  • For links, enter the path without curly braces as the link address, for example d.user.email.
  • Sheet names can’t be generated from data.

HTML

HTML templates give you full control over the design with CSS. They are a good choice when you want a modern, brand-styled PDF.

Basics

  • Write a complete HTML page with a <style> block or inline styles. Everything you can do with CSS for print is available.
  • Tags work in text and in attributes: src, href, style, class.
  • Loops repeat <tr>, <li>, <div> or any other element:
<table>
<tr>
<td>{d.form_submissions[0].form.bom.tables[0].groups[i].rows[i].optionRows[i].optionColumns[field='name'].value}</td>
<td class="num">{d.form_submissions[0].form.bom.tables[0].groups[i].rows[i].optionRows[i].optionColumns[field='sales_price'].value}</td>
</tr>
<tr><td>{d.form_submissions[0].form.bom.tables[0].groups[i].rows[i].optionRows[i+1]}</td></tr>
<tr><td>{d.form_submissions[0].form.bom.tables[0].groups[i].rows[i+1]}</td></tr>
<tr><td>{d.form_submissions[0].form.bom.tables[0].groups[i+1]}</td></tr>
</table>

Images

Use an absolute URL or a data URI in src. Relative paths such as logo.png don’t work, so host your logo online or embed it as a data URI:

<img src="https://yourcompany.com/logo.png" style="height: 40px;">
<img src="{d.form_submissions[0].form.data.elements[label='Robot'].options[0].image}" style="width: 160px;">

Line breaks

Descriptions and text-area fields can contain line breaks. Keep them with CSS:

.description { white-space: pre-line; }

Dynamic styling

Because tags work inside attributes, you can style elements based on the data:

<tr style="color: {d.form_submissions[0].form.data.elements[i].options[i].price:ifLT(0):show('#C0392B'):elseShow('#1F2933')};">
<div style="display: {d.vat_total:ifGT(0):show('block'):elseShow('none')};">
VAT: {d.vat_total:formatN(2)} {d.currencyCode}
</div>

Page breaks

.page-break { break-before: page; page-break-before: always; }
<div class="page-break"></div>

Fonts

Web-safe fonts such as Arial, Helvetica or Georgia give the most reliable result. Always include a generic fallback in your CSS, for example font-family: Arial, sans-serif;.

A complete, ready-to-use HTML quote template is available on the Example Quote Template page.