Releases RSS Feed
Compatibility : nodejs and browser

Summary (version 3.11.3) Buy table module

This module makes it easy to create a table from a configuration object (header, subheader, ...)

This module is available as part of the docxtemplater ENTREPRISE plan.


Table Module

This module exposes multiple tags to create or transform tables.

Currently, you can

  • Loop over table columns with the {:vt#users} {:vt/users} syntax (Vertical Loop Table)
  • Create a table from scratch with the{:table table1} syntax, (Full Table)
  • Create a table by copying a cell over and over with the {:#grid user} syntax (Grid Taable)
  • Merge cells that are adjacent vertically into a single cell by using the {:merge-cells-col 1} where 1 is the column number, starting from 1.


You will need docxtemplater v3: npm install docxtemplater

Install this module with npm install --save "$url"

Vertical Loop Table

To have the vertical-loop-table, write :

const TableModule = require("docxtemplater-table-module");
const doc = new Docxtemplater(zip, { modules: [new TableModule.Vertical()] });

To create a vertical loop table, you just have to use the {:vt#users} {:vt/users} tags, for example

Table {:vt#users}
Name {name}
Age {age}
Address {address}{:vt/users}

This will create a column for each user in the users array.

It will completely remove the column if users is false or empty.

Full Table


Your docx should contain the text: {:table table1}. You can find a working sample at ./sample.js


To have the vertical-loop-table, write :

const TableModule = require("docxtemplater-table-module");
const doc = new Docxtemplater(zip, { modules: [new TableModule.Full()] });

Units :

In all options, the following units are used :

  • Pixels (px), where 75pixels = 1inch = 2.54cm
  • Dxa (dxa), where 1440dxa = 1inch = 2.54cm

When creating the table, you have multiple options :

  • fixedColumns: Example : [null, "Example 1", null, "Example 2"], this option defines the columns that should take the whole height of the table
  • widths : [unit:px] Example : [100, 150, 320, 100], this option defines the width of each column
  • totalWidth : [unit:px or percentage] Example : This option cannot be used together with widths. if you use totalWidth, the width of each cell will be the totalWidth divided by the number of columns. For example, you can set totalWidth to 700 and have 2 columns of each width 350. It is also possible to set a width as a percentage with a string (for example : totalWidth: "80%". When using percentages, the current page layout will be taken into account, to have the table width depend on the page layout
  • header : Example ["Source", "Hazard", "Handling", "Protection"] : This option defines the header of the table (in bold)
  • subheader: Example ["The source", "The Hazard", "The Handling", "The Protection"] : This option defines the subheader of the table (in italic)
  • finalPageBreak: (true or false), default false. Whether to insert a finalPageBreak after the generated table/tables
  • indent : [unit:dxa] Example : 150, this option defines the indentation of the table, ie the indentation to be added before the leading edge of the table
  • border: Example : { type: "all", size: 5, color: "000000"} : This option defines the borders that are around each cell.
  • cellMargin : [unit:dxa] Example : {left: 250, top: 100, right: 250, bottom: 0} : This option defines the margins in each cell (it controls the <w:tblCellMar> tag)
  • chunkSize: Example : 6 : This option defines the number of lines after which to break the table into multiple tables

You can also have dynamic chunkSize, for example:

chunkSize: {
    type: "dynamic",
    size: { min: 7000, max: 8100},

This means that the height of the table will never exceed 8100 (the max). If the table exceeds the min, the next line will be in a new table. The unit is an internal word unit.

  • data : Example :

    data: [
        ["A1", "lorem"],
        ["B1", "lorem"],
        ["C1", "lorem"],

    This option defines the data of the table.

Global Options

It is possible to have global options for all tables created in the document, for example, to have all tables center-aligned :

const options = { align: "center" };
const doc = new Docxtemplater(zip, {
    modules: [new TableModule.Full(options)],

If options is an object, it will be merged with the default options.

It is also possible to pass a function here which gets the default options as an argument, and returns the used options.

For example, to remove the default spacingAfter of 200, you can write

const options = function (defaultOptions) {
    return {};
const doc = new Docxtemplater(zip, {
    modules: [new TableModule.Full(options)],

Grid Layout

It is possible to create a grid layout like this :

grid-template Grid template

Which will be rendered like this :

grid-template Grid template

In your code, do the following

const TableModule = require("docxtemplater-table-module");
const doc = new Docxtemplater(zip, { modules: [new TableModule.Grid()] });
    user: {
        size: [2, 4], // means 2 lines, 4 columns
        widths: [175, 175, 175, 175], // The widths of each column
        height: 200, // The height of each column
        data: [
                index: 1,
                name: "John",
                title: "Foobar",
                description: "3374 Olen Thomas Drive Frisco Texas 75034",
                index: 2,
                name: "Mary",
                title: "Foobaz",
                description: "352 Illinois Avenue Yamhill Oregon(OR) 97148",

PPTX Grid Layout - loop over multiple slides

If you also have access to the slides module version 3.2.0 or above, you can also have PPTX Grid Layout support.

You can generate multiple "slides" in a grid layout with following template :


companies is an array of objects representing each company.

It will generate output similar to this :


In your code, do the following

const TableModule = require("docxtemplater-table-module");
const doc = new Docxtemplater(zip, {
    modules: [new TableModule.GridPptx(), new SlidesModule()],

    companies: [
            name: "first company",
            id: "first id",
            logo: "2",
            region: "france",
            name: "second company",
            id: "second",
            region: "germany",
            name: "third",
            id: "third id",
            logo: "4",
            region: "russia",
            name: "fourth",
            id: "fourth id",
            region: "italy",

PPTX Grid Layout - loop on single slide

It is also possible to use the Grid Layout on some named data, for example :


will render :


with following data :

    "people": [
            "personName": "Mary foo",
            "awards": [
                    "name": "Swim 15km",
                    "image": "disc.png"
                    "name": "Jump 2m",
                    "image": "disc.png"
                    "name": "Drink 2L",
                    "image": "disc.png"

Merge cells

It is possible to merge adjacent cells that have the same value.

In your code, do :

const TableModule = require("docxtemplater-table-module");
const doc = new Docxtemplater(zip, { modules: [new TableModule.Merge()] });

The syntax for that is : {:merge-cells-col 1}, that should be placed inside a table, which means that in the first column, all adjacent cells that have the same content should be merged together.

For example :


will render :


When using the merge-cells-col tag, you specify on which columns you want the cells to be merged when they are identical. In this sample, it is just for column 1, but you could also write : {:merge-cells-col 1,2,4} to merge cells in column 1, 2 or 4



Bugfix, when using the FullTableModule, the resolver did not work (it catched all tags, thus having as consequence the fact that image tags for example where replaced with no data).


Bugfix, when using the FullTableModule with the HTMLmodule and the image module in async mode, the images would not be loaded correctly.

Now, images are shown even when using async mode together with the HTMLModule


Bugfix, when having empty data as in data: [["", ""]] for the Fulltable module together with the HTML module : html: true, the cells now have an empty paragraph.


Add support to have HTML as part of the data when using together with the HTML module. Note that when using this option, the automatic chunkSize will not infer the size of the table very accurately.

To enable this feature you need to use both the Table Module and the HTML module, and you should also add the html: true option to the table module.

const TableModule = require("docxtemplater-table-module");
const HtmlModule = require("docxtemplater-html-module");
const doc = new Docxtemplater(zip, {
    modules: [new HtmlModule(), new TableModule.Full({ html: true })],
    header: ["Header1", "Header2"],
    data: [
        ["<p><strong>Strong</strong> Text</p>", "Good"],
        ["<p><u>Underline</u> Text</p>", "Good"],
        ["<p><span style='color:#f00'>Red</u> Text</p>", "Good"],

When using this feature, all text that are inside the header, subheader or data parts will be rendered by converting HTML to docx.


Bugfix async support for TableModule.Merge when using together with subsection module


Add async support for TableModule.Merge (works with resolveData now)


Add new module to be able to merge adjacent cells together.

The syntax for that is : {:merge-cells-col 1}, that should be placed inside a table, which means that in the first column, all adjacent cells that have the same content should be merged together.


Bugfix Vertical Table Module in async mode (with resolveData).

Previously, an error would be thrown during render.


Do not render any element if data is empty


Add support for cellMargin.


Declare supportedFileTypes, which allows to use this module with the new docxtemplater constructor which was introduced in docxtemplater 3.17.


Update to work with latest docxtemplater, version 3.15.4


With vertical-table loop module, it is now possible to have nested horizontal loops + simple vertical loops


With vertical-table loop module, when you have row loops, you can also have a column that you hide/show based on a condition


In grid slide module for pptx, add possibility to loop over a given value.


Bugfix Cannot read property 'map' of undefined when having data: [] without any fixedColumns.


Bugfix for Cannot read property 'getAttribute' of undefined when having styles without names.


For Vertical Table module, the generated document was corrupt when having tables inside tables. This is no more the case


Do not add <w:spacing> tag if it is already present (fixes setting the spacing on the paragraph to change spacing of each paragraphs in the table).


Add support for finalPageBreak (default false), and stop inserting page breaks every time.

Add support for newlines (with \n) in data, header, subheader.


Add support for indent parameter to offset the table


Add support for table grid functionality when using this module together with the slides module.


Allow to have data: [] to show only a header.


Keep same font-size of text in {:table table1}


  • Update browser build to use XMLSerializer instead of xmldom

  • Use requiredAPIVersion


Add option border : { type: "all"} to force to have borders.

Fix bug totalWidth float


Add possibility to specify totalWidth, for example totalWidth: 700 or totalWidth: '100%'.

Add table grid module using : {:#grid user} and {:/grid}


  • Move docxtemplater from devDependencies to dependencies

Explanation : On some versions of npm (notably 5.8.0), when having a package containing docxtemplater-table-module, the installation will generate a tree of node_modules that puts the module on a level where it has no access to docxtemplater. By explicitly asking it as a dependency, this issue is avoided.


Make it possible to not have a subheader (header without subheader)


  • Make module compatible with docxtemplater version 3.5 and below.

Explanation : Recently, the scopemananger API (internal API) has changed, this new version of the footnotes module makes the module work with both versions newer than 3.6 and older than 3.6 of docxtemplater.


Add meta context argument to custom parser with information about the tag for each types of tags


For Full Table module, add possibility to add function in constructor to be able to customize the default spacingAfter property (eg for example, remove any default options).


For Full Table module, use style and properties of current paragraph for each cells in the paragraphs.


For Full Table module, Add possibility to :

  • set the alignment with the align option

  • set options global to each table in the constructor


For Full Table module, make all parameters except data optional.


Handle vertical tables that have different amount of columns. For example :

Table {:vt#users}
name (The name of the user) {name}
address (The address of the user) {address}{:vt/users}


Make generated docx not contain unnecessary commas


Add support for vertical table


  • Add table style only if needed


  • Fix other .forEach when last table is empty.
  • Fix height calculation, that doesn't take into account the height of the vertical cells


The headerSize is now calculated and taken into account when chunking.

Fix .forEach bug : If the dataset contains a cell that would not fit in the table because it is too high, the module will still put it in there since it cannot be splitted


Add support for dynamic chunkSize.

You can write :

const opts = {
    chunkSize: {
        type: "dynamic",
        size: { min: 7000, max: 8100 },


Initial release

Edgar Hipp

I'm the creator of docxtemplater. I work on making docxtemplater great since 2013.