UNPKG

docxtemplater

Version:

Generate docx, pptx, and xlsx from templates (Word, Powerpoint and Excel documents), from Node.js, the Browser and the command line

1,927 lines (1,285 loc) 85.1 kB
## 3.63.0 **Important** If you use one of these modules, please make sure to update to the latest version : - [table] v3.26.4 - [qrcode] v3.5.2 - [pptx-sub] v3.1.12 - [image] v3.31.5 - [html] v3.56.8 Change the way `xmltemplater.parse` and `xmltemplater.postparse` are called. Previously, we did : ``` for (file of files) { preparse(file) } for (file of files) { parse(file) postparse(file) } ``` Now we do : ``` for (file of files) { preparse(file) } for (file of files) { parse(file) } for (file of files) { postparse(file) } ``` Add events for `before-preparse`, `after-preparse`, `after-parse`, `after-postparse` which run like this : - `before-preparse` : before doing all preparse calls - `after-preparse` : after doing all preparse calls (after the for loop) - `after-parse` : after doing all parse calls (after the for loop) - `after-postparse` : after doing all postparse calls (after the for loop) Update moduleApiVersion to 3.46.0. When a document had a header that contained a table, if the table rows were specified in the "percent" unit, the following stacktrace would be shown : ``` Cannot read properties of undefined (reading 'width') at collectCellsDimensions (get-dimensions.js) at Object.collect (get-dimensions.js) at HtmlModule.preparse (index.js) at preparse (parser.js) ``` This is fixed with the following versions : `docxtemplater-html-module@v3.56.8`, `docxtemplater-table-module@v3.26.4`, `docxtemplater-image-module@v3.31.5` The qrcode and pptx-subtemplate module incorrectly relied on the order of "parse/postparse". With older versions, the output will get quite messed up You have to update to these versions to make it work : - [qrcode] v3.5.2 - [pptx-sub] v3.1.12 ## 3.62.2 Bugfix a regression of 3.61.2 when your data contains invalid xml characters. Since version 3.61.2, in some cases, if two tags contained invalid xml characters, in the Multi Error, only one would be shown. Now, all invalid xml characters of all tags are shown in the error (this was also the case in versions <= 3.61.1) ## 3.62.1 Add correct typescript types for new export functions added in 3.62.0 ## 3.62.0 Also requires an update to pizzip to at least pizzip@3.2.0 Add multiple export functions : `toBuffer`, `toBlob`, `toBase64`, `toUint8Array`, `toArrayBuffer` Instead of : ```js const doc = new Docxtemplater(zip, { paragraphLoop: true, linebreaks: true, }); doc.render(/* data */); const buf = doc.getZip().generate({ type: "nodebuffer", /* * Compression: DEFLATE adds a compression step. * For a 50MB document, expect 500ms additional CPU time. */ compression: "DEFLATE", }); ``` You can now write : ```js const doc = new Docxtemplater(zip, { paragraphLoop: true, linebreaks: true, }); doc.render(/* data */); const buf = doc.toBuffer(); ``` It automatically uses `"compression": "DEFLATE"` (which makes the docx file output smaller but takes a bit of CPU time for the zipping algorithm), and correctly writes the files in the correct order so that the mime type detection for unix systems recognizes the files as the correct mimetypes. ## 3.61.2 Correctly remove all corrupt characters when using the `stripInvalidXMLChars` option. Previously only the first occurence was removed. ## 3.61.1 Update moduleApiVersion to 3.45.0 (for being able to use `require("docxtemplater/js/get-tags.js");`). Please update xlsx module to 3.29.1 at least. Please update slides module to 3.7.1 at least. ## 3.61.0 Add `doc.getTags()` to get tags per document/header/footer. It works for docx files only For xlsx files, you need the paid version and use the `xlsxModule.getSheets()`. For pptx files, you need the paid version and use the `slidesModule.getSlides()`. ## 3.60.2 Throw specific error when trying to render a xlsx template to tell you that you have to use the [paid xlsx module](https://docxtemplater.com/modules/xlsx/) for that. ## 3.60.1 Add typescript typings for `expressionParser.configure({setIdentifier: (tag, value, scope, scopeList, context) => true})`. ## 3.60.0 Make it possible to disable parsing of "{" and "}" completely by setting the delimiters.start and delimiters.end to null. ```js const doc = new Docxtemplater(zip, { delimiters: { start: null, end: null, }, }); ``` Fixed #777 ## 3.59.0 Update internal preparse API in order to be able to return a new preparsed value (useful for the new ErrorLocationModule version 3.9.7). Provides moduleApiVersion 3.44.0 (please update the ErrorLocationModule if you use it). ### 3.58.4 Make it possible to write unbalanced loops, if specifying the following the option : ```js const expressionParser = require("docxtemplater/expressions.js"); const doc = new Docxtemplater(zip, { paragraphLoop: true, linebreaks: true, syntax: { allowUnbalancedLoops: true, }, }); doc.render(/* data */); ``` Then the following template in a table will work ```docx ------------------------- | {#a} | {/a}{#b}{/b} | ------------------------- ``` This template will normally throw an "unbalanced_loop_tags" exception. The correct fix is to move the {#b} to be inside the {#a} loop like this : ```docx ------------------------- | {#a} | {#b}{/b}{/a} | ------------------------- ``` However, if you have some templates that were used before v3.19.9 of docxtemplater, and can't change the templates, you can use the `allowUnbalancedLoops` option. ### 3.58.3 Do not throw an error if sending xml invalid character such as "\u0002" when using TxtTemplater. ### 3.58.2 Bugfix Inspectmodule so that it shows image tags inside xlsx files. Previously, those tags would not appear in the `getTags` result. ### 3.58.1 Add `renderAsync` typescript typing to TxtTemplater. ### 3.58.0 Add `renderAsync` method to TxtTemplater, usage is like this : ```js const TxtTemplater = require("docxtemplater/js/text.js"); const doc = new TxtTemplater("Hello {user}, how are you ?"); const result = doc.renderAsync({ user: new Promise((resolve) => { resolve("John"); }), }); ``` ### 3.57.3 When using the `stripInvalidXMLChars:true` option, if passing a value of a non string, such as : ```js doc.render({ first_name: 44, }); ``` The following stacktrace would be shown : ```log string.replace is not a function at removeCorruptCharacters (es6/doc-utils.js:385:16)" at Render.render (es6/modules/render.js:101:12)" at moduleRender (es6/render.js:10:33)" ``` Now, the rendering works correctly. ### 3.57.2 Add context parameter to expressionParser : ``` postEvaluate?: ( result: any, tag: string, scope: any, context: DXT.ParserContext ) => any; // context.meta.part will be equal to "name" ``` ### 3.57.1 - Add `postEvaluate` API to expressionParser. - Refactor `expandToOne` trait ### 3.57.0 Add traits.expandToOne.onError for module API to be able to catch or ignore expansion errors. Provides moduleApiVersion 3.43.0 (please update the HTML module if you use it). For TxtTemplater, throw XtRenderingError on rendering Error (if the data resolver throws an error), previously a useless stacktrace would be thrown. ### 3.56.0 When the data contains control characters, such as "U+0002" (Start of Text) or other control characters, the document would fail to generate. Docxtemplater now has an option called `stripInvalidXMLChars` which will strip the bad control characters automatically. Use it like this : ```js const doc = new Docxtemplater(zip, { stripInvalidXMLChars: true, paragraphLoop: true, linebreaks: true, }); ``` ### 3.55.9 Fix small issues with expressions.js - Add `compiled` property to be able to access the internal expression : If the tag is simply : `{myVal}` In your code, you can use : ```js const expressionParser = require("docxtemplater/expressions.js"); const doc = new Docxtemplater(zip, { parser: (tag) => { const result = expressionParser(tag); const firstExpression = result.compiled.ast.body[0].expression; expect(firstExpression.type).to.equal("Identifier"); expect(firstExpression.name).to.equal("myVal"); expect(firstExpression.constant).to.equal(false); return result; }, }); ``` - Use better error message if using non string value for expressions.js - Do not fail if trying to access property of null inside a loop with expressions.js ### 3.55.8 Update to fix inspectModule.getAllTags() for all less used modules (qrcode, expand-loop for xlsx). Use hasOwnProperty.call() for better compatibility. ### 3.55.7 Bugfix to fix inspectModule.getAllTags() when using image module ({%image} tag inside alt text) or table merge cell module. In case when you were using the features of the module, the getAllTags would fail with a stacktrace. ### 3.55.6 When using a loop inside a table, if there is a bookmark right after the table, a new empty paragraph would be added. Now an empty paragraph will not be added in this specific case (an empty paragraph is added between two tables for example, this is mandatory to generate a valid docx document). ### 3.55.5 Angular-expressions had a vulnerability (CVE-2024-54152), and was patched at the same time of the release of docxtemplater@3.55.5. The new version is angular-expressions@1.4.3. All users of docxtemplater that use `angular-expressions` should upgrade to `angular-expressions@1.4.3` as soon as possible.. With version angular-expressions@1.4.3 and version<=3.55.4 of docxtemplater, the following template using `this` with a computation would not return the correct value ``` // If the scope is `2` {this + this} // ✕ Will return undefined with angular-expressions@1.4.3 and docxtemplater@3.55.4 {this + this} // ✓ Will return 4 with angular-expressions@1.4.3 and docxtemplater@3.55.5 // Behavior with older angular-expressions {this + this} // ✓ Will return 4 with angular-expressions@1.4.2 and docxtemplater@3.55.5 {this + this} // ✓ Will return 4 with angular-expressions@1.4.2 and docxtemplater@3.55.4 ``` Similarly, the following templates would also produce a non correct value : ``` {this|square} {. + .} ``` Most expressions (Probably 99.5%) are not affected and continued to work without an upgrade in docxtemplater, such as {users | filter}, {age > 18}, {company.address}, ... With version 3.55.5, the correct behavior is restored for the 0.5% cases using this with computations. ### 3.55.4 Improve handling of XLSX files for the inspectModule.getTags() function. It now works correctly with innerloops, like this : ```xlsx {#l1} | {#l2} {name} | {otherName} | {/}{/} ``` Previously, the "otherName" key would appear as a direct child of l1 (instead of inside l2). ### 3.55.3 Hotfix, 3.55.2 was published and did not contain the full fix, 3.55.3 now really fixes the issue with the XlsxModule and odt files. ### 3.55.2 Bugfix issue introduced in 3.55.1 when using the XlsxModule and trying to load an odt file, an unexpected error was thrown instead of an error explaining that odt files are not supported. ### 3.55.1 Add internal xmlContentTypes API for setting xmlFileNames easily from modules. Update moduleApiVersion to 3.42.0 ### 3.55.0 - Performance improvements : docxtemplater now uses for of loops instead of forEach to avoid creating many anonymous functions. - Options immutability : in previous versions, when changing the delimiters.start from the optionsTransformer for one instance, it would change the options for all future doc instances. If for some reason, you were changing the DocUtils.defaults, like this, this is no longer possible : (This was not documented anywhere so it is very unlikely that you're doing this). ```js require("docxtemplater").DocUtils.defaults.paragraphLoop = true; ``` This code will not have any effect starting from 3.55.0, you have to pass the options in the constructor. - Refactor InspectModule.getAllTags() to work correctly on xlsx files to properly show nesting of data. ### 3.54.1 Bugfix so that "errorChecker" is called when resolveTags fails (and not later in render). This fixes a bug when using the xlsx + error location module in async mode, so that errors are correctly shown. ### 3.54.0 Add console.warn messages when using deprecated methods : compile, attachModule, setData, resolveData, loadZip [Read more about the migration here](https://docxtemplater.com/docs/api/#upgrade-guide) ### 3.53.0 Add support for replacing placeholders such as `{name}` in Smart art shapes. ### 3.52.0 Add `syntax.allowUnclosedTag` option. This allows to write : `Hello {user` and not have an error in your template. ### 3.51.2 Improve typescript typings : - Add position and tag to `DXT.Part` - Add void return value to `getFileType?(opts: any): string | void;` - Add `targets` to Docxtemplater instance ### 3.51.1 Update to be able to write `{#loop}{. | filter}{/}` so that the variable passed to filter is not of type Proxy. Previously, the variable passed to the filter would be of type Proxy. This requires `angular-expressions@1.4.0` ### 3.51.0 Add support for `module.preZip` function, which is useful for the subtemplate and the meta module. After upgrading to 3.51.0, if you use any of the paid modules, please also run the upgrade for all your modules with this command : ```sh npm install docxtemplater && npx -y update-docxtemplater && npm install ``` Update moduleApiVersion to 3.41.0. ### 3.50.0 In the continuity of the "evaluateIdentifier" feature added in 3.49.0, we added the `setIdentifier` option for the expressions.js file : This is useful if you want to do assignments in your template, like this : ```docx {$$globalVar = 3} ``` You can then write : ```js const expressionParser = require("docxtemplater/expressions.js"); const globalData = {}; const doc = new Docxtemplater(zip, { parser: expressionParser.configure({ setIdentifier(tag, value) { const matchGlobal = /^\$\$/g; if (matchGlobal.test(tag)) { globalData[tag] = value; return true; } }, evaluateIdentifier(tag) { const matchGlobal = /^\$\$/g; if (matchGlobal.test(tag)) { return globalData[tag]; } }, }), }); doc.render(/* data */); ``` In this case, all of your assignments to variable that start with "$$" will be assigned to the "globalData" object. Also tags that contain one assignment and then a statement will now return the statement. So for example, you can write : Hello { $$admin=user; $$admin } In this case, it will render "Hello John" (if the data is `{user: "John"}`) ### 3.49.2 Bugfix corruption that could appear when using the vertical loop module. Previously, the vertical loop module could sometimes produce empty tables that would not be cleaned. For example, with following template : ```docx -------------- | {:vt#loop} | -------------- | XXX | | {:vt/} | -------------- ``` If the loop was an empty array, the output would produce a corrupt document. The table is now correctly removed in this case. The table will ### 3.49.1 Add `doc.keepStyles` and `doc.includeSections` to Typescript definition. ### 3.49.0 Add possibility, when using the angular parser, to use "magic" keys to return some specific values. (This feature cannot be implemented if you use the `"docxtemplater/expressions-ie11.js"` package). In your template, if you write : ```docx {#loop} {__val} {/} ``` This will retrieve the "val" value from the scope that is above the current scope (it retrieves the value of "val" in the scope outside of the loop). ```js const expressionParser = require("docxtemplater/expressions.js"); const doc = new Docxtemplater(zip, { parser: expressionParser.configure({ evaluateIdentifier(tag, scope, scopeList, context) { const matchesParent = /^(_{2,})(.*)/g; if (matchesParent.test(tag)) { const parentCount = tag.replace(matchesParent, "$1").length - 1; tag = tag.replace(matchesParent, "$2"); if (parentCount >= 1) { for (let i = scopeList.length - 1 - parentCount; i >= 0; i--) { const s = scopeList[i]; if (s[tag] != null) { const property = s[tag]; return typeof property === "function" ? property.bind(s) : property; } } } } }, }), }); doc.render({ loop: [ { val: "This value", }, ], val: "Other value", // <= This value will be retrieved }); ``` ### 3.48.0 Allow to configure the behavior of the "change delimiter syntax". As documented here : https://docxtemplater.com/docs/tag-types/#set-delimiter You can for example use : ``` {=[[ ]]=} [[name]] ``` It is possible to change the special behavior that will catch tags that start with a "=". It is either possible to set the `syntax.changeDelimiterPrefix` to null so that it won't be possible to change the delimiters inside the template, or you can change the char that is used. For example : ```js const doc = new Docxtemplater(zip, { syntax: { changeDelimiterPrefix: null, }, }); ``` or ```js const doc = new Docxtemplater(zip, { syntax: { changeDelimiterPrefix: "$", }, }); ``` ### 3.47.4 Add correct typescript typings for `isIdentifierStart` and `isIdentifierContinue`. ### 3.47.3 Improve getStructuredTags and getTags of the inspectModule to allow to get tags present in image attributes. (This is to work together with the image-module 3.28.0) ### 3.47.2 Bugfix internal api mechanism : It internally allows to have multiple traits.expandToOne(). Fixes bugs with the subtemplate and subsection module. Update moduleApiVersion to 3.40.0. ### 3.47.1 If zip file is not a docx file, show the following error message now : `The filetype for this file could not be identified, is this file corrupted ? Zip file contains : world.txt,xxx.log` In previous versions, the following message was shown : `The filetype for this file could not be identified, is this file corrupted ?` ### 3.47.0 Make it possible to dynamically allow to use a given tag for a module. For example, you can write : ```js const doc = new Docxtemplater(zip, { modules: [ { optionsTransformer(options, doc) { for (module of doc.modules) { if (module.name === "RawXmlModule") { module.prefix = function (placeholderContent) { if (placeholderContent === "raw") { return "raw"; } if (placeholderContent[0] === "@") { return placeholderContent.substr(1); } }; } } return options; }, }, ], }); ``` This code means that if you write : {raw} in your document (without the "@" prefix), that tag will be used as a rawxml tag. ### 3.46.2 Add "synced-zip" event that is run right after the zip is prepared. Update moduleApiVersion to version 3.39.0, which is used by the latest subtemplate module. ### 3.46.1 Fix typescript issue with TxtTemplater ### 3.46.0 When using a loop inside a powerpoint table, if the result is an empty table, correctly drop the table from the presentation. ### 3.45.1 Add getObjectIdentifiers to expressionParser, which can be used like this : ```js const expressionParser = require("docxtemplater/expressions.js"); expressionParser("a.b.c").getObjectIdentifiers(); // returns { a: { b: { c: {} } } } ``` ### 3.45.0 Bugfix for proofstate module : Following error was thrown when using this module : `Unnamed module` Now the module should work correctly ### 3.44.0 Make it possible to configure the angular parser for just one docxtemplater instance. (This needs angular-expressions version 1.2.0) Use following code : ```js const expressionParser = require("docxtemplater/expressions.js"); new Docxtemplater(zip, { parser: expressionParser.configure({ csp: true, // this disables the use of "new Function", useful for Vercel, Deno, ... filters: { uppercase: (input) => { if (typeof input === "string") { return input.toUpperCase(); } return input; }, }, }), }); ``` ### 3.43.1 Improve Typescript support to use the NodeNext moduleResolution setting. See [the explanation here](https://github.com/arethetypeswrong/arethetypeswrong.github.io/blob/main/docs/problems/MissingExportEquals.md). Fixed in [this pull request](https://github.com/open-xml-templating/docxtemplater/pull/742) thanks to @benasher44. ### 3.43.0 Add getResolvedId calculation in docxtemplater to all template parts so that all modules can store a value for each templated part. This value is guaranteed to be the same for a given {placeholder} and data attribute between `resolve` and `render`. ### 3.42.7 Throw specific error if two modules with the same name are attached. Bugfix issue on TxtTemplater when using `{paragraphLoop: true}`. ### 3.42.6 Bugfix of internal API change, which was published in v3.42.5 ### 3.42.5 Bugfix for TxtTemplating : ```js const TxtTemplater = require("docxtemplater/text.js"); ``` The following template : ``` <p>Foobar</p> ``` Would be rendered as : ``` <p&gt;Foobar</p&gt; ``` Also, errors such as unclosed loops, like in : ``` {#users}Foo ``` would produce an internal stacktrace. Now, a MultiError is thrown which contains the list of all errors inside `error.properties.errors` ### 3.42.4 Avoid issue `Cannot read properties of undefined (reading 'length')` when using `renderAsync`. Now, the correct error message should be shown. ### 3.42.3 Bugfix to avoid following error when runnig `iModule.getStructuredTags()` : ``` TypeError: Cannot read properties of undefined (reading 'replace') ``` Now, the tags are correctly returned. ### 3.42.2 Bugfix to add clone method to the assertion module and to the inspect module ### 3.42.1 Bugfix for inspect module when used together with qrcode/xlsx or table module, in some specific cases, the getTags function would return values correctly, but also return a key named "undefined", like this : ```js const tags = iModule.getAllTags(); console.log(tags); // would return : { name: {}, undefined: {}} ``` In order to apply the fix, you have to update the following modules (if you use them) : - qrcode module to 3.4.7 - table module to 3.19.9 - xlsx module to 3.14.2 ### 3.42.0 [Internal] Add filePath to each "inspect" call, which fixes a bug with the chart module when used together with the "getTags" feature of the inspect module. If you update to this version, it is important that you also upgrade following modules if you use them : - slides module to version 3.5.3 - pptx-sub module to version 3.1.4 ### 3.41.0 Correctly show error in a multi error if the scope parser execution fails inside the render function Previously, following error was thrown : ```error Error: Scope parser execution failed at new XTScopeParserError (....) ``` with following template : ```txt {#users | sortBy:'foo'} Foo {/} ``` ``` expressionParser.filters.sortBy = function (input, ...fields) { if (!input) return input; return sortBy(input, fields); }; ``` (when sortBy is not imported correctly). Now, the error will show a multierror with the list of errors that are happening + the tags that are causing the error. Add support for angularExpressions.compile(), angularExpressions.Parser, and expressionParser.Lexer ### 3.40.3 Fix issue when having {tag} inside title in pptx (or docx) and using the linebreak option. ### 3.40.2 Bugfix to not add "w:sdt" inside "w:sdtContent". Fixes a corruption on a particular type of document. ### 3.40.1 Bugfix when using docxtemplater asynchronously, and having some module inside a loop. The "contentType" and some other properties were not transfered correctly to the elements inside the loop. This specifically caused an issue in the HTML module to return the correct pageHeight inside the `getSize` and `getImage` function. This could also lead to some other bugs that were happening only when having some specific tag present in the loop. ### 3.40.0 - In previous versions the following code will throw an error: ```js new Docxtemplater(zip, { paragraphLoop: true, linebreaks: true, delimiters: { start: "$(", end: ")", }, }); ``` ```template $(last_name) $(first_name) Some text (Some text) Some text $(last_name) $(first_name) ``` ```js MultiError { name: "TemplateError", id: "unopened_tag", explanation: "The tag beginning with \") Some text\" is unopened" } ``` The syntax can now be made more lenient to permit closing tags even when there are no corresponding opening tags. In your code, write : ```js new Docxtemplater(zip, { paragraphLoop: true, linebreaks: true, syntax: { allowUnopenedTag: true, }, }); ``` For now, the only available property for `syntax` object is `allowUnopenedTag` (it makes it possible to use the end delimiter tag as a text and not to parse it as a closing tag and cause syntax error). Fixes https://github.com/open-xml-templating/docxtemplater/issues/726. The default behavior for the parser without setting the syntax option is the same as in 3.39.2, meaning without the `syntax.allowUnopenedTag: true` option, placeholders that are closed but not opened will throw an error. - Internal: Refactor `getDelimiterErrors` function to be cleaner and more performant - Internal: Add tests for new functionality ### 3.39.2 - Internal: Remove mergeObjects from doc-utils.js - Internal: Small refactoring in regex - Internal: Avoid calling dropUnsupportedFileTypesModules too many times ### 3.39.1 Always add {tag} in second argument to parser, like this : ```js parser(tag, options) { console.log(options.tag.module); // for image tag, it will log "open-xml-templating/docxtemplater-image-module" } ``` ### 3.39.0 Add `preResolve` API for modules that allows to run some code before the calls to resolve. Update moduleApiVersion to version 3.37.0 ### 3.38.0 Add support for templating content which is in comments. ### 3.37.14 Bugfix following error, when calling `setOptions` and then `getFullText` : ``` Cannot read properties of null (reading 'tagsXmlTextArray') at XmlTemplater.getFullText (es6/xml-templater.js:53:56) at Docxtemplater.getFullText (es6/docxtemplater.js:484:5) ``` ### 3.37.13 In powerpoint, the inspect module will now return correctly for the `getAllTags` and `getStructuredTags` methods : For this to work, you need to install version 3.4.10 of slides module or above. For following template with the slides module attached : ``` {:loop} {$index}{name} ``` The output of `inspectModule.getAllTags()` will now be : ```js { loop: { $index: {}, name: {}, }, } ``` ### 3.37.12 For the following template ```template Hi {#products}{# . }-{ . }-{/}{/} ``` This did not work correctly with following data with expressions parser : ```js doc.render({ products: [ [1, 2, 3, 4], [4, 5, 6, 7], ], }); ``` It rendered : ``` Hi -1,2,3,4--4,5,6,7- ``` (which is incorrect) This is because the `docxtemplater/expressions.js` parser was returning an object instead of the array in this case. ### 3.37.11 Update handling of "." in angular parser. Docxtemplater now supports the following expression : ```template { . | myFilter } ``` This is the same as : ```template { this | myFilter } ``` Also, the following will also work now to access the "user-name" property of the root object (synonym of `this["user-name"]` : ```template {.["user-name"]} ``` ### 3.37.10 Important bugfix for modules, if you are still using the legacy constructor (eg if you still have `attachModule` somewhere in your code. For example, one issue that could happen is with the HTML module, you could have following stacktrace : ```txt Cannot read property 'getElementsByTagName' of undefined` error ``` This would happen when adding lists, and only if you're using one of following methods : `attachModule`, `setOptions`, or `loadZip`. ### 3.37.9 Update to render parts of the documents in the most natural order : First all header parts, than the main document body, than the footer part. ### 3.37.8 When using the following code : ```js const expressionParser = require("docxtemplater/expressions.js"); const doc = new Docxtemplater(zip, { parser: expressionParser }); doc.render(); ``` This would always fail (when the scope was not set), but this should be allowed. This will now work correctly. ### 3.37.7 Correctly calculate the endLindex for loop module. This fixes a bug of the Segmentmodule (part of the subtemplate module) where the segment would show wrongly an error of "Unclosed loop" when using the segment module with following template : ```template {:segment s} {#loop}{#loop}{value} {/}{/} {:segment/} {#loop} {:includesegment s} {/} ``` This fix also needs the latest subtemplate module : version 3.12.3 ### 3.37.6 Template docProps/app.xml before word/document.xml. This way, users can write assignments in the word/settings.xml, and use the exposed variables in the word/document.xml With 3.37.5, require("docxtemplater/text") would throw the following error : ``` Cannot find module './lexer.js' from 'node_modules/docxtemplater/text.js' ``` This is now fixed in version 3.37.6 ### 3.37.5 The TxtTemplater feature is now available using `require("docxtemplater/text")` ```js const TxtTemplater = require("docxtemplater/text.js"); const doc = new TxtTemplater("Hello {user}, how are you ?"); const result = doc.render({ user: "John" }); console.log(result); // Shows : "Hello John, how are you ?" ``` Previously this was only available at "docxtemplater/js/text.js", but now both are supported. ### 3.37.4 Add typings definitions for `docxtemplater/js/text.js` (Fixes #715) ### 3.37.3 Add better typings to expressions.js (including typings for filters). ### 3.37.2 Add support to get identifiers when using the `docxtemplater/expressions.js` package : ```js const expressionParser = require("docxtemplater/expressions.js"); const identifiers = expressionParser("x+0+users").getIdentifiers(); // identifiers will be : ["x", "users"] ``` ### 3.37.1 Add typescript typings to expressions.js ### 3.37.0 Improve the way {$index} is handled with the expressions parser. Previously, if you wrote the following : ```template {#todos} {#important}{$index}.! {text}{/} {^important}{$index}. ({text}){/} {/} ``` The `$index` value would always be equal to `0`. This was because the `$index` would use the closest condition or loop. Now, the library will look whether the `{#important}` is using an array or a boolean. Only for arrays will it calculate the `{$index}`, it will ignore any section that is a condition. This means that the output of the following will correctly be : ```output 0.! Do the dishes 1.! Invite XYZ 2. (Other thing) ``` Previously, the same template would show just 0 for the index. ### 3.36.1 Bugfix when using following in the template : ```txt {this["first name"]} ``` With following file : ```js doc.render({ "first name": "John", }); ``` This was incorrectly rendering undefined. The bug was present since version 3.32.0 Version 3.31.6 and before were not affected by this bug. Now, the code will correctly render : "John" in this case ### 3.36.0 Bugfix issue #707 : Correctly handle usage of {#.}{.}{/} with angular parser ### 3.35.0 Update moduleApiVersion to version 3.36.0 - Now the modules that define their `supportedFileTypes` will correctly be removed if the filetype does'nt match even when using the `attachModule` API. - Bugfix in FixDocPRCorruptionModule : when using the following code : ```js const fixDocPrCorruption = require("docxtemplater/js/modules/fix-doc-pr-corruption.js"); const doc = new Docxtemplater(zip, { modules: [fixDocPrCorruption] }); ``` The issue was that if you attached the same module to multiple docxtemplater instances in parallel, because of badly handled state, the state for the fixDocPrCorruption was overwritten ```js const doc1 = new Docxtemplater(zip, { modules: [fixDocPrCorruption] }); const doc2 = new Docxtemplater(zip, { modules: [fixDocPrCorruption] }); doc1.render(); // In this situation, the fixDocPrCorruption would use data from the doc2, which is incorrect, and could result in a corrupt document ``` Now, the fixDocPrCorruption can be used on multiple docxtemplater instances without causing any issue. ### 3.34.3 Fix typescript definition for constructor / zip instance. Allows to correctly autocomplete after doing `doc.getZip().generate()` Thanks to @oleksandr-danylchenko https://github.com/open-xml-templating/docxtemplater/pull/704 ### 3.34.2 Fix typescript definition for `getAllStructuredTags` : remove file argument. Fixed in #702 thanks to @oleksandr-danylchenko ### 3.34.1 Bugfix in `require("docxtemplater/expressions.js")` : Avoid error const expressionParser = require("docxtemplater/expressions.js"); ``` TypeError: 'set' on proxy: trap returned falsish for property 'x' ``` This will no more happen now, in the case where for example you wanted to set a property to any falsy value, like this : {x=0} ### 3.34.0 Add support to reorder modules automatically using module.priority. Fetch data from `_rels/.rels` and pass it to each module function using the `relType` attribute. Fixes issue in HTML module for some particular input that contains some `tp/document-orig.xml` file. ### 3.33.0 Add support for templating text files (or simple strings). Usage is like this : ```js const TxtTemplater = require("docxtemplater/js/text.js"); const doc = new TxtTemplater("Hello {user}, how are you ?"); const result = doc.render({ user: "John" }); console.log(result); // Shows : "Hello John, how are you ?" ``` This also works with loops and options can be set (parser for angular expressions) ### 3.32.6 Automatically template footnotes ### 3.32.5 When having a comment inside a placeholder, the document could get corrupt. This is now fixed. ### 3.32.4 Update resolveOffset algorithm to improve slides module compatibility. Internal update of moduleApiVersion to 3.34.0 ### 3.32.3 Bugfix of version 3.32.2, 3.32.1, 3.32.0 When using this document : ```txt Hello {name}! ``` if the data is `{ name: "" }` with the "docxtemplater/expresssions.js" option, the tag will render the following : ```txt Hello ! ``` In version 3.32.2, this would have rendered `Hello undefined!` which is incorrect. ### 3.32.2 Bugfix of version 3.32.1 and 3.32.0. Correctly expose `require("docxtemplater/expressions.js")`. ### 3.32.1 Add support to accented characters in tags when using the "docxtemplater/expressions.js" parser. Tags such as {être} will not throw an error. ### 3.32.0 Expose "docxtemplater/expressions.js" to simplify the parser option for angular parser. You now can replace your expressionParser code with the following : ```js const expressionParser = require("docxtemplater/expressions.js"); new Docxtemplater(zip, { parser: expressionParser }); ``` For IE11 or other runtimes that do not support "Proxy", you can use instead : ```js const expressionParser = require("docxtemplater/expressions.js"); new Docxtemplater(zip, { parser: expressionParser }); ``` Both examples require the `angular-expressions` package which is an external dependency : ```bash npm install --save angular-expressions ``` ### 3.31.6 Add `replaceFirstSection` and `replaceLastSection` booleans types for typescript and the subsection module. ### 3.31.5 Bugfix for pptx files not keeping correct font properties (font-size) when using `{linebreak: true}` option. ### 3.31.4 Bugfix to correctly handle empty loops. Fixes https://github.com/open-xml-templating/docxtemplater/issues/680 Previously the following stack trace would be shown : ```txt TypeError: Cannot read properties of undefined (reading 'lIndex') at .../docxtemplater/js/modules/loop.js:331:42 at Array.some (<anonymous>) at LoopModule.postparse (.../docxtemplater/js/modules/loop.js:322:15) at .../docxtemplater/js/parser.js:226:24 at Array.reduce (<anonymous>) at _postparse (.../docxtemplater/js/parser.js:225:22) at postparse (.../docxtemplater/js/parser.js:228:20) at .../docxtemplater/js/modules/expand-pair-trait.js:268:30 at Array.reduce (<anonymous>) at Object.postparse (.../docxtemplater/js/modules/expand-pair-trait.js:248:32) ``` Now the template is rendered correctly. ### 3.31.3 Bugfix for table module : merge-cells-col did not work correctly when placed inside a loop. Fixes : https://github.com/open-xml-templating/docxtemplater/issues/671 ### 3.31.2 Bugfix to avoid throwing following error : ``` New Delimiters cannot be parsed ``` When the template contains an equal sign right after a closing tag. For example, the following template would throw that error in previous versions : ``` Hello {name}=== ``` Now, no error is thrown. ### 3.31.1 Correctly handle case when having a manual section break of type "nextPage", that is within a loop. Add "cp:contentStatus" to templated tags ### 3.31.0 When having a table, that after the generation, has no table rows (<w:tr> elements), the whole `<w:tbl>` element is dropped. This automatically fixes a corruption that would happen when using a loop within table rows. If you are using the subtemplate module, you have to update to subtemplate module 3.11.3 ### 3.30.3 Throw an error when calling `doc.render()` twice on the same instance. ### 3.30.2 Bugfix in fix-doc-pr-corruption module to work with xmlDocuments too. ### 3.30.1 Bugfix to correctly add `xml:space="preserve"` for each type of placeholder, not just for the loop module. This fixes spacing issues that happened rarely in many modules that have an "inline mode" (word-run, image, html, styling, paragraph-placeholder). ### 3.30.0 Make it possible to have a tag that contains multiple lines, like this : ```txt Hello { name = "John"; name; }, how are you ? ``` And remove the paragraphs correctly. Internal update of moduleApiVersion to 3.33.0 After upgrading this, you will need to upgrade : - image-module to 3.14.2 or higher - xlsx-module to 3.10.2 or higher - styling-module to 3.6.14 or higher ### 3.29.5 Bugfix to make loop module work well even on dotx files. Internal update of moduleApiVersion to 3.32.0 ### 3.29.4 Improve corruption handling of adding `<w:p/>` after some tables, even when the table is added inside a loop. ### 3.29.3 Avoid corruption when having a table without a `<w:p/>`. This corruption only happens on very rare cases, for example when having a table containing a table that has no paragraph after it. ### 3.29.2 With the paragraphLoop option turned on, when using a loop that was containing a selfclosing paragraph : `<w:p/>`, the generated output could become corrupt. Now the output is valid. ### 3.29.1 Handle following input when using loops with array : ``` {#users} Hello {name} {/users} ``` ```js doc.renderAsync({ users: [ new Promise((resolve, reject) => { resolve({ name: "John" }); }), new Promise((resolve, reject) => { resolve({ name: "Mary" }); }), ], }); ``` ### 3.29.0 Log errors on multiple lines instead of on one line. Previously, error messages were shown in one line only, making the output hard to read. Now, error messages are shown on multiple lines, using normal JSON indentation. You can use the previous behavior (one big JSON line) by writing the following : ```js var doc = new Docxtemplater(zip, { paragraphLoop: true, linebreaks: true, errorLogging: "jsonl", // JSONL stands for JSON Line, one big JSON entry on a single line // Other options for errorLogging are false which means do not log anything, or "json" (which is now the default) }); ``` ### 3.28.6 Template document properties that are set inside `<vt:lpwstr>` in docProps/custom.xml ### 3.28.5 Add slideLayout files to list of templated files Internal update of moduleApiVersion to 3.31.0 ### 3.28.4 Bugfix issue introduced in 3.28.3 when using expandOne trait ### 3.28.3 Update expandOne trait to work even when having nested `<w:p>` and `<w:txbxContent>` tags Fixes issue in the styling module in particular. This release might slow down documents having many rawxml tags ### 3.28.2 Throw specific error when using rawxml tag and the type of the output is not a string. For example, if you do the following : ```txt {@raw} ``` ```js doc.render({ raw: 42, }); ``` This will throw the following error : `Non string values are not allowed for rawXML tags` ### 3.28.1 Typing files : make them Typescript 3.x compatible (a change in 3.28.0 of docxtemplater made the typings only work with typescript 4+) Add type for "errorLogging" parameter ### 3.28.0 Internal update of moduleApiVersion to 3.30.0 Add `matchers` API for modules, to replace the internal `parse` function. This internal change fixes bugs that can be triggered between for example the SlidesModule and the TableGridPptxModule. When two modules have two prefixes that contain each other, for example the SlidesModule has a prefix of `:` as in `{:users}`, and the TableGridPptxModule is `:#` as in `{:#1}`. In versions before this version, the tag `{:#1}` would be Interpreted as a SlidesModule tag depending on the order of the modules. Since this version, the `matchers` API makes it possible for docxtemplater to intelligently decide that the tag belongs to the TableGridPptxModule. The algorithm used is to use a "priority" integer if present, or to use the tag that has the longest prefix. This change requires updates in following modules : - chart 3.4.0 or higher - footnotes 3.3.0 or higher - html-pptx 3.3.0 or higher - html 3.29.0 or higher - image 3.12.0 or higher - paragraph-placeholder 3.3.0 or higher - pptx-sub 3.1.0 or higher - slides 3.4.0 or higher - styling 3.5.0 or higher - subsection 3.5.0 or higher - subtemplate 3.9.0 or higher - table 3.15.0 or higher - word-run 3.2.0 or higher - xlsx 3.8.0 or higher ### 3.27.2 Internal bugfix that would show a stacktrace instead of the real underlying RenderingError. The stacktrace was "Cannot read property indexOf of undefined" in the `isStarting` function Tag names containing "non-breaking-spaces" (Ascii code 160) will be converted to normal spaces. ### 3.27.1 Bugfix issue introduced in 3.27.0 When using the option `{linebreaks: true}`, documents could be made corrupt on version 3.27.0 This version fixes the corruption ### 3.27.0 Internal update of moduleApiVersion to 3.29.0 Add support to output docx files that are bigger than 500MB. Please make sure to update the following modules if you use them : - chart 3.3.0 or higher - error-location 3.4.0 or higher - html 3.28.0 or higher - image 3.11.0 or higher - subsection 3.4.0 or higher - subtemplate 3.8.0 or higher - table 3.14.0 or higher - styling 3.4.0 or higher Previously, after a certain limit (usually about 500MB), the error "Invalid String Length" would be thrown by Node, because that is the max string length allowed. Fixes issue reported here : https://stackoverflow.com/questions/68578216/docxtemplater-rangeerror-invalid-string-length A test has been created, which you can run with `npm run memorytest` if you clone this repository. It will create a file of about 550MB. This test need more memory than the default tests, and takes about 75 seconds on my computer. ### 3.26.4 Bugfix to template header and footers created by Office365. Previously, only files matching header\d.xml would be templated. Now, also header.xml (without any digit) will be templated. ### 3.26.3 Bugfix issue when having tab character in the document, that would, after rendering, appear as "&#9;" in the document. When updating to this version, you also need to update - the xlsx module to 3.7.2 - the error-location module to 3.3.1 Internal update of moduleApiVersion to 3.28.0 ### 3.26.2 Bugfix issue "Cannot read property 'tag' of undefined" when having an empty condition, like : ``` Hello {#a}{/a} ``` Altough there is not really a good reason to create such an empty condition, it is better to not fail with an obscure error message. ### 3.26.1 Add code for fix-doc-pr-corruption accessible by doing : ```js const fixDocPrCorruption = require("docxtemplater/js/modules/fix-doc-pr-corruption.js"); const doc = new Docxtemplater(zip, { modules: [fixDocPrCorruption] }); ``` ### 3.26.0 Add automatic error logging using console.log to make code samples easier. You can replace the following code : ```js // The error object contains additional information when logged // with JSON.stringify (it contains a properties object containing all suberrors). function replaceErrors(key, value) { if (value instanceof Error) { return Object.getOwnPropertyNames(value).reduce(function (error, key) { error[key] = value[key]; return error; }, {}); } return value; } function errorHandler(error) { console.log(JSON.stringify({ error: error }, replaceErrors)); if (error.properties && error.properties.errors instanceof Array) { const errorMessages = error.properties.errors .map(function (error) { return error.properties.explanation; }) .join("\n"); console.log("errorMessages", errorMessages); // errorMessages is a humanly readable message looking like this: // 'The tag beginning with "foobar" is unopened' } throw error; } var zip = new PizZip(content); var doc; try { doc = new Docxtemplater(zip, { paragraphLoop: true, linebreaks: true, }); } catch (error) { // Catch compilation errors // (errors caused by the compilation of the template: misplaced tags) errorHandler(error); } try { // render the document // (replace all occurences of {first_name} by John, {last_name} by Doe, ...) doc.render({ first_name: "John", last_name: "Doe", phone: "0652455478", description: "New Website", }); } catch (error) { // Catch rendering errors // (errors relating to the rendering of the template: // for example when the expressionParser throws an error) errorHandler(error); } ``` to this : ```js var zip = new PizZip(content); var doc = new Docxtemplater(zip, { paragraphLoop: true, linebreaks: true, }); // render the document // (replace all occurences of {first_name} by John, {last_name} by Doe, ...) doc.render({ first_name: "John", last_name: "Doe", phone: "0652455478", description: "New Website", }); ``` To disable this automatic errorLogging, use : ```js var doc = new Docxtemplater(zip, { paragraphLoop: true, linebreaks: true, errorLogging: false, }); ``` ### 3.25.5 Add specific error message when using a module without instantiating it. When doing : ```js const HtmlModule = require("docxtemplater-html-module"); const doc = new Docxtemplater(zip, { modules: [HtmlModule] }); ``` The error message shown will now be : ``` Cannot attach a class/function as a module. Most probably you forgot to call new on the module. ``` If you get this error, you should simply write : ```js const HtmlModule = require("docxtemplater-html-module"); const doc = new Docxtemplater(zip, { modules: [new HtmlModule()] }); ``` ### 3.25.4 Bugfix when having loop containing hebrew, the text would be escaped once for each iteration The regression was introduced in version 3.25.2 and is now fixed ### 3.25.3 Fix issue in rendering of tables generated with loop module for Powerpoint documents by deduplicating a16:rowId tags. Previously, when having a loop, the following would be generated : ``` <a:tr> <a:t>Content</a:t> <a:extLst> <a:ext> <a16:rowId val="1379104516"/> </a:ext> </a:extLst> </a:tr> <a:tr> <a:t>Content</a:t> <a:extLst> <a:ext> <a16:rowId val="1379104516"/> </a:ext> </a:extLst> </a:tr> ``` The duplicate `val` attribute for the a16:rowId caused rendering issues on office live. Now, the values are incremented after each loop, like this : ``` <a:ext> <a16:rowId val="1379104516"/> </a:ext> <a:ext> <a16:rowId val="1379104517"/> </a:ext> ``` ### 3.25.2 When having a loop inside a pptx table, the height of the frame was not updated if a tag in the form of : `<a:ext uri="{11111111-1111-1111-1111-111111111111}">` was present in the document. Now, those tags are ignored and the height of the table should be updated appropriately. ### 3.25.1 When having a loop inside a pptx table, the height of the frame will automatically be updated if some rows are added or removed. In previous versions, the table would keep the previous height, meaning the added rows would not be shown, except after forcing a rerendering of the table by changing the fontsize. ### 3.25.0 Add support for "lambdas", eg if a value in the data is a function, that function will be called with the `scope` and the `scopeManager`. You now can write : ```js const doc = new Docxtemplater(zip); doc.render({ userGreeting: (scope) => { return "How is it going, " + scope.user + " ? "; }, users: [ { name: "John", }, { name: "Mary", }, ], }); ``` With the following template : ```txt {#users} {userGreeting} {/} ``` ### 3.24.0 Add support to remove the call to `setData` or `resolveData`. (The setData function and resolveData will still work, but will be dropped in Docxtemplater v4) You can now do : ```js const doc = new Docxtemplater(zip, { linebreaks: true }); doc.render({ user: "John", }); ``` or, in the async version : ```js const doc = new Docxtemplater(zip, { linebreaks: true }); doc .renderAsync({ user: new Promise(function (resolve, reject) { resolve("John"); }), }) .then(function () { const zip = doc.getZip().generate({ type: "nodebuffer", compression: "DEFLATE", }); }); ``` ### 3.23.2 Bugfix error : `Can