docx-templates JavaScript Tutorial – Docs gen from Templates

docx-templates JavaScript Tutorial – Create Word Documents from Templates

Portrait of documami document automation expert
Ben A.

Documami expert

This docx-templates JavaScript tutorial walks you through generating Word documents from .docx templates directly in the browser. Using the docx-templates library, you can fill a Word template with dynamic data from an HTML form and download the result as a .docx file — no server required. For advanced techniques like loops, dynamic images, and multi-library comparisons, see our Advanced JavaScript Document Generation guide.

Imagine you have a form that collects information about the overdue books and the library member’s details. With docx-templates, you can easily take this data and populate a Word template, creating a professional document in the docx format. This method is efficient and eliminates the need to update notices, streamlining your workflow manually.

We’ll guide you step-by-step on setting up the template, collecting data from the form, and generating the final document. By the end of this post, you’ll be able to produce customized Word documents quickly and efficiently, similar to how you might use a Microsoft or Google Document template but directly within your JavaScript application. Let’s get started!

Table of Contents

What is the Docx-Templates Library?

Docx-Templates is a JavaScript templating engine library for generating docx documents from templates. It supports both browser and Node.js which enables catering to a wide range of solutions and architectures. Some of its features include:

  • substitution of template variables with provided data
  • using queries in GraphQL and SQL inside templates
  • executing JavaScript snippets and injecting the results into the document
  • dynamically embedding images, hyperlinks, and HTML into the document
  • using conditions, loops, and aliases in the document template
  • injecting literal XML into documents

It was created by Guillermo Grau Panea and actively maintained by over 20 contributors. The code is distributed under the MIT License. For additional information check out:

Getting Started

Our first step towards generating documents from a Word template is ensuring we have all the required project resources. Despite the urge to jump right in and generate a Word document,  it’s crucial to understand what our goals are and what is required, even in a small project like this one.

You can find the complete working code in our codesandbox example.

Planning our project

As mentioned in the introduction, we will use a simple use-case scenario to demonstrate how docx documents can be generated using JavaScript. In our scenario, we’ll create a form that collects a book library’s user account and book information and then automatically generates a notice letter for overdue books. Let’s break down the different scenario components:

1. Collecting the required information using a form

We’ll create an HTML file that contains a form collecting the following information:

  • Letter date – the date of creating the document
  • Account ID – the identification number of the library’s user account
  • Account title – an optional prefix for addressing the account owner such as Mr. or Dr.
  • First name – the account owner’s first name
  • Last name – the account owner’s last name
  • Books count – the amount of overdue books
  • Due date – the final date to return the books before the account owner is fined
  • Fine amount – the amount of money the account owner is charged in case they do not return the books until the due date

2. Creating the document template that will be used to generate our notice letters

We’ll create a Google Docs or MS Word template that will contain all of our notice letter’s design and text along with variables and logic that will be replaced by the templating engine every time we generate a new notice letter based on the information gathered from the HTML form.

3. Creating the notice letter document by using a document template

Once the user submits the information we’ll use the docx-templates library to create the letter document. This will require:

  • Collecting the form data and formatting it as a javascript object that can be interpreted by docx-templates
  • loading the document template as a buffer that can be interpreted by docx-templates

Once we have both the form information and template in the correct format we can send it to docx-templates for the template variables to be replaced with data.

4. Downloading the created letter document

In the final step of the scenario, we’ll enable downloading the document created by the templating engine to the user’s computer. We’ll use the account ID as part of the file name, as well as set the appropriate file extension (.docx) and MIME type for downloading the document.

Setting up our project environment

Now that we have a clear understanding of what our project goals are and how we plan to achieve them, we’ll need to set up our environment. We’ll need 3 items to complete our project:

  • Code editor – we’ll need a way to create our project’s javascript, CSS, and HTML files. Any text editor will do, but using a code editor will make things a lot easier.
  • Web Browser – since our HTML and javascript code will run locally, we’ll need a browser to access to user interface. 
  • Web server – to avoid issues with loading javascript files, we’ll need a web server to serve our files to the browser. Any lightweight web server will do, as we don’t need to do any processing on the server side, only serving the pages to avoid issues with security restrictions. There are many web servers to choose from, here are a few links to get you started:

Once we have all 3 items, we can create the basic structure of our project. Select a folder on your local computer to store the project files. We’ll be creating 4 files in this project:

  • index.html – our HTML file containing the Form that collects the required information
  • script.js – our javascript file containing all of our script logic
  • style.css – a file containing our style definitions in CSS format
  • template.docx – our template file that we can create using MS Office Word or Google Docs

For now, we’ll create the first 3 files in our project directory and keep them empty. You can create a basic HTML file as index.html just to test that your web server is functioning properly if needed.

Building the Input Form To Collect Our Data

Now that we have completed our project plan and setup we can start building our solution. In this section, we’ll create the user interface that will allow entering the required information using the browser.

Creating the HTML Form

We’ll start by opening the index.html file we’ve created and adding the code below to create our HTML form. We’ll create an input field in the form for each of the information items we wish to collect.

				
					<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>docx-templates browser example</title>
    <link rel="stylesheet" href="style.css" />
  </head>
  <body>
    <div class="input-div">
      <h1>Library Books Late Notice Generator</h1>
      <form id="input-form" class="input-form">
        <label for="docdate">Document date:</label>
        <input type="date" name="docdate" id="docdate" required />
        <label for="accid">Account ID:</label>
        <input type="text" name="accid" id="accid" required />
        <label for="title">Title:</label>
        <select id="title" name="title">
          <option value="none">none</option>
          <option value="Mr.">Mr.</option>
          <option value="Mrs.">Mrs.</option>
          <option value="Ms.">Ms.</option>
          <option value="Dr.">Dr.</option>
          <option value="Prof.">Prof.</option>
        </select>
        <label for="firstname">First name:</label>
        <input type="text" name="firstname" id="firstname" required />
        <label for="lastname">Last name:</label>
        <input type="text" name="lastname" id="lastname" required />
        <label for="booksnum">Books:</label>
        <input
          type="number"
          name="booksnum"
          id="booksnum"
          min="1"
          value="1"
          required
        />
        <label for="duedate">Due date:</label>
        <input type="date" name="duedate" id="duedate" required />
        <label for="fineamount">Fine amount ($):</label>
        <input
          type="number"
          name="fineamount"
          id="fineamount"
          min="0"
          value="10"
        />
        <div class="input-row">
          <input type="submit" value="Create document" class="input-btn" />
          <input
            type="button"
            id="form-reset"
            value="Reset"
            class="input-btn"
          />
        </div>
      </form>
    </div> <script src="script.js" type="module"></script> </body>
</html>

				
			

Notice each <input> element has a name and id properties. The name property will be used in the document template later in the process as a placeholder for dynamic data. The id property will be used in the javascript logic to access specific values from different inputs (such as changing the due date format).

In addition, you can add the required property to form elements that are required before submitting the information. If a required field does not have a value, the user will be asked to fill it in before submitting.

Once complete, you can open index.html with your browser to see the result. Although all functionality is there, as you can tell, it is not very tidy and needs some additional styling to make it easier to use.

You can learn more about building HTML Forms on the W2Schools website.

Styling The Form Elements

To make our user interface clearer we’ll use CSS to change the look and feel. Open the style.css file, and copy the code below:

				
					.input-div {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 25px;
}

.input-form {
  display: flex;
  flex-direction: column;
  align-items: start;
  justify-content: center;
  row-gap: 10px;
}

.input-btn {
  font-size: 20px;
  background-color: green;
  color: white;
  border: 2px solid black;
  border-radius: 60px;
  padding: 5px 15px;
  margin-top: 15px;
}

.input-row {
  display: flex;
  flex-direction: row;
  column-gap: 10px;
}

h1 {
  text-align: center;
}

				
			

Now you can open/refresh the index.html file in your browser to see how the user interface has changed. You can learn more about CSS styling on the W3Schools website.

The final result in your browser should look like this:

A screenshot of the HTML form for the tutorial

Using JavaScript to Manage Form Actions

Finally, we’ll want to add some logic to our HTML file so that we can take action when the user submits or resets the form. Let’s open our script.js file and add the following code:

				
					//create event listener for form submit and reset when the page is done loading
window.addEventListener("load", (e) => {
  const input_form = document.getElementById("input-form");
  if (input_form) {
    input_form.addEventListener("submit", onFormSubmit);
  } else {
    console.error("No input form");
    return;
  }

  const form_reset_btn = document.getElementById("form-reset");
  if (form_reset_btn) {
    form_reset_btn.addEventListener("click", resetForm);
  }
});

//onFormSubmit will be executed when the HTML Form is Submitted.
//It will generate the final docx document based on the HTML Form inputs.
const onFormSubmit = async (e) => {
  //prevent form default submit action
  e.preventDefault();
  
  //we'll add logic here later
  
  //prevent browser url from changing
  return false;
};

//resetForm will be executed when the Reset button is clicked. 
//It will reset all HTML Form fields.
const resetForm = (e) => {
  const input_form = document.getElementById("input-form");
  if (input_form) {
    input_form.reset();
  }
};
				
			

The above code will trigger the onFormSubmit function every time the form is submitted, as well as the resetForm function every time the user clicks the “reset” button on the web page. You can test the functionality by adding a console.log() command to each of the functions to see that a log entry is added each time the buttons are pressed in the debug console. 

Now that we have our input form in place, we can proceed to create our document template based on the input fields of our form.

Creating the Document Template

Now that we have a user interface for supplying the information we need, it’s time to create the template that will be used to generate our notice letter documents. The template will include the static elements that are common to all notice letters such as text, images, and design. It will also include placeholders for dynamic data that will be replaced with the information provided in our form using the templating engine.

The basics of templating with Docx-templates

Docx-templates uses 3 items to generate a document: a data object, a template, and a string the defines dynamic data. It combines these items to create the final document:

Javascript object literal containing the input data

The JS object literal contains key and value pairs for the dynamic information we wish to use in the generated document. For example:

				
					const myData = {firstname: 'john', lastname: 'doe', id: '123456789'};
				
			

The key is the name that is used in the template file and its value will be injected when a document is generated. In the example above, using the term firstname in the template will be replaced by john in the final document.

It’s important to note that although JavaScript’s object literal may resemble JSON data, it is not a string-based structure like JSON but rather a native JS object. There are additional capabilities these objects offer, such as functions as values, that are useful in advanced templating engine configurations that are beyond the scope of this blog post. 

A string that indicates dynamic content in the template

To avoid collision between dynamic instructions and actual text in the template document, a specific string is configured that will start and end a dynamic phrase. Some common configurations include using +++dynamic content+++ or {{dynamic content}}.

For our example, we will use the {{dynamic content}} syntax (double curly braces). In the data object example above, this is meant to ensure that if the word ‘name’ exists in the document it will not be replaced with ‘john’, only {{name}} will be replaced by ‘john’.

Docx template file containing placeholders for the input data

Docx-templates has many options for creating dynamic templates. In this post, we will focus on 2 common actions: 

  • replacing template placeholders with specific form data – this is done by putting the variable name inside double curly braces: {{variable_name}}. Once the templating engine receives the document template along with the form data, it will replace the variable name with the actual value. This is useful for injecting names, dates, ID numbers, and any other dynamic value that needs to be placed in a specific location in the generated document. 
  • replacing template placeholders with different values based on a condition – Sometimes we want to inject different values based on a condition, such as using plural and singular terms if an item count is bigger than 1, or displaying paragraphs based on a specific condition. This is done by using one of two methods, depending on what you wish to achieve:
    • By using JavaScript’s ternary operator to implement an if-else structure: {{= item_count > 1 : `found $(item_count) item` : `found $(item_count) value` }}
    • By using a conditional section: {{IF user_type === ‘customer’}} Some Customer Text Here {{END-IF}}

You can read about all the different options docx-templates offers on the project’s GitHub page.

creating our notice letter document template

In our example scenario, we will use the name of each form input field as the key used in the template for getting its value. We do so since it’s easy to turn form data into a key-value literal object in JavaScript, as you will see in the upcoming section.

Here is our template:

Our template contains the following dynamic placeholders:

  1. At the top right corner of the template, we’ll place the document date form field value using {{docdate}}
  2. In the first row of the template content, we use a ternary operator to display the recipient’s name using {{= title !=`none` ? `${title} ${lastname}` : `${firstname} ${lastname}` }}. This means that if the title form input value is not ‘none’ we’ll display the title and last name (Dr. Doe), otherwise we’ll display the first and last name (John Doe).
  3. In the second row of the template content, we use another ternary operator to distinguish between singular and plural form depending on the number of overdue books by using {{= booksnum > 1 ? `are ${booksnum} books` : `is one book` }}. If the number of books (the booksnum input field) is greater than 1 we’ll use the plural form, otherwise, we’ll use the singular form.
  4. We’ll use a conditional section to display the second paragraph only if the fine amount filed (fineamount input field) is greater than 0 using {{IF fineamount>0}} and {{END-IF}}. This means that any content between the start and end of the condition will only be added to the document if there is a fine to be paid.
  5. Inside the fine charges paragraph, we’ll select the plural or singular form based on the number of books overdue using {{= booksnum > 1 ? `books are` : `book is` }}
  6. In the same paragraph we’ll use {{duedate}} to display the due date, {{fineamount}} to display the fine amount, {{firstname}} {{lastname}} to display the account owner’s full name, and {{accid}} to display the account id. 

Once the template is sent to the templating engine, all of the above rules will be processed along with the HTML form data to produce the requested document content.

Adding JavaScript Logic to Generate Our Word Document

Now that we have all the input information we need to create our notice letter generator, it’s time to add the JavaScript code that will execute the entire process. 

Before we proceed, we’ll need to add some code that will import the docx-templates browser version package, set the location of our template for later use, and set the MIME type of the generated document for downloading later on. Place the following code at the top of the index.js page:

				
					import { createReport } from "https://unpkg.com/docx-templates/lib/browser.js";

//template file location
const TEMPLATE_URL = "./docx-templates-js-template.docx";

//output file mime type
const FILE_MIME_TYPE =
  "application/vnd.openxmlformats-officedocument.wordprocessingml.document";

				
			

There are alternate ways of loading the docx-templates package such as installing the relevant packages from npm using the npm install command or downloading the relevant javascript files to the project folder. We chose to use a direct link for simplicity, but you can find more information on the project’s GitHub repository page.

Here is the complete content of our onFormSubmit function which handles the document generation logic:

				
					const onFormSubmit = async (e) => {
  //prevent form default submit action
  e.preventDefault();

  //get form data as object
  const input_form = document.getElementById("input-form");
  var formData = {};
  if (input_form) {
    formData = Object.fromEntries(new FormData(input_form));
  }

  //format the date selection input values
  const docdate = document.getElementById("docdate");
  if (docdate && docdate.value) {
    let newDocDate = new Date(docdate.value).toLocaleDateString("en-US", {
      dateStyle: "long",
    });
    formData["docdate"] = newDocDate;
  }
  const duedate = document.getElementById("duedate");
  if (duedate && duedate.value) {
    let newDueDate = new Date(duedate.value).toLocaleDateString("en-US", {
      dateStyle: "long",
    });
    formData["duedate"] = newDueDate;
  }

  //load the template file
  const template = await fetch(TEMPLATE_URL)
    .then((res) => res.arrayBuffer())
    .catch((err) => {
      console.error("Failed to fetch template file. Error:", err);
      return;
    });
  if (!template) {
    console.error("No template file found");
    return;
  }

  //generate the document
  const report = await createReport({
    template,
    data: formData,
    cmdDelimiter: ["{{", "}}"],
  });

  //set the output filename to the account id
  if (formData["accid"]) {
    filename = formData["accid"] + "_notice.docx";
  }

  //download the created document
  saveCreatedDocument(report, filename, FILE_MIME_TYPE);

  //prevent browser url from changing
  return false;
};
				
			

In the next sections, we’ll break it down step-by-step by functionality.

Collecting the Required Information Needed to Generate Our Document

We’ll start by obtaining the form input values when a form is submitted and storing it as a literal object with the field name as the key and the field value as the value.

				
					//get form data as object
  const input_form = document.getElementById("input-form");
  var formData = {};
  if (input_form) {
    formData = Object.fromEntries(new FormData(input_form));
  }
				
			

We’ll format the values of the date fields (document date and due date) into a more clear format to avoid confusion between the day and month. In this example, we’ll turn the dates into US English long date style: day month_name, year. 

				
					  //format the date selection input values
  const docdate = document.getElementById("docdate");
  if (docdate && docdate.value) {
    let newDocDate = new Date(docdate.value).toLocaleDateString("en-US", {
      dateStyle: "long",
    });
    formData["docdate"] = newDocDate;
  }
  const duedate = document.getElementById("duedate");
  if (duedate && duedate.value) {
    let newDueDate = new Date(duedate.value).toLocaleDateString("en-US", {
      dateStyle: "long",
    });
    formData["duedate"] = newDueDate;
  }
				
			

Finally, we’ll load the template we’ve created in the previous section into a variable in the format of a javascript array buffer, which is the format needed for docx-templates to read our template content.

				
					  //load the template file
  const template = await fetch(TEMPLATE_URL)
    .then((res) => res.arrayBuffer())
    .catch((err) => {
      console.error("Failed to fetch template file. Error:", err);
      return;
    });
  if (!template) {
    console.error("No template file found");
    return;
  }
				
			

Generating Our Document from a Template

With both template and data loaded and stored in the right format, we can now generate our output document. We’ll do so by calling the createReport function supplied with docx-templates. For this example, we’ll provide an object containing:

  • the template array buffer
  • a ‘data’ key with our form data formatted as a literal object
  • a ‘cmdDelimiter’ key with an array of starting and ending string delimiters. This is notifying the templating engine we’re using ‘{{‘ and ‘}}’ to indicate dynamic content in our template.

Note that the createReport function is asynchronous and requires using ‘await’ if you wish to pause the code execution until it is finished. We do so as we want to wait for the function to complete before proceeding to save our generated document. 

				
					//generate the document
  const report = await createReport({
    template,
    data: formData,
    cmdDelimiter: ["{{", "}}"],
  });
				
			

Saving Our Generated Document

The final step in our process is to save the document we generated from our Google Docs or MS Word template to the local computer drive. 

We’ll start by setting the file name based on the account ID set in the input HTML form, adding “_notice” and the “.docx” extension.

Then we’ll add a function for saving the generated file, and call it along with the file name and appropriate MIME type.

Finally, we’ll return false to ensure that the HTML will not redirect or reload, which is the default behavior when submitting forms. 

				
					//set the output filename to the account id
  if (formData["accid"]) {
    filename = formData["accid"] + "_notice.docx";
  }

  //download the created document
  saveCreatedDocument(report, filename, FILE_MIME_TYPE);

  //prevent browser url from changing
  return false;
				
			

Below is our saveCreatedDocument function. It accepts the file content (data), the file name (fileName), and the Mime type (mimeType). The function will create a download link, click it, and then remove the link after 1 second. This will automatically download the file once the function is called:

				
					const saveCreatedDocument = (data, fileName, mimeType) => {
  //create a url for document data
  const blob = new Blob([data], { type: mimeType });
  const url = window.URL.createObjectURL(blob);

  //trigger file download
  const a = document.createElement("a");
  a.href = url;
  a.download = fileName;
  document.body.appendChild(a);
  a.style = "display: none";
  a.click();
  a.remove();

  //revoke the document url after 1 second
  setTimeout(() => {
    window.URL.revokeObjectURL(url);
  }, 1000);
};
				
			

Testing Our Complete Solution

Now that our solution is complete you can test the entire process with your browser. Here are a couple of helpful tips:

  • Ensure you are accessing the webpage via the web server and not directly from the local drive, otherwise, you will probably get a CORS error when trying to import the docx-templates from a URL while your HTML is loaded from the local drive. This is because loading JavaScript as modules requires the same origin.
  • Use the browser’s developer tools to find errors in the console. We’ve added some console logging to the examples to help debug issues.

Final Thoughts: Using Docx-Templates to generate Word documents in JavaScript

Using JavaScript to generate Word documents is a game-changer for automating routine tasks. In our example, creating overdue book notices for library members becomes seamless and efficient. By leveraging the docx-templates library, you can transform form data into polished Word documents with ease.

This method saves time and reduces the chance of errors, ensuring every document generated is accurate and professional. No more manually updating each document; automation handles it for you. This improves workflow and allows staff to focus on more important tasks.

Experiment with the tools and adapt them to your specific needs. As you gain confidence, you’ll find new ways to optimize your processes.

Next steps

We hope you found our example useful and you are now ready to take it to the next level with more functionality and complexity. To expand on the lesson learned in this post you can:

Frequently Asked Questions

Using JavaScript to generate Word documents from templates offers several advantages. JavaScript is versatile and widely used, making it easy to integrate document generation into web applications. This method is efficient for dynamic content generation and ensures consistency across documents. With libraries like docx-templates, you can automate the creation of Word documents, saving time and reducing manual errors.

Pros include:

  • the ability to generate Word documents directly from a web form
  • seamless integration with other JavaScript code
  • the convenience of working within a familiar programming environment.
  • JavaScript can run on the client’s browser reducing server load and avoiding sending sensitive information over the network.

However, there are some cons:

  • JavaScript file handling can be complex, especially when dealing with large documents or extensive formatting.
  • Not all browsers support advanced file operations equally, which may cause compatibility issues.
  • A local web server may still be required as some JavaScript execution may be limited when running from the local computer drive.

Alternative methods include using server-side languages like Node.js, Python, or PHP to generate Word documents. Tools like Microsoft Word’s built-in mail merge or Google Docs scripts can also automate document creation but might lack the flexibility and seamless integration of a JavaScript solution.

Generating Word documents with JavaScript is powerful and flexible, especially for web-based applications. It simplifies workflows, enhances productivity, and ensures that documents are consistently formatted and accurate.

Sure. In terms of javascript packages that can run on the browser a couple of popular alternatives are:

  • using docxtemplater to generate documents from a template. Note that docxtemplater also has a paid version with additional functionality.
  • using docx to create or modify .docx files.

Both are very popular packages that are widely used. If you’re looking to develop a production app or service we advise you to take the time to understand the pros and cons of each package before committing to one.

The docx document format is a widely used file type for creating and sharing text documents. Introduced by Microsoft Word, it has become the standard format for word-processing documents. Unlike its predecessor, .doc, the .docx format uses XML and is essentially a zip file. The zip file contains various files and folders that define the document’s content, layout, and styles.

A docx file includes text, images, tables, and other elements in a structured format. This makes it easy to edit and share across different platforms. It is compatible with various word processing programs, including Microsoft Word and Google Docs, ensuring broad accessibility.

The docx format offers several advantages. It produces smaller file sizes, making documents easier to store and share. It also improves data recovery and reduces the risk of corruption compared to older formats. Additionally, because it is an open standard, developers can create tools and applications to generate and manipulate docx files programmatically.

Overall, the docx format enhances document compatibility, security, and functionality. This makes it a reliable choice for professional and personal use. Its flexibility and widespread support ensure that documents can be easily created, edited, and shared across various platforms and devices.

illustrated left thumb up

Skip the hard work

Developing document automation solutions takes time and effort.

We’ll develop a document generation solution that fits perfectly with your needs!

Related Posts