Important : This module only supports xlsx (Excel documents), not docx, see the html if you want to include HTML inside Word documents.
The module also needs the XLSX module to work.
To achieve that, simply add "~~" in front of your field name. The final syntax should be: {~~myField}
You can then write in your data, the following :
const HTMLXlsxModule = require("docxtemplater-html-xlsx-module");
const doc = new Docxtemplater(zip, {
modules: [new HTMLXlsxModule({})],
});
doc.render({ myField: "<b>Hello</b>, Foo !" });
const HTMLXlsxModule = require("docxtemplater-html-xlsx-module");
const XlsxModule = require("docxtemplater-xlsx-module");
const fs = require("fs");
const doc = new Docxtemplater(zip, {
modules: [new XlsxModule(), new HTMLXlsxModule({})],
}).render({ html: "<b>Hello</b>, Foo !" });
const buffer = doc.toBuffer();
fs.writeFile("test.xlsx", buffer);
<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/xlsxmodule.js"></script>
<script src="build/html-xlsx-module.js"></script>
<script>
PizZipUtils.getBinaryContent(
"examples/input.xlsx",
(error, content) => {
if (error) {
console.error(error);
return;
}
const zip = new PizZip(content);
const doc = new docxtemplater(zip, {
modules: [
new DocxtemplaterXlsxModule(),
new DocxtemplaterXlsxHtmlModule({}),
],
});
doc.render({
html: "<p>Hello <b>John</b></p>",
});
const out = doc.toBlob();
saveAs(out, "generated.xlsx");
}
);
</script>
</html>
This module currently supports:
<a href="URL">Linktext</a>
<b>
, <u>
and <i>
tags<strong>
, <em>
and <span>
tags<ul>
, <ol>
, and <li>
<br>
font-size: 15px
color: #770
It is possible to style the full cell (changing the background color, text-align or borders).
Use it like this :
{~~html} |
const HTMLXlsxModule = require("docxtemplater-html-xlsx-module");
const doc = new Docxtemplater(zip, {
modules: [new HTMLXlsxModule({})],
});
doc.render({
myField: {
html: "<b>Hello</b>, Foo !",
cellStyle: `
background-color: #008ff0;
text-align: right;
border-bottom: 3px dashed #f0f;
`,
},
});
It is possible to add styles to your HTML using CSS.
You can do so using the following code :
const HTMLXlsxModule = require("docxtemplater-html-xlsx-module");
const doc = new Docxtemplater(zip, {
modules: [
new HTMLXlsxModule({
styleSheet: `
.important {
font-size: 25px;
color: black;
font-weight: bold;
}
`,
}),
],
});
doc.render({
html: "<span class='important'>Hello</span>, Foo !",
});
You can use following selectors currently :
Selector | Example | Example description |
---|---|---|
.class | .intro | Elements with class="intro" |
#id | #firstname | Element with id="firstname" |
* | * | All elements |
element | p | <p> elements |
element, element | div, p | All <div> elements and all <p> elements |
element element | div p | <p> elements inside <div> elements |
element > element | div > p | <p> elements where the direct parent is a <div> element |
element + element | div + p | <p> elements that are placed immediately after <div> elements |
[attribute] | [target] | Elements with a target attribute |
[attribute=value] | [target=_blank] | Elements with target="_blank" |
border-collapse
The border-collapse
property is ignored in the HTML module.
This is because in Excel, table borders are not collapsible — each cell defines its own borders, and only one border can appear between two adjacent cells. You cannot force Excel to render two overlapping borders like in HTML with border-collapse: separate
.
As a result, border-collapse
has no effect in the XLSX context and is effectively meaningless.
If you place a block placeholder in a paragraph, like this
The behavior of this is controlled by the option onInvalidBlock
.
The value can be set like this :
const doc = new Docxtemplater(zip, {
modules: [new HTMLModule({ onInvalidBlock: "block" })],
paragraphLoop: true,
linebreaks: true,
});
doc.render({
/* data */
});
The possible values are the following :
"block"
(default) which will remove the rest of the paragraph, and render the HTML tag."inline"
, which will automatially convert that HTML tag into an HTML tag. In that case, HTML block tags such as <table>
will not be shown as real tables."error"
, which will raise a template error.If putting an HTML tag inside a loop, keep the HTML tag as block if there is no content except for the loop start.
Show warning if trying to import multiple links in one cell (this is not possible because of an excel limitation).
Correctly render multiple links if using horizontal loop
{>loop}{~html} |
The xlsx module version 3.34.1 or higher is required to make this version work.
Fix stacktrace when having inline html tag that returns a non-string (now, it is automatically first converted to a string).
This version needs the xslx-module version 3.34.0 or higher.
If your data returns something that is not a string, the HTMLXlsx Module will call the XlsxModule, which allows you to render Dates or other types with the HTMLXlsx Module.
Add support for onInvalidBlock: "inline"
which will automatically convert a block tag to an inline tag if the context does not allow a block tag.
With this template :
{#loop}{~~html}{/} | {/} |
The {~~html} block tag is normally not allowed inside an inline loop, if you set onInvalidBlock: "inline"
, the module will transform the html tag to an inline tag.
Use it like this :
const HTMLXlsxModule = require("docxtemplater-html-xlsx-module");
const XlsxModule = require("docxtemplater-xlsx-module");
const doc = new Docxtemplater(zip, {
paragraphLoop: true,
linebreaks: true,
modules: [
new XlsxModule(),
new HTMLXlsxModule({
onInvalidBlock: "inline",
}),
],
});
doc.render({
name: "<b>John</b>",
});
If you set the same prefix for block tags and for inline tags, the option onInvalidBlock: "inline"
is automatically set.
Add support for html-inline tag (requires xlsx module 3.33.0).
Fix error that was thrown when an html tag is on a cell that has no style specified.
Fix error when passing non-string value to the html-xlsx module.
Bugfix error when using following input :
doc.render({
html: `
<p>A B C</p>
<p></p>
<p>DEF</p>
<p></p>
<p></p>
<p>G HI</p>
`,
});
The following error was shown :
Now this error has been fixed
Verify that all options specified in the module's constructor are valid by ensuring the types are accurate, using Minizod, a library akin to Zod for type verification.
Use new internal xmlContentTypes API (requires docxtemplater 3.55.1 or higher)
Make this module compatible with xlsx module 3.29.2 and above
In very rare cases, the html-xlsx module could produce output that would show an error message when opened with Excel. This requires version 3.27.5 of the xlsx module.
This version now produces correct documents.
Make it possible to use prefix from the constructor
Add typescript typings to be able to change the module prefix
Bugfix to allow to mix together <ol>
tags together with <u>
, <b>
tags.
Previously, the following would result in an error :
doc.render({
html: `
<u>Underline</u> Foobar <b>strong</b>
<ol><li>Todo</li><li>Foobar</li></ol>
<br>
<p>X Y Z</p>
<br>
<p>O M P</p>
<ul>
<li>Zoo</li>
<li>Bax</li>
</ul>
<br>
<br>
Zaza
`,
});
It now renders correctly the complete content.
The fix which was theoretically fixed in version 3.2.3 was still present.
The complexity was still O(n²) because the following was used :
// simplified code
const relsDoc = {}; // ...
const links = []; // links will be "https://ddg.gg", ...
function addLink(link) {
const relationships =
relsDoc.getElementsByTagName("Relationships")[0];
const child = relsDoc.createElement("Relationship");
child.getRelationFromLink(link);
relationships.appendChild(child);
}
for (let i = 0, len = links.length; i < len; i++) {
addLink(links[i]);
}
getElementsByTagName
is called for each iteration of the loop.
Since getElementsByTagName() needs to check each node in the XML, the more nodes there are, the more time this function takes.
It makes more sense to get the relationships object outside of the addLink function (which then acts as a sort of cache).
Adding 10000 links should take about 2.5 seconds now.
When using the HTML tag and inserting links, there was a performance issue when adding over 1000 links in a document.
The more links you added, the slower it got.
This is now fixed, and the time spent should be proportional to the number of links added (10000 links should still take about 2 seconds). Previously, adding 10000 links could easily take 30 seconds.
See this Create React App issue and this @adobe/css-tools issue.
Add support for <figure>
and <figcaption>
tag (which renders exactly like a div).
Make it possible to style the full cell : border
, text-align
, background-color
;
Bugfix when using special characters in links.
Previously, the following code would produce a corrupt document :
const HTMLXlsxModule = require("docxtemplater-html-xlsx-module");
const XlsxModule = require("docxtemplater-xlsx-module");
const doc = new Docxtemplater(zip, {
modules: [new XlsxModule(), new HTMLXlsxModule({})],
});
doc.render({
html: "<a href=\"https://ddg.gg/>''\">< && \"DDG' & > XXX</a>",
});
Now the generated document is valid.
Upgrade module to use NodeNext moduleResolution setting. See explanation here
Bugfix issue when having tag inside "sheetname" (a normal tag, not an HTML tag). The value shown would simply be "true".
Use new resolvedId
API => requires docxtemplater@3.43.0
Add support for setting ignoreUnknownTags:true
Fix bug when using renderAsync and parser compilation fails : the error should now be shown inside a multierror. To to this, we know use sm.getValueAsync
in resolve instead of sm.getValue
Set module.priority in order to have no more issues related to module ordering
Bugfix issue when using expand horizontal loop in xlsx :
Bugfix issue when using loop module with HtmlXlsxModule enabled, the following template :
{#items} | {#x}1{/}{#y}2{/y} | {/} |
Would produce :
In async mode :
In sync mode :
Add module.clone() internal
Bugfix when passing in empty string : ""
or blank string : " "
.
Previously, the following error was thrown :
Add support for :
<ul>
, <ol>
, and <li>
<br>
font-size: 15px
color: #770
Bugfix for <strong>
, <em>
, <i>
, <u>
.
Initial release