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

Usage

This module makes it possible to locate errors in a Word or Powerpoint document.

For example, if you write the following template :

Usage (nodejs)

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();

Usage (browser)

<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.

Options

Author

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 {
    errorModule.addComments();
    // doc = errorModule.getDoc()
    // ...
}

date takes a Date parameter as an input, and author a string.

Removing existing comments

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 {
    errorModule.addComments();
    // doc = errorModule.getDoc()
    // ...
}

Translation of messages

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 {
    errorModule.addComments();
    // doc = errorModule.getDoc()
    // ...
}

Please contact me if you would like to have a translation for another language

Custom validation of template

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 {
    // ...
}

CHANGELOG

3.9.6

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 {
        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 {
        errorModule.addComments();
    }
}

generate();

3.9.5

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

3.9.4

Bugfix when using chart module with error, it produced a corruption in previous versions

Fixes Github Issue #746

3.9.3

Upgrade module to use NodeNext moduleResolution setting. See explanation here

3.9.2

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 {
    errorLocationModule.addComments();
}

3.9.1

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.

3.9.0

Add support for using the error location module on XLSX files (needs the xlsx module).

3.8.6

Bugfix current stacktrace when using error-location module on "docm" files (macro enabled files) :

Cannot read properties of undefined (reading 'addCommentFromObject')
at ErrorLocationModule.transformRun

3.8.5

Bugfix to set or get xml attributes correctly, even when using tabs instead of spaces in tags attributes

3.8.4

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

3.8.3

Bugfix when used together with HTML module, when the document contains a comment iand 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.8.2

Upgrade to correctly pass in fileType, contentType, … to subresolved

Makes it compatible with docxtemplater 3.40.1

3.8.1

Add module.clone() internal to make module work well with subsegment module

3.8.0

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

3.7.0

Add support for templating comments.xml content. (requires docxtemplater@3.38.0 or above).

3.6.1

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

3.6.0

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.

Error in textbox
Error highlighted by a red textbox created by the error-location module

3.5.1

Add xml:space="preserve" to all added comments

3.5.0

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.

3.4.4

Avoid possible issue of "Maximum call stack size exceeded"

Add "translations" to typescript definitions

3.4.3

Update typing definition to add "getDoc" function

3.4.2

Update to work with docxtemplater 3.28.5

3.4.1

Stop using hardcoded "Marquedecommentaire" and Mangal font :

<w:rStyle w:val="Marquedecommentaire"/>
<w:rFonts w:cs="Mangal"/>

3.4.0

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

3.3.1

Update to make module work well together with docxtemplater 3.26.3

3.3.0

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

3.2.5

Add typescript typing for addComments() method

3.2.4

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

3.2.3

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.

3.2.2

Bugfix to make module work correctly with version 3.22.3 of docxtemplater core, especially when the input template contains the "&" character (ampersand symbol).

3.2.1

Add typescript definitions for public API

3.2.0

Add support for PPTX

With the exact same API, pptx documents can have their errors highlighted with comments.

3.1.6

Add support for office365 files

3.1.5

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

3.1.4

  • Bugfix when comment is first text in the document, remove extra xml:space="preserve"

3.1.3

  • Update browser build to use XMLSerializer instead of xmldom

  • Use requiredAPIVersion

3.1.2

  • Fix browser build "TypeError: Argument 1 of XMLSerializer.serializeToString does not implement interface Node."

3.1.1

  • Move docxtemplater from devDependencies to dependencies

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.

3.1.0

Add support for language translation (with Dutch for now)

3.0.3

Make error-location module work with comments even when the HTML module is attached

3.0.2

Commenter does not change file if there are no errors

3.0.1

Make it possible to overwrite author + date of the comments

3.0.0

Initial release

Talk with sales Contact us