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 :
To use this module, do your operations before the call to the render method.
const DocxtemplaterMetaModule = require("docxtemplater-meta-module");
const metaModule = new DocxtemplaterMetaModule();
const doc = new Docxtemplater(zip, {
modules: [metaModule],
});
metaModule.readonly();
doc.render(data);
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);
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/changedThere 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.
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);
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"/>
.
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);
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.
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".
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 :
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",
},
],
},
});
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();
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();
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)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();
It is possible to get the list of all loop tags in your document.
With following template :
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"
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)
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.
Bugfix typescript definitions to allow to run restrictEdition({password: "test123"})
.
The only mandatory parameter is password, the other have some default parameters.
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.
Make it possible to use prefix from the constructor
Add typescript typings to be able to change the module prefix
Bugfix issue with the "CommentModule".
The following error would occur sometimes :
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);
Add support to add multiple comments on one placeholder.
replaceAll
functionsearch
for the text <foo>
. All characters such as "
, >
, &
, >
could not be searched in the previous versionsreplace
on some empty search result.getLoopTags
function to retrieve all loop tags.Add following methods :
dropContentBeforePageBreak
getPageBreaks
dropContentBetween
Upgrade module to use NodeNext moduleResolution setting. See explanation here
Add support for : module.dropLastPageIfEmpty()
Set module.priority in order to have no more issues related to module ordering
Bugfix when used together with HTML module, when the document contains a comment + a {~~html} tag
The following error was thrown :
Now this error is fixed.
Upgrade to correctly pass in fileType, contentType, … to subRender and subResolve
Makes it compatible with docxtemplater 3.40.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.
Add support for metaModule.readonly()
method for pptx documents.
For some docx documents, calling metaModule.readonly()
would result in the following error :
This is now also fixed
Correctly render tags that are present in comments. (Needs docxtemplater@3.39.0)
Add new feature to change proofspelling language globally in the document using the : metaModule.setLang("en-US")
call.
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.
Bugfix to allow to template Hyperlinkbase when attaching the meta module (when not using setHyperlinkBase)
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.
Avoid possible issue of "Maximum call stack size exceeded"
Add possibility to restrict edition of generated document with : metaModule.restrictEdition({password: "user-entered-pass"})
.
Bugfix metaModule.readonly()
Bugfix "Cannot read properties of undefined (reading 'xml')", when using metaModule.readonly();
Bugfix to always template "title" values, and all other possible tags contained in docProps/core.xml
Use @xmldom/xmldom instead of xmldom, see this github issue
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.
Add typescript definitions for public API
Add support for setting hyperlink base using setHyperlinkBase(baseLink)
, see docs.
Add support for setting header/footer margins, see docs.
Declare supportedFileTypes, which allows to use this module with the new docxtemplater constructor which was introduced in docxtemplater 3.17.
Add API to change margins
Add API to add text watermark
Update browser build to use XMLSerializer instead of xmldom
Use requiredAPIVersion
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.
Initial release