> For the complete documentation index, see [llms.txt](https://docs.apryse.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.apryse.com/web/generate/template-based-generation/generate-docx-template.md).

# Generate PDFs from DOCX/Word Templates using JSON and JavaScript

Generate DOCX/Word templates effortlessly with JSON data using JavaScript. Replace placeholders with dynamic content for personalized documents. Learn how to merge data seamlessly in this comprehensiv

WebViewer allows you to generate PDFs from DOCX, XLSX, or PPTX templates. Templates can be created in any application, and replaceable content is defined with `{{` curly brackets. The data can be merged from any data source in JSON format. Data merging is happening client-side without any server-side dependencies.

![](https://3532544125-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FX9YnTSKIHvV7m0A36LbO%2Fuploads%2Fgit-blob-83944acf8c30622179f3a098ac1deabcf42a616c%2Fd890bc566449ac649bfcc57c28f520f9f5049d3b-1440x480.png?alt=media)

You can watch the video below that walks you through it, or continue to the steps below.

{% embed url="<https://www.youtube.com/embed/pk5qI6WB5FM>" %}

## Load a DOCX template

First, we need to load a DOCX template either into the viewer, or into memory.

Download the simple template below to get started with your integration.

<a href="https://www.pdftron.com/docs/template-generation/tg_demo_repeated.docx" class="button primary">Download DOCX template</a>

The template can be DOCX, XLSX, or PPTX format with `{{placeholders}}` defined. Placeholders will preserve their original styling and can be replaced with text, images, or tabular data. The content will automatically reflow based on content length and paginate accordingly. [You can read more about the template files here.](/web/generate/template-based-generation/data-model.md)

To load your template file into WebViewer, you can use the `loadDocument` API.

{% tabs %}
{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
WebViewer(...)
    .then(async instance => {
        await instance.UI.loadDocument('/template.docx');
        
        instance.Core.documentViewer.addEventListener('documentLoaded', async () => {
            const doc = instance.Core.documentViewer.getDocument();
        });
    });
```

{% endcode %}
{% endtab %}
{% endtabs %}

[UI.loadDocument](https://sdk.apryse.com/api/web/UI.html#loadDocument__anchor)

Alternatively, you can load the document into memory like so:

{% tabs %}
{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
WebViewer(...)
    .then(instance => {
        const doc = await instance.Core.createDocument('/template.docx');
    });

```

{% endcode %}
{% endtab %}
{% endtabs %}

## Prepare your JSON Data

Next, we need to prepare our JSON data that will be injected into the template. The JSON data will replace the `{{}}` values in the template.

In the sample template you downloaded above, you can see there are three different instances of `{{short_text}}`. Whatever the value of `{{short_text}}` is in our JSON data will replace all of these values.

{% tabs %}
{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
WebViewer(...)
    .then(async instance => {
        await instance.UI.loadDocument('/template.docx');
        
        instance.Core.documentViewer.addEventListener('documentLoaded', async () => {
            const doc = instance.Core.documentViewer.getDocument();
            
            const jsonData = {
                short_text: "This is some text"
            }
        });
    });
```

{% endcode %}
{% endtab %}
{% endtabs %}

In the example above, we are hard coding the data. In a real world application, you would likely dynamically generate this JSON by pulling data from a database or some other data source.

The placeholders can also be automatically detected with [API](https://sdk.apryse.com/api/web/Core.Document.html#getTemplateKeys) to get the template keys.

{% tabs %}
{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
WebViewer(...)
  .then(instance => {
    instance.UI.loadDocument('/template.docx');

    const { documentViewer } = instance.Core;

    documentViewer.addEventListener('documentLoaded', async () => {
        const doc = documentViewer.getDocument();

        const keys = await doc.getTemplateKeys();
        console.log(keys);
    });
  });
```

{% endcode %}
{% endtab %}
{% endtabs %}

[getTemplateKeys](https://sdk.apryse.com/api/web/Core.Document.html#getTemplateKeys)

## Merge JSON data into DOCX template

Now that our data data is prepared, it is now ready to be merged. This is done by calling [`applyTemplateValues`](https://sdk.apryse.com/api/web/Core.Document.html#applyTemplateValues) on the document object.

{% tabs %}
{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
WebViewer(...)
  .then(instance => {
    instance.UI.loadDocument('/template.docx');

    const { documentViewer } = instance.Core;

    documentViewer.addEventListener('documentLoaded', async () => {
        const doc = documentViewer.getDocument();
        
        const jsonData = {
            short_text: "This is some text"
        }
        
        await doc.applyTemplateValues(jsonData);
    });
  });
```

{% endcode %}
{% endtab %}
{% endtabs %}

[doc.applyTemplateValues](https://sdk.apryse.com/api/web/Core.Document.html#applyTemplateValues)

If you have already loaded the document in WebViewer, the replacement will happen inline and the generated PDF will be immediately displayed.

If your document hasn't been displayed yet, you can load it in WebViewer by passing it to `loadDocument`.

{% tabs %}
{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
WebViewer(...)
    .then(instance => {
        const doc = await instance.Core.createDocument('/template.docx');
        
        const jsonData = {
            short_text: "This is some text"
        }
        
        await doc.applyTemplateValues(jsonData);
        await instance.UI.loadDocument(doc);
    });
```

{% endcode %}
{% endtab %}
{% endtabs %}

## Other Examples

The following are a series of real examples. For each example, the template source and the json data source are included, so that you can try them out yourself.

### Automatic reflow

<a href="https://www.pdftron.com/docs/template-generation/tg_demo_columns_reflow.docx" class="button primary">Sample template</a><a href="https://www.pdftron.com/docs/template-generation/template_params_utf8.json" class="button primary">Sample JSON</a>

Text reflows according to the rules set in the original template file, and will automatically generate extra pages if needed. Make use of column layouts and justification rules. This example uses a list loop with dynamic item renumbering.

![](https://3532544125-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FX9YnTSKIHvV7m0A36LbO%2Fuploads%2Fgit-blob-a9c9c7648ec09f2770c806a37f61a83e6ab3383d%2F0f914a56723bf56c24cd0fb3c791495ce929892d-1440x502.png?alt=media)

{% tabs %}
{% tab title="JSON" %}
{% code lineNumbers="true" %}

```json
{
	"legal_heading":"End-User Agreement",
	"legal_clauses": [
		{"legal_clause":"Sed ut unde omnis iste natus error sit volup tatem..."},
		{"legal_clause":"Lorem ipsum dolor sit amet, consec tetuer adipi s..."},
		{"legal_clause":"pretium quis, sem. Nulla conse quat massa quis eni..."},
		{"legal_clause":"idunt. Cras dapibus. Vivamus elem entum semper nis..."}
	]
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

### Dynamic tables

<a href="https://www.pdftron.com/docs/template-generation/tg_demo_styled_table_loop.docx" class="button primary">Sample template</a><a href="https://www.pdftron.com/docs/template-generation/template_params_utf8.json" class="button primary">Sample JSON</a>

Dynamically insert or remove rows into tables using loops and conditionals. Table formatting such as row bands are updated. Especially useful for invoice generation.

![](https://3532544125-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FX9YnTSKIHvV7m0A36LbO%2Fuploads%2Fgit-blob-da5d3c7b6a19b19571b85cb2869ed5fb1aba555a%2F74a6dc14372bedfbea43d9a06327bf737706af78-1437x497.png?alt=media)

{% tabs %}
{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
{
	"items": [
		{"item": "Wireless", "charge": "$42.34"},
		{"item": "Long Distance", "charge": "$12.55"},
		{"item": "Data", "charge": "$14.89"}
	],
	"balance":"$12.52",
	"total_due":"$82.30",
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

### Insert images

<a href="https://www.pdftron.com/docs/template-generation/tg_demo_logo.docx" class="button primary">Sample template</a><a href="https://www.pdftron.com/docs/template-generation/template_params_utf8.json" class="button primary">Sample JSON</a>

Insert images into the text at any location using the `image_url` value specifier. Images can be resized as desired, and inserted at any position in the original document.

![](https://3532544125-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FX9YnTSKIHvV7m0A36LbO%2Fuploads%2Fgit-blob-44fb31d8dc44fcb20fbd3f6585dac0a7428176be%2F1d6544aac1e26cd8d548bb7daeaa560d0315e010-1440x480.png?alt=media)

{% tabs %}
{% tab title="JSON" %}
{% code lineNumbers="true" %}

```json
{
	"logo":{"image_url":"./logo_red.png", "width":40, "height":40}
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

### Reflow around figures

<a href="https://www.pdftron.com/docs/template-generation/tg_demo_logo.docx" class="button primary">Sample template</a><a href="https://www.pdftron.com/docs/template-generation/template_params_utf8.json" class="button primary">Sample JSON</a>

Automatically flow text around obstacles according to the template.

![](https://3532544125-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FX9YnTSKIHvV7m0A36LbO%2Fuploads%2Fgit-blob-e0f33978ee802bb4ad913580efadeec70fdb896a%2F3164d8efc69b1b7ff658d6f7a5a4ffecb7e5db7e-1440x480.png?alt=media)

{% tabs %}
{% tab title="JSON" %}
{% code lineNumbers="true" %}

```json
{
	"long_text": "Sed ut perspiciatis unde omnis iste natus..."
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

## Further Reading

For more information, see the following resources:

[Detailed specification of the template generation data model](/web/generate/template-based-generation/data-model.md) To find out more details about the specification about the data model

[Advanced features](/web/generate/template-based-generation/advanced.md) For a specification of advanced features, and greater detail on behavior

[Live Web Sample](https://sdk.apryse.com/samples/web/samples/advanced/template-fill/) To try a live sample of template filling using our WebViewer


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.apryse.com/web/generate/template-based-generation/generate-docx-template.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
