npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

n8n-nodes-temp-doc

v0.1.2

Published

n8n node for generating DOCX, XLSX, Markdown, and TXT files from templates

Readme

n8n-nodes-universal-templater

An n8n community node that generates DOCX, XLSX, Markdown, and TXT files from templates using a single, standardised JSON data structure.


Supported Formats

| Format | Engine | Template Syntax | |----------|-------------------|-----------------------------------------| | DOCX | docxtemplater | {key}, {#each rows}…{/each} | | XLSX | ExcelJS | {{key}}, {{rows[*].col}} | | Markdown | Handlebars | {{key}}, {{#each rows}}…{{/each}} | | TXT | Handlebars | same as Markdown |


Installation

In an existing n8n instance

# Inside the n8n user data directory
npm install n8n-nodes-universal-templater

Restart n8n. The Universal Templater node will appear in the node palette under the Transform group.

Local / development install

git clone https://github.com/your-org/n8n-nodes-universal-templater.git
cd n8n-nodes-universal-templater
npm install
npm run build

# Link into your local n8n
cd ~/.n8n/nodes   # or wherever N8N_CUSTOM_EXTENSIONS points
npm link /path/to/n8n-nodes-universal-templater

Node Parameters

| Parameter | Type | Default | Description | |-------------------------|---------|----------|------------------------------------------------------------------------------| | Output Format | Select | DOCX | The format of the file to generate. | | Input Binary Property | String | data | Binary property on the input item that holds the template file. | | Template Data | JSON | {} | Data object injected into the template. | | Output File Name | String | output | Base name for the output file (extension is added automatically). | | Output Binary Property | String | data | Binary property on the output item where the rendered file will be written. |


JSON Data Structure

The node expects a flat-or-nested JSON object. The recommended standardised shape is:

{
  "title": "My Report",
  "author": "John Doe",
  "date": "2024-01-01",
  "rows": [
    { "name": "Item 1", "price": 10.00, "qty": 2 },
    { "name": "Item 2", "price": 25.50, "qty": 1 }
  ]
}

All engines accept this shape. Scalar fields (title, author, date) are substituted wherever their placeholder appears. The rows array (or any other array) drives row expansion in XLSX and loop iteration in DOCX / Handlebars templates.


Template Syntax by Format

DOCX (docxtemplater)

docxtemplater uses single-brace tags inside a valid .docx file.

Dear {firstName} {lastName},

Please find below your order summary dated {date}:

{#items}
  - {name}: {qty} × ${price}
{/items}

Total items: {totalItems}

Tips:

  • Tags must be styled normally inside Word — do not split them across formatting runs.
  • Use {#arrayName}…{/arrayName} for loops.
  • Use {?condition}…{/condition} for conditionals.
  • See the docxtemplater docs for the full syntax.

XLSX (ExcelJS)

Place placeholder strings directly in cell values within a .xlsx template file.

Scalar replacement — any cell whose text contains {{key}} will have the token replaced with the matching value from the data object:

Cell A1: {{title}}
Cell B1: Generated on {{date}}

Array / table expansion — place one template row whose cells use the pattern {{arrayName[*].propertyName}}:

| Column A | Column B | Column C | |------------------------|------------------------|-----------------------| | {{rows[*].name}} | {{rows[*].price}} | {{rows[*].qty}} |

At render time the node will:

  1. Detect that row as a template row for the rows array.
  2. Duplicate the row once per item in data.rows.
  3. Fill each cell with the corresponding item property value.
  4. Delete the original template row.

Multiple independent template rows (for different arrays) are supported within the same sheet. They are processed bottom-up to keep row numbers stable.


Markdown & TXT (Handlebars)

Both formats use the full Handlebars templating language. The template is stored as binary text (UTF-8) on the input item.

Basic interpolation:

# {{title}}

**Author:** {{author}}
**Date:** {{date}}

Loops:

## Line Items

{{#each rows}}
- **{{name}}** — qty: {{qty}}, price: ${{fixed price 2}}
{{/each}}

Conditionals:

{{#if rows}}
The report contains {{rows.length}} items.
{{else}}
No items found.
{{/if}}

Built-in helpers registered by this node:

| Helper | Description | |-------------------------|------------------------------------------------------| | {{eq a b}} | True if a === b | | {{gt a b}} | True if a > b | | {{lt a b}} | True if a < b | | {{gte a b}} | True if a >= b | | {{lte a b}} | True if a <= b | | {{ne a b}} | True if a !== b | | {{json obj}} | Pretty-print an object as JSON | | {{upper str}} | Convert to UPPER CASE | | {{lower str}} | Convert to lower case | | {{trim str}} | Remove leading/trailing whitespace | | {{default val fallback}} | Return val if truthy, else fallback | | {{add a b}} | a + b | | {{subtract a b}} | a - b | | {{multiply a b}} | a × b | | {{divide a b}} | a / b (returns 0 on divide-by-zero) | | {{fixed num digits}} | Format number to fixed decimal places | | {{formatDate dateStr locale}} | Format a date string using toLocaleDateString |


Examples

Example 1 — Generate a Word invoice

Workflow:

  1. Read Binary File node — reads invoice_template.docx into binary property data.
  2. Set node — sets jsonData to the invoice data JSON.
  3. Universal Templater — format: DOCX, data property: data, output: invoice_2024.docx.
  4. Write Binary File or Send Email — uses the data binary output.

Template data:

{
  "invoiceNumber": "INV-2024-001",
  "clientName": "Acme Corp",
  "date": "2024-01-15",
  "rows": [
    { "description": "Consulting services", "hours": 8, "rate": 150.00 },
    { "description": "Expense reimbursement", "hours": 0, "rate": 75.00 }
  ],
  "total": 1275.00
}

Excerpt from invoice_template.docx:

Invoice #: {invoiceNumber}
Client: {clientName}
Date: {date}

{#rows}
{description}  |  {hours}h  |  ${rate}
{/rows}

Total: ${total}

Example 2 — Generate a Markdown report via HTTP

Workflow:

  1. HTTP Request node — GET https://api.example.com/data → JSON response.
  2. Function node — transforms API response into the standard data shape.
  3. Read Binary File node — reads report_template.md → binary template.
  4. Universal Templater — format: Markdown, input binary property: template, template data from expression {{ $json }}, output file name: report.
  5. Write Binary File — saves report.md.

Example 3 — Excel report with table expansion

Template sales_template.xlsx cell layout:

| A1: {{title}} | B1: (blank) | C1: (blank) | |---------------------|---------------------|--------------------| | A2: Month | B2: Revenue | C2: Units | | A3: {{rows[*].month}} | B3: {{rows[*].revenue}} | C3: {{rows[*].units}} |

Template data:

{
  "title": "Sales Report Q1 2024",
  "rows": [
    { "month": "January",  "revenue": 45200, "units": 312 },
    { "month": "February", "revenue": 51800, "units": 389 },
    { "month": "March",    "revenue": 63100, "units": 441 }
  ]
}

Output: Row 1 gets Sales Report Q1 2024 in A1; the template row (row 3) expands into three rows, one per month, then the template row is deleted.


Development

# Install dependencies
npm install

# Compile TypeScript (outputs to ./dist)
npm run build

# Watch mode
npm run dev

# Lint
npm run lint

# Format
npm run format

Project structure

n8n-nodes-universal-templater/
├── nodes/
│   └── UniversalTemplater/
│       ├── UniversalTemplater.node.ts   # Main INodeType implementation
│       ├── engines/
│       │   ├── docxEngine.ts            # docxtemplater wrapper
│       │   ├── xlsxEngine.ts            # ExcelJS placeholder engine
│       │   └── textEngine.ts            # Handlebars wrapper
│       └── utils/
│           └── binaryHelpers.ts         # Buffer ↔ IBinaryData conversion
├── index.ts                             # Package entry point
├── package.json
└── tsconfig.json

License

MIT