---
title: "Generate Word documents server-side | Nutrient"
canonical_url: "https://www.nutrient.io/guides/document-engine/pdf-generation/from-word-template/"
md_url: "https://www.nutrient.io/guides/document-engine/pdf-generation/from-word-template.md"
last_updated: "2026-05-23T00:08:18.043Z"
description: "Learn how to populate DOCX templates with data and convert them to PDF. Discover configuration tips and templating essentials in our comprehensive guide."
---

# Generate Word documents

This guide explains the process of populating Office DOCX templates with data. The resulting DOCX file can then be [converted into a PDF document](https://www.nutrient.io/guides/document-engine/conversion/office-to-pdf.md).

This is useful for automatically generating documents like invoices, contracts, reports, or letters where the layout stays the same but the content changes based on your data.

> Populating DOCX templates with data and converting DOCX files into PDF documents require special licenses. Contact [Sales](https://www.nutrient.io/contact-sales) for more information.

## General principles

Word templating consists of the following elements:

1. A DOCX file that will be used as the template.

2. A template model that contains the placeholder values to replace in the DOCX template.

3. Configuration for the template model.

## Template model

The template model must contain:

1. A configuration containing both a start and end delimiter. The default delimiters are `{` and `}`, and both can be configured in the request.

2. At least one placeholder-value pair. The placeholder name must correspond to the placeholder defined in the DOCX template.

## Populating a document

Document Engine supports replacing placeholder text strings, automatic reflow, loops, and dynamic tables.

### Text replacement

Consider the following DOCX content:

```

Hello my name is {name}.
There is {more}.

```

Use the following model:

```json

"model": {
  "name": "Petey Eff",
  "more": "lorem ipsum dolor sit amet."
}

```

The output DOCX document will be:

```

Hello my name is Petey Eff.
There is lorem ipsum dolor sit amet.

```

### Loops

Consider the following DOCX content:

```

{ledger}:
{#items} {name} {price} {/items}

```

Here, `items` is the name of the loop, and `name` and `price` are placeholders for repetitive elements. Consider the following model:

```json

"model": {
  "ledger": "Tom's groceries",
  "items": [
    { "name": "A", "price": 10 },
    { "name": "B", "price": 15 }
  ]
}

```

The outcome in the output DOCX document will be:

```

Tom's groceries:
A 10
B 15

```

### Request example with custom delimiters

This example demonstrates dynamically populating a DOCX template with custom delimiters (`{{` and `}}`) using a request to the [`/api/process_office_template`](https://www.nutrient.io/api/reference/document-engine/upstream/#tag/Document-Editing/operation/process-office-template) endpoint:

### CURL

```bash

curl -X POST http://localhost:5000/api/process_office_template \
  -H 'Authorization: Token token=<API token>' \
  -H 'content-type: multipart/form-data' \
  -F 'document=@/path/to/template.docx'
  -F 'model={
    "config": {
      "delimiter": {
        "start": "{{",
        "end": "}}"
      }
    },
    "model": {
      "placeholder": "replacement value",
      "loop-name": [
        {
          "placeholder-within-loop": "replacement value",
          "another-placeholder-within-loop": "replacement value 2"
        },
        {
          "placeholder-within-loop": "another replacement value",
          "another-placeholder-within-loop": "another replacement value 2"
        }
      ]
    }
  }' \
  --output result.docx

```

### HTTP

```http

POST /api/process_office_template HTTP/1.1
Authorization: Token token=<API token>
Content-Type: multipart/form-data; boundary=customboundary

--customboundary
Content-Disposition: form-data; name="document";

template-document
--customboundary
Content-Disposition: form-data; name="model";
Content-Type: application/json

{
  "config": {
    "delimiter": {
      "start": "{{",
      "end": "}}"
    }
  },
  "model": {
    "placeholder": "replacement value",
    "loop-name": [
      {
        "placeholder-within-loop": "replacement value",
        "another-placeholder-within-loop": "replacement value 2"
      },
      {
        "placeholder-within-loop": "another replacement value",
        "another-placeholder-within-loop": "another replacement value 2"
      }
    ]
  }
}
--customboundary

```

**Understanding the above example**

Consider a DOCX template with the following content:

```

Invoice for: {{customer}}

Products:
{{#products}}

{{name}} - ${{price}}
{{/products}}

```

Use the following model:

```json

"model": {
  "customer": "Acme Corporation",
  "products": [
    { "name": "Widget A", "price": "29.99" },
    { "name": "Widget B", "price": "49.99" }
  ]
}

```

The output DOCX document will be:

```

Invoice for: Acme Corporation

Products:
Widget A - $29.99
Widget B - $49.99

```
---

## Related pages

- [Generate a PDF from images](/guides/document-engine/pdf-generation/from-images.md)
- [Server-side PDF generation](/guides/document-engine/pdf-generation.md)
- [Preview document thumbnails](/guides/document-engine/pdf-generation/thumbnail-preview.md)

