Filling Word, Excel and PowerPoint templates in n8n

This page answers the question completely, including the two routes that do not involve us. It is written by the people who build DocMint, so the recommendation at the end is not neutral — but the facts are checkable, and where a route is better than ours we say so. Everything here was verified on 29 August 2026.

n8n has no core node for this

Worth stating plainly, because it is the first thing people search for and the answer is short: n8n ships no built-in node that fills a .docx, .xlsx or .pptx template from workflow data. The Convert to File and Extract from File nodes handle CSV, JSON, spreadsheets-as-data and binary conversion; none of them opens a Word template and replaces placeholders in it. The Google Docs node can do a text replacement inside a Google document, which is a different thing and only works if your template lives in Google Docs.

So the choice is between a community node, an HTTP call to a rendering service, and running a templating library yourself inside a Code node.

The three routes

Community nodeHTTP Request nodeCode node + library
SetupInstall once, credentials onceNone — the node is built inSelf-hosted n8n only
Works on n8n CloudYes — verified nodeYesNo
Placeholders as real fieldsYesNo — you write the JSONNo
Data leaves your networkYesYesNo
CostPer documentPer documentFree core; paid modules for Excel, slides, images

Route 1: the community node

n8n-nodes-docmint is on npm — version 0.2.1, published 4 September 2026. It is the official node for this service: we build and run DocMint and we publish the package. It exposes three resources:

The template picker is a searchable list rather than a name you have to remember, and the fill operation uses n8n's resourceMapper: the template's own placeholders are fetched and shown as real n8n fields, each one mappable to an expression, instead of a JSON textarea you fill in blind. There is still a raw-JSON toggle for when a whole object arrives from an earlier node.

Installing it — Cloud and self-hosted

Be careful with claims here, including ours. There are two different install paths and they have different requirements:

Self-hosted n8n: available now. Settings → Community nodes → Install, enter n8n-nodes-docmint. Or set N8N_COMMUNITY_PACKAGES_ALLOW_TOOL_USAGE=true and install from npm in the usual way. This works today.

n8n Cloud: available now. n8n published version 0.2.0 in its verified community-node registry on 4 September 2026. In the Nodes panel, open More from the community, find DocMint and install it with one click. n8n permits owners and admins to install verified nodes; members need one of them to do this. Cloud currently serves 0.2.0 while npm has the documentation-only 0.2.1 release; the node code is the same.

Then add a credential: DocMint API, with a key that starts dm_live_. A key is one API call away and needs no card:

curl -X POST https://docmint.app.mintapis.com/v1/signup \
  -H "Content-Type: application/json" \
  -d '{"email":"you@example.com","password":"a-long-enough-password"}'

{ "email": "you@example.com",
  "api_key": "dm_live_…",
  "plan": { "id": "free", "name": "Free", "credits": 30 },
  "note": "This is the only time the key is shown. Store it now." }

Route 2: a plain HTTP Request node

This needs nothing installed and works on n8n Cloud today. One HTTP Request node, and the binary comes back on the item.

SettingValue
MethodPOST
URLhttps://docmint.app.mintapis.com/v1/render
AuthenticationGeneric → Header Auth → Authorization: Bearer dm_live_…
Send Bodyon, JSON
Response → FormatFile — this is the setting people miss; leave it on JSON and you get bytes as mangled text
{
  "template": "invoice",
  "data": {
    "invoice_no": "{{ $json.number }}",
    "customer":   "{{ $json.customer.name }}",
    "items":      {{ JSON.stringify($json.lines) }}
  },
  "output": "pdf"
}

The document comes back as binary on the item, ready for the Gmail, Google Drive or S3 node that follows. Ask for "output": "document" for the Office file, "pdf" for a PDF, or "both" — that is per request, not fixed per template.

Two response headers are worth mapping into your workflow: x-docmint-credits-remaining, and x-docmint-warnings, which is non-zero when the render succeeded but something in it deserves a look.

Route 3: a Code node and a library

On self-hosted n8n you can skip the network entirely: allow an external module (NODE_FUNCTION_ALLOW_EXTERNAL=docxtemplater,pizzip) and fill the template inside a Code node. If your documents must not leave your network, this is the right answer and no API can beat it — the data protection argument is settled by the data not moving.

What you take on: docxtemplater's free core covers {tag} replacement, conditions and loops in Word. Excel templating, PowerPoint slide control, images, HTML and knowing where a tag failed are separate commercial modules at €500 per module per year, per their pricing page on 29 August 2026. There is also no PDF step — you would need LibreOffice on the n8n host. And the default for a missing value is to write the literal word undefined into the document, which is configurable but is what you get if you do not know to change it. The longer comparison is here.

The thing that saves the most time

Whichever route you take, the loop that actually costs you the afternoon is this: the placeholder names live inside a zipped binary, so you guess the JSON keys, render, open the file in Word, find the field that came out empty, and guess again.

Ask instead. POST /v1/inspect, or the node's Inspect operation, returns a typed, nested field list with a ready-to-POST skeleton — free, no document, no credit. Live output from 29 August 2026, abridged:

{ "format": "docx",
  "fields": [
    { "name": "invoice_no", "scope": "", "type": "string", "required": true,
      "locations": ["word/document.xml, paragraph 1"] },
    { "name": "items", "scope": "", "type": "array", "repeating": true,
      "formatters": ["sumProduct", "currency"] },
    { "name": "price", "scope": "items", "type": "number", "required": true } ],
  "names": ["invoice_no","customer","description","qty","price","items"],
  "sample_data": { … a skeleton you can POST straight back … } }

scope is why the node can render a repeating section instead of a textarea: price lives inside items, and the response says so.

And when the data is wrong anyway, the render fails loudly instead of quietly. Measured live today, with price missing from a line item:

HTTP 422 — no document, and the credit is refunded

{ "error": {
    "code": "placeholder_unresolved",
    "message": "The template uses {price|currency} but the data has no \"price\".",
    "hint": "Add \"price\" to the data, or write {price|default:} to allow it to be absent.",
    "details": { "field": "price",
                 "location": "word/document.xml, paragraph 2",
                 "available": ["invoice_no","customer","items","description","qty"] } } }

In n8n that arrives as a node error with the message intact, so "Continue on Fail" plus an alert branch gives you a workflow that never emails a customer a document with a blank total. The refund is a measurement, not a promise: eight failed renders while this page was written, and GET /v1/usage reported credits: 0 for all of them.

Which one to pick

Where the data comes from, if it arrives as an email. The mapping step assumes you already have fields. When the source is a mailbox — an order confirmation, a delivery note, a supplier invoice — the step in front of DocMint is a parser, not another template engine. MailMint is ours and does that half: an inbound address or an IMAP mailbox in, structured JSON out, with the message’s own SPF, DKIM and DMARC verdict attached. MailMint’s and DocMint’s nodes are both verified and available on n8n Cloud and self-hosted n8n.

Some honest limits before you build on this: DocMint runs on one small instance in Frankfurt with no SLA and no SOC 2 report, PDF conversion runs one at a time (1,346 ms server-side, measured today, so bursts queue rather than slow), the free tier is 30 documents a month, and there is no web dashboard. The full list is on the home page under "What DocMint does not do yet". Measured the same day: five consecutive .docx renders at 10 ms server-side, 54–74 ms round trip from Germany.