Paragon

Reports authored in Word or PowerPoint

A report does not have to be an HTML page. It can be a real .docx or .pptx — written in Word or PowerPoint, by whoever normally writes the document — with {{ }} placeholders in it. The engine fills them in and hands back the file.

This guide is that route end to end. Authoring a report is the HTML one, and most of what it says about projects, assets and codes is true here too.


Which kind of report to write

Two kinds, one engine, and the choice is made once when the report is created.

HTML report Word or PowerPoint template
Written in HTML, CSS and JS, in the designer Word, or PowerPoint
Laid out by a browser Word, or PowerPoint
Produces PDF, Word, PowerPoint or Excel the one file it is written in
Best at dashboards, precise layout, anything visual documents people already have, and already maintain

Pick the office route when the document already exists. A statement, a contract, a certificate, a board deck — something a finance or legal team wrote, formats to their own standard, and expects to keep editing. Nobody has to rebuild it as HTML, and the people who own it keep owning it.

Pick HTML when the layout is the product. A dashboard of cards and charts is a browser's job. And if the report must come out as a PDF, it has to be an HTML report — see What it produces.

The rest of the engine does not change. Your application still calls GenerateAsync(code, json). Same catalog, same licence, same integrity hashes, same cache. Only the folder's contents differ.

The folder

An office template report is a folder like any other, named after the report code:

R-acme-erp-004/
  template.docx      the report — or template.pptx
  manifest.json      what the engine reads about it
  assets/            fonts, stylesheets, chart libraries
  parts/             HTML pages the document draws its pictures from

No p1.html, and no page setup. The document carries its own — page size, margins, headers, footers, section breaks, whatever its author set in Word. That is the point of authoring one.

The language is the same Handlebars

Not a dialect, and not a second template language. Same binder, same helpers, same paths. Anything true of {{ }} in a template.html is true of {{ }} in a template.docx.

{{customer.name}}                     a path
{{#each lines}}{{name}}{{/each}}      a block
{{#if overdue}}Late{{else}}Due{{/if}} a choice
{{../company.name}}                   the scope above this one
{{@index}}                            where you are in the loop

Every helper in Template helper reference works here — money, date, number, the comparisons, the logic. One exception: {{json}} writes a payload into an HTML data island for chart code to read, and a document has neither, so it simply prints the JSON as text.

Word breaks your placeholders up and it does not matter. As you type, Word splits a run wherever it likes — spellcheck, a revision mark, where the cursor happened to be — so {{amount}} is often three fragments on disk. The engine puts them back together before binding. Nothing to do, and nothing you could have done: Word never shows you this.

Where a marker may go

Three places, and only three.

Place Example
In the text a paragraph, a table cell, a text box the ordinary case
A picture's alt text {{paragonPart 'chart'}} the picture is replaced
A shape's alt text {{paragonFill colour}} slides only

Alt text is reached through Format → Alt Text on the picture or shape.

Never inside an attribute — not a fill colour, not a width, not a style id. Those fields are typed, so a placeholder in one is not a template with a marker in it, it is a broken file. PowerPoint notices and offers to repair the deck, and repairing strips the marker out. Word says nothing at all and silently drops it, which is worse. To colour something from data, see Colour from data.

Alt text is the exception because it is the one string Word and PowerPoint carry through a round trip without validating, reformatting or discarding.

Word

Marker Where it goes What it does
{{field}} in the text Fills in the value
{{#each items}} … {{/each}} both markers in one table row Repeats that row, once per item
{{#each items}} … {{/each}} each marker alone in its own paragraph Repeats the paragraphs between them
{{#if x}} … {{else}} … {{/if}} both markers in one run of text An inline choice between two pieces of text
{{#if x}} … {{else}} … {{/if}} markers in different rows Chooses between whole rows — this is how a row is shaded by a condition
{{paragonPart 'name'}} a picture's alt text Renders parts/name.html and drops the result in at the picture's size
{{field}} a picture's alt text Replaces the picture with an image the payload carries as base64
{{pageBreak}} in the text A page break

A block repeats the smallest thing that holds both of its markers. Put {{#each lines}} and {{/each}} in the first and last cell of one row and the row repeats. Put each on a paragraph of its own and the paragraphs between them repeat. That one rule is the whole of it, and nesting, {{else}}, {{@index}} and ../ all fall out of it, because Handlebars is doing the work.

PowerPoint

Everything above applies, in the same words. These are the things a slide adds.

Marker Where it goes What it does
{{#slides items}} anywhere on the slide, or in the slide's notes Repeats the whole slide, once per item. No closing marker — the slide is the scope. An empty list removes the slide
{{paragonFill field}} a shape's alt text Colours the shape from the payload. Six hex digits, no #
{{paragonPart 'name'}} a picture's alt text As in Word — and on a repeated slide it is given that slide's item, so a chart per region draws its own region

A repeating slide is usually the reason to build a deck from data at all — a slide per region, per customer, per line. Inside one, that item is the context, so the slide says {{name}} and still reaches the payload's root through {{../company.name}}. The copies keep their place, so the slides around them do not move.

Writing the marker in the slide's notes keeps an instruction off a slide that should not carry one.

Colour from data

A shape on a slide {{paragonFill field}} in its alt text
A Word table cell, with a fixed set of states Draw the row once per state, style each one in Word, and wrap the set in {{#if}}/{{else}} — the markers land in different rows, so the block picks a row
A Word table cell, colour straight from the data Not supported — a cell's shading is an attribute, and the rule above applies
Anything richer A web part, which is HTML and CSS and can do whatever those can

paragonFill leaves a real colour on the shape. Fill it in PowerPoint the way it should look — that is what the template shows its author — and the payload replaces it when the report is built.

Web parts

The parts/ folder holds ordinary HTML pages. A picture whose alt text is {{paragonPart 'name'}} is replaced by parts/name.html, rendered in a browser and photographed at exactly the size the picture occupies. That is how a chart gets into a document Word could not have drawn.

The page is bound before it is rendered, so it reads the payload the same way the document does:

<script id="report-data" type="application/json">{{json this}}</script>
<script>
  var data = JSON.parse(document.getElementById('report-data').textContent);
</script>

Reference CSS and JS from the report's assets/ folder as any page would. Nothing is fetched from the internet — the same rule as everywhere else in Paragon.

A part that draws asynchronously needs the same treatment as a chart on an HTML page: see Waiting for several asynchronous things.

What it produces

The file it is written in, and nothing else. A Word template gives a .docx; a PowerPoint template gives a .pptx. Not a PDF, and not each other.

That is a real limit and worth stating plainly: turning a .docx into a PDF needs Word or LibreOffice installed on the machine doing it, and Paragon deliberately depends on neither. A report that has to be a PDF is written as an HTML report, which has always produced all four formats.

Shipping it

Two buttons in the designer that are easy to confuse, because they hand back different things.

Download gives you the document alone — the file to open in Word, edit, and put back with Replace. That is the authoring round trip.

Export gives you the folder as a zip: the document, manifest.json, assets/ and parts/. That is what a consuming application needs. Unzip it into the application's template folder and the report is deployed — see Quick start for a consuming application.

The document travels byte for byte. Nothing rewrites it on the way out, so what you shipped is the file you last saved.

Things that will not work

A block marker typed between paragraphs. Give each marker a line of its own. Written loose between paragraphs on a slide, it is text in a place the format does not allow text, and PowerPoint will refuse to open the file. Word tolerates the same mistake, so it usually shows up on the deck first.

Literal {{ }} in prose. An empty pair is an expression Handlebars cannot compile, and a real pair is a placeholder rather than a description of one. A template that documents its own syntax to its reader has to say it in words.

A placeholder in a fill colour, a width or a style id. See Where a marker may go.

A PDF, or a deck out of a document. See What it produces.


When it fails

The four above are mistakes in the template: they produce a file that opens wrong, or does not open, rather than an error you can catch. These are the ones raised as exceptions.

Condition Exception
The template file is not a readable .docx or .pptx — truncated, or never an Office file InvalidOfficeTemplateException (the SDK's own error is the inner exception)
A readable package with no document part, or no presentation part InvalidOfficeTemplateException
The manifest says Word or PowerPoint and no template file was loaded OfficeTemplateMissingException (carries ReportCode and Format)
A {{paragonPart 'name'}} with no parts/name.html in the folder MissingWebPartException (carries Name and the Path it looked for)

All derive from ParagonException, so one catch still covers the route.

Everything that happens before the template is opened — the folder, the manifest, the assets — fails the same way it does for an HTML report, and those are in Report template format — schema 1.0. A marker that names a helper the engine does not have raises TemplateBindingException here exactly as it does on a page; see Template helper reference.

The worked examples

Three of them among the worked examples, and each is the real file — download it and open it in Word or PowerPoint.

Customer Account Statement A Word statement: a looped table, rows shaded by condition, and two web parts side by side
Biography A Word document at its plainest — paths, a loop over paragraphs, and a picture from the payload
Quarterly Business Review A deck using every slide marker, left visible on the slides on purpose