This module makes it possible to locate errors in a Word or Powerpoint document.
For example, if you write the following template :
const path = require("path");
const fs = require("fs");
const Docxtemplater = require("docxtemplater");
const PizZip = require("pizzip");
const ErrorLocationModule = require("docxtemplater-error-location-module");
function generate() {
const content = fs.readFileSync(
path.resolve(__dirname, "input.docx"),
"binary"
);
const zip = new PizZip(content);
const errorModule = new ErrorLocationModule();
let doc;
try {
doc = new Docxtemplater(zip, {
modules: [errorModule],
});
} catch (e) {
doc = errorModule.getDoc();
// In this catch block, the template is syntactically invalid, for example when writing following template :
// `Hello {user, how are you ?`
// Since the tag user is unclosed the template can not be compiled
console.log("error during compilation");
console.log(e);
errorModule.addComments();
const buffer = doc.getZip().generate({
type: "nodebuffer",
compression: "DEFLATE",
});
fs.writeFileSync("generated-with-errors.docx", buffer);
return;
}
try {
doc.render();
} catch (e) {
// In this catch block, the template is syntactically valid, but the data cannot be applied to it.
// This is usually related to an implementation issue, you could either show this error to your users or log it for a developpers inspection
// If you use angular-expression filters, please make sure that your filters return the input if the type of the input is not the expected type :
// expressionParser.filters.upper = function(input) {
// // This condition should be used to make sure that if your input is undefined, your output will be undefined as well and will not throw an error
// if(!input) return input;
// return input.toUpperCase();
// }
console.log("error during render");
console.log(e);
errorModule.addComments();
const buffer = doc.getZip().generate({
type: "nodebuffer",
compression: "DEFLATE",
});
fs.writeFileSync("generated-with-errors.docx", buffer);
return;
}
const buffer = doc.getZip().generate({
type: "nodebuffer",
compression: "DEFLATE",
});
fs.writeFileSync("generated.docx", buffer);
}
generate();
<html>
<script src="node_modules/docxtemplater/build/docxtemplater.js"></script>
<script src="node_modules/pizzip/dist/pizzip.js"></script>
<script src="node_modules/pizzip/vendor/FileSaver.js"></script>
<script src="node_modules/pizzip/dist/pizzip-utils.js"></script>
<script src="build/error-location-module.js"></script>
<script>
PizZipUtils.getBinaryContent(
"examples/one-error.docx",
function (error, content) {
if (error) {
console.error(error);
return;
}
const errorModule =
new DocxtemplaterErrorLocationModule({});
const zip = new PizZip(content);
let doc;
try {
doc = new docxtemplater(zip, {
modules: [errorModule],
});
} catch (e) {
doc = errorModule.getDoc();
console.log("error during compilation");
console.log(e);
errorModule.addComments();
console.log("error", e);
const out = doc.getZip().generate({
type: "blob",
mimeType:
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
});
saveAs(out, "generated.docx");
return;
}
try {
doc.render({});
} catch (e) {
console.log("error during render");
console.log(e);
errorModule.addComments();
const out = doc.getZip().generate({
type: "blob",
mimeType:
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
});
saveAs(out, "generated.docx");
return;
}
const out = doc.getZip().generate({
type: "blob",
mimeType:
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
});
saveAs(out, "generated.docx");
}
);
</script>
</html>
After installing the module, you can use a working demo by running node sample.js
.
If you would like to change the author name and date of the comments, you can use the date
and author
options :
const ErrorLocationModule = require("docxtemplater-error-location-module");
const errorModule = new ErrorLocationModule({
author: "My author name",
date: new Date(),
});
let doc;
try {
doc = new Docxtemplater(zip, {
modules: [errorModule],
});
doc.render(data);
} catch (e) {
errorModule.addComments();
// doc = errorModule.getDoc()
// ...
}
date
takes a Date parameter as an input, and author
a string.
With the option : removeComments
set to true, all comments present in the template will first be removed before doing any error handling.
Use it like this :
const ErrorLocationModule = require("docxtemplater-error-location-module");
const errorModule = new ErrorLocationModule({
author: "My author name",
removeComments: true,
date: new Date(),
});
let doc;
try {
doc = new Docxtemplater(zip, {
modules: [errorModule],
});
doc.render(data);
} catch (e) {
errorModule.addComments();
// doc = errorModule.getDoc()
// ...
}
It is possible to translate the messages shown as comments in the document (if your end-users do not speak english), by providing a translation file.
An example with Dutch can be used with following code :
const ErrorLocationModule = require("docxtemplater-error-location-module");
const errorModule = new ErrorLocationModule({
translations: require("docxtemplater-error-location-module/translations/dutch.js"),
});
try {
doc = new Docxtemplater(zip, {
modules: [errorModule],
});
doc.render(data);
} catch (e) {
errorModule.addComments();
// doc = errorModule.getDoc()
// ...
}
Please contact me if you would like to have a translation for another language
It is possible to add custom validation of a template, for example, if you are using the following :
{#signatures}
{%sig}
{/}
You probably want to make sure that everytime the "signatures" block is used, the "{%sig}" tag which is the image tag is also included.
You can do this custom validation like this :
const ErrorLocationModule = require("docxtemplater-error-location-module");
const errorModule = new ErrorLocationModule();
const Errors = require("docxtemplater/js/errors.js");
const errorSignatureModule = {
name: "ErrorSignatureModule",
postparse(parsed, options) {
const basePart = options.basePart;
if (!basePart) {
return parsed;
}
if (
basePart.module !== "loop" ||
basePart.value !== "signatures"
) {
return parsed;
}
let foundImageTag = false;
parsed.forEach(function (part) {
if (
part.value === "sig" &&
part.module ===
"open-xml-templating/docxtemplater-image-module"
) {
foundImageTag = part;
}
});
if (!foundImageTag) {
const err = new Errors.XTTemplateError(
"Signature block needs to have a %sig tag"
);
err.properties = {
file: options.filePath,
offset: basePart.offset,
index: basePart.index,
explanation:
"Signature block needs to have a %sig tag",
};
return {
parsed,
errors: [err],
};
}
},
};
try {
doc = new Docxtemplater(zip, {
modules: [errorModule, errorSignatureModule],
});
} catch (e) {
// ...
}
Disallow to reuse a module instance for multiple generations.
Instead of :
const ErrorLocationModule = require("docxtemplater-error-location-module");
// BAD : same errorModule is reused by multiple Docxtemplater instances
const errorModule = new ErrorLocationModule();
function generate() {
let doc;
try {
doc = new Docxtemplater(zip, {
modules: [errorModule],
});
doc.render(/* data */);
} catch (e) {
errorModule.addComments();
}
}
generate();
You have to use :
const ErrorLocationModule = require("docxtemplater-error-location-module");
function generate() {
// instantiate a new ErrorLocationModule for each generation
const errorModule = new ErrorLocationModule();
let doc;
try {
doc = new Docxtemplater(zip, {
modules: [errorModule],
});
doc.render(/* data */);
} catch (e) {
errorModule.addComments();
}
}
generate();
When error occurs in docProps/app.xml, show : [In document properties]: Error XXX
When error occurs in an other file (other than document, header or footer), show : [In path/to/file.xml]: Error xxx
Bugfix when using chart module with error, it produced a corruption in previous versions
Fixes Github Issue #746
Upgrade module to use NodeNext moduleResolution setting. See explanation here
Bugfix for errors thrown by the "parser" for xlsx files.
This change also requires version 3.17.3 of the xlsx module.
If the parser returns an error (during compilation or during rendering), the error will now be correctly shown as a comment on xlsx files.
It is possible to customize the comment shown using the following code :
function parser() {
return {
get(scope, context) {
const err = new Error("Custom Error");
const part = context.meta.part;
err.properties = {
explanation:
`Custom error : tag '{${part.value}}' is not defined on` +
context.meta.part.square,
};
throw err;
},
};
}
const XlsxModule = require("docxtemplater-xlsx-module");
const ErrorLocationModule = require("docxtemplater-xlsx-module");
const xlsxModule = new XlsxModule();
const errorLocationModule = new ErrorLocationModule();
try {
const doc = new Docxtemplater(zip, {
parser,
paragraphLoop: true,
linebreaks: true,
modules: [xlsxModule, errorLocationModule],
});
doc.render();
} catch (e) {
errorLocationModule.addComments();
}
Bugfix for errors shown in XLSX file :
In previous versions, the comment was often not shown (only if one comment already existed in the file would the other comments also show).
Now the comments will show up correctly in both cases.
Add support for using the error location module on XLSX files (needs the xlsx module).
Bugfix current stacktrace when using error-location module on "docm" files (macro enabled files) :
Bugfix to set or get xml attributes correctly, even when using tabs instead of spaces in tags attributes
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 iand a {~~html}
tag
The following error was thrown :
Now this error is fixed.
Upgrade to correctly pass in fileType, contentType, … to subresolved
Makes it compatible with docxtemplater 3.40.1
Add module.clone() internal to make module work well with subsegment module
Correctly render tags that are present in comments. (Needs docxtemplater@3.39.0)
Add support for templating comments.xml content. (requires docxtemplater@3.38.0 or above).
Correctly add comments to other forms of textboxes
With the following type of textbox, it would not work :
<w:p>
<w:r>
<w:pict>
<v:shape id="_x0000_s1026" o:spid="_x0000_s1026" o:spt="202" type="#_x0000_t202" style="position:absolute;left:0pt;margin-left:24.05pt;margin-top:0.8pt;height:113.75pt;width:197.5pt;z-index:251659264;mso-width-relative:page;mso-height-relative:page;" fillcolor="#FFFFFF" filled="t" stroked="t" coordsize="21600,21600">
<v:path/>
<v:fill on="t" focussize="0,0"/>
<v:stroke color="#000000"/>
<v:imagedata o:title=""/>
<o:lock v:ext="edit" aspectratio="f"/>
<v:textbox>
<w:txbxContent>
<w:p>
<w:pPr>
<w:rPr>
<w:rFonts w:hint="default"/>
<w:lang w:val="en-US"/>
</w:rPr>
</w:pPr>
<w:r>
<w:rPr>
<w:rFonts w:hint="default"/>
<w:lang w:val="en-US"/>
</w:rPr>
<w:t>Other } error {here</w:t>
</w:r>
</w:p>
</w:txbxContent>
</v:textbox>
</v:shape>
</w:pict>
</w:r>
</w:p>
This now works well
When having an issue in a textbox, the module was not adding the comment.
This was due to the fact that comments cannot be added to a textbox in Word.
The module will now create an overlaying textbox with a red, transparent background and print the errors in that textbox.
Add xml:space="preserve" to all added comments
Add option "removeComments": true to be able to remove existing comments.
This way, if a user reuploads a fixed template without removing the comments, those will no more appear in the generated document.
Avoid possible issue of "Maximum call stack size exceeded"
Add "translations" to typescript definitions
Update typing definition to add "getDoc" function
Update to work with docxtemplater 3.28.5
Stop using hardcoded "Marquedecommentaire" and Mangal font :
<w:rStyle w:val="Marquedecommentaire"/>
<w:rFonts w:cs="Mangal"/>
Make module compatible with docxtemplater@3.27.0. Please make sure to update docxtemplater to 3.27.0 at the same time you update this module
Update to make module work well together with docxtemplater 3.26.3
Show header and footer errors by using a prefix in the comment :
For example, it will now show :
[In footer]:The tag beginning with "{bar" is unclosed
Add typescript typing for addComments()
method
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/error-location-module.js
The .min.js file is also created now.
Bugfix to make module work correctly with version 3.22.3 of docxtemplater core, especially when the input template contains the "&" character (ampersand symbol).
Add typescript definitions for public API
Add support for PPTX
With the exact same API, pptx documents can have their errors highlighted with comments.
Add support for office365 files
Declare supportedFileTypes, which allows to use this module with the new docxtemplater constructor which was introduced in docxtemplater 3.17.
xml:space="preserve"
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-error-location-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.
Add support for language translation (with Dutch for now)
Make error-location module work with comments even when the HTML module is attached
Commenter does not change file if there are no errors
Make it possible to overwrite author + date of the comments
Initial release