You are currently offline, serving cached version
10 December 2024 : If you are using angular-expressions to parse expressions such as {user.name}, {#users.length > 10}, please upgrade asap to angular-expressions@1.4.3 for security reasons : View Github issue

Meta module

This module doesn't expose tags, but it makes it possible to do some operations on the docx itself.

After installing the module, you can use a working demo by running node sample.js.

The META module currently can :

Usage

To use this module, do your operations before the call to the render method.

Readonly

const DocxtemplaterMetaModule = require("docxtemplater-meta-module");
const metaModule = new DocxtemplaterMetaModule();
const doc = new Docxtemplater(zip, {
    modules: [metaModule],
});
metaModule.readonly();
doc.render(data);

Watermark

const DocxtemplaterMetaModule = require("docxtemplater-meta-module");
const metaModule = new DocxtemplaterMetaModule();
const doc = new Docxtemplater(zip, {
    modules: [metaModule],
});
metaModule.addTextWatermark("DRAFT", {
    diagonal: true,
});
doc.render(data);

Restrict Edition using a password

Word has a "restrict edition" mode that one can setup so that the document will be readonly unless you have a specific password.

The meta module can protect a document in this way.

Note that the content of the document will not be encrypted, the Microsoft Office software will simply respect the restriction and a malicious user could quite easily remove that protection.

Usage is like this :

const DocxtemplaterMetaModule = require("docxtemplater-meta-module");
const metaModule = new DocxtemplaterMetaModule();
const doc = new Docxtemplater(zip, {
    modules: [metaModule],
});
metaModule.restrictEdition({
    password: "my-complex-password", // This should be autogenerated
    // protect, default "readOnly",
    // algorithm, default: "sha512", // You most likely should not change this, this is the most secure algorithm that word does support
    // spinCount, default: 100000, // You most likely should not change this, a high spinCount will make the password much more difficult to guess
    // salt, base64 string (completely optional, it will be randomly generated when not provided)
});

doc.render(data);

The password length must be of at least 6 characters.

Note that spinCount and algorithm options already have default values which are secure enough for most use cases.

The protect option can take one of the following values :

  • "readOnly" => The document cannot be edited at all
  • "trackedChanges" => The document can be edited, all changes are tracked
  • "forms" => Only forms can be edited
  • "comments" => Only comments can be added/changed

There also is a salt parameter which is a base64string of 24 characters, but this value is generated by the library so you don't have to, in most cases.

Margins

It is possible to update the margins that are going to apply to all pages using following code :

const DocxtemplaterMetaModule = require("docxtemplater-meta-module");
const metaModule = new DocxtemplaterMetaModule();
const doc = new Docxtemplater(zip, {
    modules: [metaModule],
});
// Margins are in inches, and apply to all pages
metaModule.setMargins({
    top: 0.5,
    left: 0.8,
    right: 1.2,
    bottom: 1,
});
doc.render(data);

Bookmarks

With the meta module, you can retrieve the list of all bookmarks, get the content in XML form of a bookmark, and replace that XML using the methods documented below :

const DocxtemplaterMetaModule = require("docxtemplater-meta-module");
const metaModule = new DocxtemplaterMetaModule();
const doc = new Docxtemplater(zip, {
    modules: [metaModule],
});
const bookmarks = metaModule.getBookmarks();
bookmarks.forEach((bookmark) => {
    // You can log all your bookmark names using console.log(bookmark.name)
    if (bookmark.name === "FirstBm") {
        const initialXml = metaModule.getXml(bookmark);
        console.log("xml for the bookmark is : ", initialXml);
        // This will remove all your bookmarks with name "FirstBm"
        metaModule.replaceXml(bookmark, "");
    }
});
doc.render(data);

Note that the XML content inside a bookmark is not always valid XML, this is because the way bookmarks are stored in the docx file : A bookmarkstart element can be inside a <w:p><w:bookmarkStart w:id="1" name="myb"/> and the end element can be outside the paragraph : </w:p><w:bookmarkEnd w:id="1"/>.

Hyperlink Base

const DocxtemplaterMetaModule = require("docxtemplater-meta-module");
const metaModule = new DocxtemplaterMetaModule();
const doc = new Docxtemplater(zip, {
    modules: [metaModule],
});
const baseLink = "https://github.com/facebook/react";
metaModule.setHyperlinkBase(baseLink);
doc.render(data);

Search and replace some text

const DocxtemplaterMetaModule = require("docxtemplater-meta-module");
const metaModule = new DocxtemplaterMetaModule();
const doc = new Docxtemplater(zip, {
    modules: [metaModule],
});
const results = metaModule.search("Lorem"); // search also works with regex
if (results.length > 0) {
    metaModule.replace(results[0], "Tatum");
}
doc.render(data);

This will replace the first found "Lorem" by "Tatum".

It is also possible to replace all occurences by using the following :

const DocxtemplaterMetaModule = require("docxtemplater-meta-module");
const metaModule = new DocxtemplaterMetaModule();
const doc = new Docxtemplater(zip, {
    modules: [metaModule],
});
metaModule.replaceAll(/Search/, "Replace Value");
doc.render(data);

If the search is not found, it will simply continue the program execution.

Add a comment from a search

const DocxtemplaterMetaModule = require("docxtemplater-meta-module");
const metaModule = new DocxtemplaterMetaModule();
const doc = new Docxtemplater(zip, {
    modules: [metaModule],
});
const results = metaModule.search("Lorem");
if (results.length > 0) {
    metaModule.addComment(results[0], "This is a latin word", {
        author: "John Doe",
        initials: "JD",
        date: new Date(),
    });
}
doc.render(data);

This will search for the first "Lorem" and add a comment around it containing "This is a latin word".

Add a comment from a tag

Since version 3.4.0 of the meta module, it is possible to add a comment from a tag using the following code :

In your template :

Hello {user}
const CommentModule = require("docxtemplater-meta-module/comment-module.js");
const doc = new Docxtemplater(zip, {
    modules: [
        new CommentModule({
            author: "John the pirate",
            date: new Date().toISOString(),
        }),
    ],
});
doc.render({
    user: {
        text: "John",
        comment: "Updated 2022\nSome comment",
        // author: "Jane the pirate",
    },
});

It is possible to add multiple comments by using the following code :

doc.render({
    user: {
        text: "John",
        comments: [
            {
                comment: "Foobar",
                date: new Date(2018, 1, 1),
            },
            {
                comment: "Other comment",
            },
        ],
    },
});

Remove content from start of document until nth page break

It is possible to remove the full content of a document from the start of the document until the nth page break using following code :

const DocxtemplaterMetaModule = require("docxtemplater-meta-module");
const metaModule = new DocxtemplaterMetaModule();
const doc = new Docxtemplater(zip, {
    module: [metaModule],
});
const breaks = metaModule.getPageBreaks();
metaModule.dropContentBetween(
    metaModule.startOfDocument,
    breaks[0]
); // This will remove the first page of the document.
doc.render();

Remove content from nth page break until end of document

It is possible to remove the full content of a document from nth page break until the end of the document using following code :

const DocxtemplaterMetaModule = require("docxtemplater-meta-module");
const metaModule = new DocxtemplaterMetaModule();
const doc = new Docxtemplater(zip, {
    module: [metaModule],
});
const breaks = metaModule.getPageBreaks();
metaModule.dropContentBetween(
    breaks[2],
    metaModule.endOfDocument
); // This will remove the content after the 3rd page break
doc.render();

Change document language

It is possible to change the language that is used for spell checking globally in your document.

const DocxtemplaterMetaModule = require("docxtemplater-meta-module");
const metaModule = new DocxtemplaterMetaModule();
const doc = new Docxtemplater(zip, {
    modules: [metaModule],
});
metaModule.setLang("en-US");
doc.render(data);

The language parameter given to the setLang function must be a BCP 47 code.

See following links describing BCP 47 code : Tech on the net, Microsoft Documentation

Following languages can be used (list non-exhaustive)

  • fr-FR : French (France)
  • en-US : English (US)
  • ru-RU : Russian (Russia)
  • zh-CN : Chinese (Mainland China)
  • ja-JP : Japanese (Japan)
  • ar-SA : Arabic (Saudi Arabia)
  • hi-IN : Hindi (India)
  • de-DE : German (Germany)
  • he-IL : Hebrew (Israel)
  • nl-NL : Dutch (Netherlands)
  • es-ES : Spanish (Spain)
  • ca-ES : Catalan (Spain)

Remove the last page of a document if it is empty

For docx documents, you can remove the last page of a document if it is empty (because of a pagebreak).

You have to call the function dropLastPageIfEmpty() just after your call to doc.render(data) or doc.renderAsync(data), like this :

const DocxtemplaterMetaModule = require("docxtemplater-meta-module");
const metaModule = new DocxtemplaterMetaModule();
const doc = new Docxtemplater(zip, {
    modules: [metaModule],
});
doc.render(data);
metaModule.dropLastPageIfEmpty();

List loop tags

It is possible to get the list of all loop tags in your document.

With following template :

{#ref1}Some text{/}
{#ref2}Some text{/}

And following code :

const DocxtemplaterMetaModule = require("docxtemplater-meta-module");
const metaModule = new DocxtemplaterMetaModule();
const doc = new Docxtemplater(zip, {
    modules: [metaModule],
});
doc.render(data);
const loopTags = metaModule.getLoopTags();

console.log(loopTags[0].value); // "ref1"
console.log(loopTags[1].value); // "ref2"

CHANGELOG

3.13.0

Add support for bookmarks, by adding following methods on an instance of metaModule

  • getBookmarks() => returns positions, an array of each positition for each bookmark.
  • replaceXml(position, xml)
  • getXml(position)

3.12.0

Bugfix when using together with subtemplate module, the following would not work correctly :

(This also needs the subtemplate module version 3.19.0 or higher).

const DocxtemplaterMetaModule = require("docxtemplater-meta-module");
const SubtemplateModule = require("docxtemplater-subtemplate-module");
const metaModule = new DocxtemplaterMetaModule();
const doc = new Docxtemplater(zip, {
    modules: [metaModule, new SubtemplateModule()],
});
metaModule.restrictEdition({
    password: "test123",
    salt: "mHQ9f0jyV8snSWoFHQwZigBo",
});
doc.render(/* data */);

This now works correctly with the subtemplate module.

It also needs the latest version of docxtemplater, 3.51.0.

3.11.6

Bugfix typescript definitions to allow to run restrictEdition({password: "test123"}).

The only mandatory parameter is password, the other have some default parameters.

3.11.5

Bugfix to addComment(results[0], "Some text")

Previously, the comment that would be added would always be "comment", and would not take the argument from the second parameter of the addComment function. It is fixed now.

3.11.4

Make it possible to use prefix from the constructor

3.11.3

Add typescript typings to be able to change the module prefix

3.11.2

Bugfix issue with the "CommentModule".

The following error would occur sometimes :

Unimplemented tag type "placeholder" "open-xml-templating/docxtemplater-comment-module"

Also, the following should work correctly now :

const CommentModule = require("docxtemplater-meta-module/comment-module.js");
const doc = new Docxtemplater(zip, {
    modules: [new CommentModule()],
});
doc.render(data);

3.11.1

Add support to add multiple comments on one placeholder.

3.11.0

  • Add replaceAll function
  • Bugfix to able to search for the text <foo>. All characters such as ", >, &, > could not be searched in the previous versions
  • Throw specific error if calling replace on some empty search result.

3.10.0

  • Add getLoopTags function to retrieve all loop tags.
  • Add typescript typings to all meta module methods

3.9.0

Add following methods :

  • dropContentBeforePageBreak
  • getPageBreaks
  • dropContentBetween

3.8.1

Upgrade module to use NodeNext moduleResolution setting. See explanation here

3.8.0

Add support for : module.dropLastPageIfEmpty()

3.7.4

Set module.priority in order to have no more issues related to module ordering

3.7.3

Bugfix when used together with HTML module, when the document contains a comment + a {~~html} tag

The following error was thrown :

TypeError: Cannot read properties of undefined (reading 'parts')
at HtmlModule.render (xtm/modules/html/js/index.js)

Now this error is fixed.

3.7.2

Upgrade to correctly pass in fileType, contentType, … to subRender and subResolve

Makes it compatible with docxtemplater 3.40.1

3.7.1

Fix a corruption when a pptx document is used and the setLang API is called.

This would many times result in a corrupt pptx document.

3.7.0

Add support for metaModule.readonly() method for pptx documents.

For some docx documents, calling metaModule.readonly() would result in the following error :

Cannot read properties of undefined (reading 'xml')
at canonicalizeState (js/sxml.js)
at findChilds (js/sxml.js)
at firstChild (js/sxml.js)
at makeReadOnly (js/read-only.js)
at MetaModule.readonly (js/index.js)

This is now also fixed

3.6.0

Correctly render tags that are present in comments. (Needs docxtemplater@3.39.0)

3.5.0

Add new feature to change proofspelling language globally in the document using the : metaModule.setLang("en-US") call.

3.4.2

Bugfix corruption when using comment module, if the tag was {user}, and the data was :

{
    "user": "John && Mary"
}

Then the output document would become corrupt.

With this version, the problem is fixed.

3.4.1

Bugfix to allow to template Hyperlinkbase when attaching the meta module (when not using setHyperlinkBase)

3.4.0

Add possibility to do search/replace or search/addComment

Add possibility to add some text together with a comment using the CommentModule, see this documentation.

3.3.1

Avoid possible issue of "Maximum call stack size exceeded"

3.3.0

Add possibility to restrict edition of generated document with : metaModule.restrictEdition({password: "user-entered-pass"}).

3.2.9

Bugfix metaModule.readonly()

3.2.8

Bugfix "Cannot read properties of undefined (reading 'xml')", when using metaModule.readonly();

3.2.7

Bugfix to always template "title" values, and all other possible tags contained in docProps/core.xml

3.2.6

Use @xmldom/xmldom instead of xmldom, see this github issue

3.2.5

Generate files in built with correct filename In previous versions, the filename was always build/docxtemplater.js. Now the filename is build/meta-module.js The .min.js file is also created now.

3.2.4

Add typescript definitions for public API

3.2.3

Add support for setting hyperlink base using setHyperlinkBase(baseLink), see docs.

3.2.2

Add support for setting header/footer margins, see docs.

3.2.1

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

3.2.0

Add API to change margins

3.1.0

Add API to add text watermark

3.0.2

  • Update browser build to use XMLSerializer instead of xmldom

  • Use requiredAPIVersion

3.0.1

  • Move docxtemplater from devDependencies to dependencies

Explanation : On some versions of npm (notably 5.8.0), when having a package containing docxtemplater-meta-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.

3.0.0

Initial release

Talk with sales Contact us