This module only supports docx (Word documents), not pptx, see the html-pptx module if you want to include HTML inside Powerpoint presentations. Also see the html-xlsx module to include HTML into Excel Spreadsheets.
Using the HTML module, you can include dynamic formatted text in the output Document by passing HTML as a field value.
To achieve that, simply add ~~
as a prefix to your field name. The final syntax should be: {~~myField}
Then, use following code :
const doc = new Docxtemplater(zip, {
modules: [new HTMLModule({})],
});
doc.render({ myField: "<b>Hello</b>, Foo !" });
const HTMLModule = require("docxtemplater-html-module");
const fs = require("fs");
const path = require("path");
// Load the docx file as binary content
const content = fs.readFileSync(
path.resolve(__dirname, "input.docx"),
"binary"
);
const zip = new PizZip(content);
const doc = new Docxtemplater(zip, {
modules: [new HTMLModule({})],
}).render({ html: "<b>Hello</b>, Foo !" });
const buffer = doc.getZip().generate({
type: "nodebuffer",
compression: "DEFLATE",
});
fs.writeFile("test.docx", 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/html-module.js"></script>
<script>
PizZipUtils.getBinaryContent(
"examples/html-block-example.docx",
function (error, content) {
if (error) {
console.error(error);
return;
}
const zip = new PizZip(content);
const doc = new docxtemplater(zip, {
modules: [new DocxtemplaterHtmlModule({})],
});
doc.render({
html: "<p>Hello <b>John</b></p>",
});
const out = doc.getZip().generate({
type: "blob",
mimeType:
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
});
saveAs(out, "generated.docx");
}
);
</script>
</html>
Inline HTML Tags: Start with a single ~
{~html}
or {~inlineComment}
Block HTML Tags: Start with double ~~
{~~html}
or {~~styledTable}
{~inline}
My product is {~blueText} and costs ...
<span>
, <b>
, <i>
, <u>
, etc.){~~block}
{~~block}
<p>
, <ul>
, <table>
, <ol>
, <h1>
, etc.)The HTML block tag {~~html}
works only with paragraphs, not with line breaks. See this tip in the FAQ to understand how to view and replace line breaks.
The HTML module currently supports following tags :
<p> (paragraphs)
<h1-h6> // <h1> translates to "Title",
// <h2> translates to "Header1"
// <h3> translates to "Header2",
<b> (bold)
<i> (italic)
<u> (underline)
<ul>, <ol> and <li> for ordered and unordered lists
<span>
<small>
<s> (strikethrough)
<ins> and <del>
<strong> (bold)
<em> (italic)
<code> (gray highlight)
<table>, <tr>, <td>, <tbody>, <thead>, <tfoot>, <th> tags
<col> and <colgroup> to specify column sizes
<a href="URL">Linktext</a> (links)
<input type="checkbox"> and <input type="checkbox" checked> (Checkboxes)
<sub> and <sup> (exponents)
<pre>, by using Courrier font and retaining all spaces
<mark> (for highlighting text parts)
<br> (line-breaks)
<hr> (horizontal-breaks)
<img> only if including the imageModule too, by using base64 src
<svg> only if including the imageModule too
<center> tag to place a paragraph to the center
<template>,<script> tag to ignore some part of the HTML
For SVG, the generated document will only be readable on newer Word version : Microsoft Word, PowerPoint, Outlook, and Excel 2016 on Windows, Mac, Android and Windows Mobile. See this article for details about this feature
We support the following CSS properties :
color: #bbbbbb;
font-size: 30px;
font-family: 'Times New Roman';
background-color: blue; /* (or with rgb codes) */
text-decoration: underline;
padding-left: 30px;
padding-bottom: 30px;
padding-top: 30px;
width:33%; height: 50%; /* (on td only) */
text-align:justify;
vertical-align: bottom; /* (on td) */
border: none; /* (on tables) */
break-after:page;
break-after:avoid;
break-after:unset|initial|auto;
break-before:page;
white-space:pre;
line-height: 1.3; /* (or with percentages, or fixed values such as `20px`) */
margin-top: 30px;
margin-bottom: 30px;
margin-left: 30px;
You can configure options for the htmlModule.
<span>
;To ignore all unknown tags:
const doc = new Docxtemplater(zip, {
modules: [
new HTMLModule({
ignoreUnknownTags: true,
}),
],
});
doc.render(data);
To remap the styles so that h1 maps to Heading1 (instead of the default Title)
function styleTransformer(tags, docStyles) {
tags.h1 = docStyles.Heading1;
tags.h2 = docStyles.Heading2;
tags.h3 = docStyles.Heading3;
tags.h4 = docStyles.Heading4;
tags.h5 = docStyles.Heading5;
/* Note that docStyles.Heading1 is a hardcoded value in the docxtemplater
* html code, it is exactly the same as writing :
*
* tags.h1 = {
* type: "block",
* data: {
* pStyle: "Heading",
* props: [],
* },
* }
*/
return tags;
}
const doc = new Docxtemplater(zip, {
modules: [
new HTMLModule({
styleTransformer,
}),
],
});
doc.render(data);
If you want to remap h1 to an other paragraphStyle (w:styleId property in styles.xml), you can do the following :
function styleTransformer(tags, docStyles, opts) {
if (opts.styleIds.indexOf("Titre1") !== -1) {
tags.h1.data.pStyle = "Titre1";
}
return tags;
}
const doc = new Docxtemplater(zip, {
modules: [
new HTMLModule({
styleTransformer,
}),
],
});
doc.render(data);
You can also create new HTMLtags with the styleTransformer api, for example :
function styleTransformer(tags) {
tags.p2 = { type: "block", data: {} };
tags.highlight = {
type: "inline",
data: {
props: [
{
type: "string",
tag: "w:b",
value: "<w:b/>",
},
{
type: "string",
tag: "w:highlight",
value: '<w:highlight w:val="yellow"/>',
},
],
},
};
return tags;
}
const doc = new Docxtemplater(zip, {
modules: [
new HTMLModule({
styleTransformer,
}),
],
});
doc.render({
html: "<p2>Hello <highlight>Foobar</highlight></p2>",
});
To change the size of "padding-left":
const doc = new Docxtemplater(zip, {
modules: [
new HTMLModule({
sizeConverters: {
paddingLeft: 20,
},
}),
],
});
doc.render(data);
This will make paddingLeft a little bit larger on word than the default (which is 15).
To add a global stylesheet
const htmlModuleOptions = {
styleSheet: `
h1 {
font-size: 60px;
}
span#foo {
font-size: 30px;
color: red;
}
`,
};
const doc = new Docxtemplater(zip, {
modules: [new HTMLModule(htmlModuleOptions)],
});
doc.render(data);
Please note that this API should only be utilized when you need to generate a unique type of tag that cannot be achieved using the styleTransformer
API. With the styleTransformer
API, you have the capability to craft new tag types and assign certain XML properties to them.
The customTags
API was introduced for scenarios where direct manipulation of XML is necessary, moving away from relying on the HTML module function to handle HTML children and similar tasks.
It is possible to create a new handler for an HTML tag to create your own XML.
For example, if you want to add some specific element in your HTML that you want to render from your code, you could do the following:
First find a name for your new element, in our case we will use the tag <mytag>
.
In your code, you can then return the XML that you want to render, like this :
const htmlModuleOptions = {
customTags: {
mycheckbox: {
type: "inline",
value(element, { getText }) {
const text = getText(element);
console.log(text);
// text="inner text"
// Return OpenXML with some formatting (bold here)
return {
type: "inline",
data: `<w:r><w:rPr><w:b/></w:rPr><w:t>[✓]</w:t></w:r>`,
};
},
},
},
};
const doc = new Docxtemplater(zip, {
modules: [new HTMLModule(htmlModuleOptions)],
});
doc.render({
html: "<p>Hello, here is <mycheckbox/></p>",
});
You can either configure your tag to be "inline" or "block", and can customize how it is going to be rendered in the value function.
This module handles only docx documents, not pptx.
The reason for that is that HTML maps well to docx because they use the same linear flow, eg elements are placed one after the other in the document. However PPTX documents have multiple slides, which are stored in different files, and each element is positioned absolutely in the slide. For example, in PPTX if you have a table element and a paragraph in the same slide, they need to be placed in two "different" blocks.
There is the HTML-pptx-module that handles HTML insertion for PPTX.
<img>
To be able to replace the <img>
tag, you have to also have access to the Image Module.
Then, you can do :
const HTMLModule = require("docxtemplater-html-module");
const ImageModule = require("docxtemplater-image-module");
const htmlModuleOptions = {
img: {
Module: ImageModule,
/*
* By default getSize returns the width and height attributes
* if both are present, or 200x200px as a default value.
*/
getSize(img, b, c, d) {
/* The html element, for example, if the data is :
* '<img width="20" src="...">'
* you will have :
*
* img.element.attribs.width = '20'
*
*/
/* If the data is '<img style="width:200px;" src="...">'
* '<img width="20" src="...">'
* you will have
*
* img.parsedStyle = [
* { property: "width", value: "200px"}
* ]
*
* on which you could do :
*
* for ({property, value} of img.parsedStyle) {
* if (property === "width") {
* width = parseInt(value.replace(/px$/, ""), 10);
* }
* }
*/
console.log(img.element);
/* data.src is the arraybuffer of your image
* (you could use the image-size library to to calculate the size)
* (https://github.com/image-size/image-size)
*/
console.log(img.src);
// data.part.value is 'myTag' if your tag is {~myTag}
console.log(img.part.value);
let width, height;
console.log(b, c, d);
if (img.element.attribs.style) {
const style = img.element.attribs.style;
const widthMatch = style.match(
/width:\s*(\d+(\.\d+)?)(px)?/
);
const heightMatch = style.match(
/height:\s*(\d+(\.\d+)?)(px)?/
);
width = widthMatch
? parseFloat(widthMatch[1])
: 200;
height = heightMatch
? parseFloat(heightMatch[1])
: 200;
} else {
width = 200;
height = 200;
}
// This is to handle the fact that when an img is inside a table,
// the width of the image should not exceed the width of the table.
if (typeof d.part.containerWidth === "number") {
if (d.part.containerWidth > width) {
const ratio = width / d.part.containerWidth;
width *= ratio;
height *= ratio;
}
}
// You return an array in pixel
// width:50px,height:100px
return [width, height];
},
},
};
const doc = new Docxtemplater(zip, {
modules: [new HTMLModule(htmlModuleOptions)],
});
doc.render(data);
The <img>
tag supports base64 and also urls, so for example, you can do :
<p>Hello</p>
<img
src="data:image/gif;base64,R0lGODlhDAAMAIQZAAAAAAEBAQICAgMDAwQEBCIiIiMjIyQkJCUlJSYmJigoKC0tLaSkpKampqenp6ioqKurq66urrCwsPb29vr6+vv7+/z8/P39/f7+/v///////////////////////////yH+EUNyZWF0ZWQgd2l0aCBHSU1QACwAAAAADAAMAAAFSiCWjRmViVVmZRWWjiurXrBI2uMkFcdjrRfaJQIQCAKQTDBmKAYACAwuswAABoBEDMUgYAkOpWiFeRgUDZIKNnqpLaJLXM2KjaYhADs="
alt=""
/>
Note that HTTP URLs in src will not work by default, you have to configure docxtemplater in async mode to do so.
You can use the following getSize function if you would like to use the same width and height as the image source.
import sizeOf from "image-size";
function getSize(img) {
const buffer = new Buffer(img.src);
const sizeObj = sizeOf(buffer);
return [sizeObj.width, sizeObj.height];
}
const htmlModuleOptions = {
img: {
Module: ImageModule,
// By default getSize returns the width and height attributes if both
// are present, or 200x200px as a default value.
getSize,
},
};
const doc = new Docxtemplater(zip, {
modules: [new HTMLModule(htmlModuleOptions)],
});
doc.render(data);
You can also add a caption to the image if using image module 3.7.0 or above, and use the following :
const HTMLModule = require("docxtemplater-html-module");
const ImageModule = require("docxtemplater-image-module");
const htmlModuleOptions = {
img: {
Module: ImageModule,
// By default getSize returns the width and height attributes if both
// are present, or 200x200px as a default value.
getProps(data) {
return {
caption: {
text: `: ${data.element.attribs.title}`,
},
};
},
},
};
const doc = new Docxtemplater(zip, {
modules: [new HTMLModule(htmlModuleOptions)],
});
doc.render(data);
It is possible to add images with src="http://......"
by using async docxtemplater.
You can customize the image resolver with the getValue
function.
Here is an example showing how to retrieve the data from https://avatars3.githubusercontent.com/u/2071336?v=3&s=100
:
const fs = require("fs");
const https = require("https");
const http = require("http");
const url = require("url");
const Docxtemplater = require("docxtemplater");
const ImageModule = require("docxtemplater-image-module");
const HTMLModule = require("docxtemplater-html-module");
const PizZip = require("pizzip");
function base64DataURLToArrayBuffer(dataURL) {
const stringBase64 = dataURL.replace(
/^data:image\/([a-z]+);base64,/,
""
);
let binaryString;
if (typeof window !== "undefined") {
binaryString = window.atob(stringBase64);
} else {
binaryString = Buffer.from(
stringBase64,
"base64"
).toString("binary");
}
const len = binaryString.length;
const bytes = new Uint8Array(len);
for (let i = 0; i < len; i++) {
const ascii = binaryString.charCodeAt(i);
bytes[i] = ascii;
}
return bytes.buffer;
}
const defaultImage = base64DataURLToArrayBuffer(
"data:image/gif;base64,R0lGODlhDAAMAIQZAAAAAAEBAQICAgMDAwQEBCIiIiMjIyQkJCUlJSYmJigoKC0tLaSkpKampqenp6ioqKurq66urrCwsPb29vr6+vv7+/z8/P39/f7+/v///////////////////////////yH+EUNyZWF0ZWQgd2l0aCBHSU1QACwAAAAADAAMAAAFSiCWjRmViVVmZRWWjiurXrBI2uMkFcdjrRfaJQIQCAKQTDBmKAYACAwuswAABoBEDMUgYAkOpWiFeRgUDZIKNnqpLaJLXM2KjaYhADs="
);
const base64Regex =
/^(?:data:)?image\/(png|jpg|jpeg|svg|svg\+xml);base64,/;
const htmlOptions = {
img: {
Module: ImageModule,
getValue: (el) => {
const src = el.attribs.src;
return new Promise(function (resolve) {
// You should handle any errors here, if the promise rejects,
// the rendering will fail with that error.
// This is to continue to handle base64 images
if (base64Regex.test(src)) {
resolve(base64DataURLToArrayBuffer(src));
return;
}
let parsedUrl;
try {
parsedUrl = url.parse(src);
} catch {
resolve(defaultImage);
return;
}
let client;
if (parsedUrl.protocol === "https:") {
client = https;
}
if (parsedUrl.protocol === "http:") {
client = http;
}
if (!client) {
resolve(defaultImage);
return;
}
client
.get(parsedUrl, function (res) {
const data = [];
res.on("error", function (err) {
console.error(
"Error during HTTP request",
err
);
resolve(defaultImage);
});
res.on("data", function (chunk) {
data.push(chunk);
}).on("end", function () {
resolve(Buffer.concat(data));
});
})
.on("error", () => {
resolve(defaultImage);
});
});
},
},
};
const content = fs.readFileSync("demo_template.docx");
const zip = new PizZip(content);
const doc = new Docxtemplater(zip, {
modules: [new HTMLModule(htmlOptions)],
});
doc.renderAsync({
html: '<img width="30" height="30" src="https://avatars3.githubusercontent.com/u/2071336?v=3&s=100"/>',
}).then(function () {
const buffer = doc.getZip().generate({
compression: "DEFLATE",
type: "nodebuffer",
});
fs.writeFileSync("demo_generated.docx", buffer);
});
By default, images use "inline-block", which means that you can insert multiple images in a given paragraph.
Images can also use the "block" mode, in that case only one image will be present per paragraph. Images can then be set to be left, right, or center aligned.
Center alignment :
const htmlOptions = {
styleSheet: `
img {
display: block;
margin-left: auto;
margin-right: auto;
width: 30px;
}
`,
};
const doc = new Docxtemplater(zip, {
modules: [new HTMLModule(htmlOptions)],
});
doc.render({ html: "<img src='.....'>" });
Left alignment :
const htmlOptions = {
styleSheet: `
img {
display: block;
margin-right: auto;
width: 30px;
}
`,
};
const doc = new Docxtemplater(zip, {
modules: [new HTMLModule(htmlOptions)],
});
doc.render({ html: "<img src='.....'>" });
Right alignment :
const htmlOptions = {
styleSheet: `
img {
display: block;
margin-left: auto;
width: 30px;
}
`,
};
const doc = new Docxtemplater(zip, {
modules: [new HTMLModule(htmlOptions)],
});
doc.render({ html: "<img src='.....'>" });
The dpi option will allow you to convert a pixel into one inch.
By default, the dpi is set to 75, which means that 75px will be converted to 1 inch.
In previous versions (3.31.x and earlier), the deviceWidth and getDxaWidth existed, but they now are ignored in favor of the dpi option.
For block elements (p
, h1
,h2
,h3
,h4
,h5
,h6
, ul
, ol
, and table
), it is now possible to customize the style of paragraphs. It can be used to customize them for example depending on the html class of that element.
const htmlOptions = {
elementCustomizer(element) {
if (
element.classNames.indexOf("my-heading-class") !==
-1 &&
element.name === "p"
) {
return { pStyle: "Heading" };
}
// element.part.value will be the string "html1" if the tag used is {~~html1}
},
};
const doc = new Docxtemplater(zip, {
modules: [new HTMLModule(htmlOptions)],
});
doc.render(data);
The following HTML :
<p>Paragraph</p>
<p class="my-heading-class">Paragraph - heading</p>
<p>Normal paragraph</p>
will have the second paragraph rendered by using the Heading type.
Of course, you can use any docx style that you have defined in your docx template.
It is possible to add CSS style using CSS selectors.
For example, if you want to change the font size with the CSS selector : h4, th p.important
const htmlOptions = {
elementCustomizer(element) {
if (element.matches("h4, th p.important")) {
return {
// htmlStyle must be valid CSS style
htmlStyle: "font-size: 30px;",
};
}
},
};
const doc = new Docxtemplater(zip, {
modules: [new HTMLModule(htmlOptions)],
});
doc.render(data);
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" |
It is possible to customize bullets with the elementCustomizer API
For example, you can write :
const htmlOptions = {
elementCustomizer(element) {
if (element.matches("ul")) {
return {
bullets: ["·", "-", "+"],
};
}
},
};
const doc = new Docxtemplater(zip, {
modules: [new HTMLModule(htmlOptions)],
});
doc.render(data);
It is also possible to customize the color, font and text with the elementCustomizer API :
const htmlOptions = {
elementCustomizer(element) {
if (element.matches("ul")) {
return {
bullets: [
{
text: " ",
font: "Wingdings",
color: "FF0000",
},
{
text: "-",
color: "00FF00",
},
{
text: "+",
size: 30,
color: "0000FF",
},
],
};
}
},
};
const doc = new Docxtemplater(zip, {
modules: [new HTMLModule(htmlOptions)],
});
doc.render(data);
Docxtemplater as such doesn't support the "list-style-position" attribute.
If you want to put the bullets aligned with the text (and not indented to the right), you have to use the following :
const htmlOptions = {
styleSheet: `
ul, ol {
margin-bottom: 0;
margin-top: 0;
padding-left: 0;
}
li {
margin-bottom: 0;
margin-top: 0;
}
ul li {
margin-left: 1em;
text-indent: -1em;
list-style-position: outside;
}
ol li {
margin-left: 1em;
text-indent: -1em;
list-style-position: outside;
}
`,
};
const doc = new Docxtemplater(zip, {
modules: [new HTMLModule(htmlOptions)],
});
doc.render({
html: `
<p>Hello</p>
<ol>
<li>L1</li>
<li>L2</li>
<li>L3</li>
</ol>
<ul>
<li>L1</li>
<li>L2</li>
<li>L3</li>
</ul>
`,
});
For tables, there is no difference between table-layout:fixed
and table-layout:auto
.
Also, unlike the auto
algorithm, the width of the column does not depend on the content of the table, but just on the width applied in the CSS style.
This means that if you want to have columns of different sizes in your generated document, you should specify the width in the first column on all tr
elements.
It is possible to use the break-after: page
or break-before: page
styles.
Here is an example :
const htmlOptions = {
styleSheet: `
.pba { break-after: page; }
.pbb { break-before: page; }
`,
};
const doc = new Docxtemplater(zip, {
modules: [new HTMLModule(htmlOptions)],
});
doc.render({
html: `<p>Hello</p>
<p class="pba">Hi</p>
<p class="pba">Hello</p>
<p>Bye</p>
<p>Bye</p>
<p>Bye</p>
<p>Bye</p>
<p class="pbb">Good bye</p>
`,
});
This will put a pagebreak after "Hi", after "Hello", and before "Good bye".
It is possible to include links using one simple tag using a label and url data, like this.
In your template :
Install following modules :
npm install --save lodash he angular-expressions
In your code, use the angular-parser and define a link filter.
const he = require("he");
const expressionParser = require("docxtemplater/expressions.js");
expressionParser.filters.link = function (url, label) {
// This condition should be used to make sure that if your url is
// undefined, your output will be undefined as well and will not
// throw an error
if (!url) {
return url;
}
return `<a href="${he.decode(url)}">${he.decode(label)}</a>`;
};
const doc = new Docxtemplater(zip, {
modules: [new HTMLModule()],
parser: expressionParser,
});
doc.render(data);
With the -xt-tab-stop
CSS property, which value can be tabstop
, it is now possible to add a tabstop to the paragraph of a Word document
const doc = new Docxtemplater(zip, {
modules: [
new HTMLModule({
ignoreUnknownTags: true,
styleSheet: `
t {
-xt-tab-stop: tabstop;
}
`,
}),
],
});
doc.render({ html: "<p>Hello<t/>Foo<t/>Bar</p>" });
Here is a list of properties that cannot be supported, and I explain a bit why :
display: inline-block;
or other "display" properties : In Word, everything is just simply a paragraph, or a table or an image (or some other things such as graphs, smartarts, …). And all these elements always behave like block elements. They can be positioned relatively, but inline-block, flex, grid, do not have any translation in the docx format. The only exception is for the <img>
tag which allows either display: block
or display: inline-block
.position: absolute;
or position: fixed
properties : There is no translation of this property into the docx format that would render anything near this.width
/height
on div elements : div's do not exist in the docx format as well, only paragraphs, tables, and images, and putting constraints on the width and height is not feasible except for tables and table cells.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.You might get the following error :
Since htmlparser2 version 8.x, the package.json of htmlparser2 defines multiple exports fields :
Webpack will by default use the "module" entry of the package.json : View htmlparser2 package.json on Github
This means that it will load the file from "lib/esm/index.js".
In your webpack configuration, you need to have the appropriate loader to be able to parse the "export" statement (and other ESM specific syntax)
You most probably currently have something like this in your webpack.config.js :
const config = {
loaders: [
{
test: /\.js$/,
loader: "babel",
exclude: /node_modules/,
query: {
presets: ["es2015", "stage-0"],
},
},
],
};
module.exports = config;
Instead you should rather use the include
property like this :
const path = require("path");
const config = {
loaders: [
{
test: /\.js$/,
loader: "babel",
include: [
/node_modules\/(htmlparser2)/,
path.join(__dirname, "./app"), // assuming that your config and app are in the same folder.
],
query: {
presets: ["es2015", "stage-0"],
},
},
],
};
module.exports = config;
This answer was inspired by this webpack issue.
The HTML module is forgiving : if an image cannot be parsed, the module will not crash. It will instead continue processing the rest of the HTML normally.
Since version 3.38.0 of the HTML module, if something in the HTML is off, the HTML module will call the warnFn
function, or by default, log the warning.
For example, if you try to include an image as base64 and the base64 is invalid, now the warnFn
will be called.
Example :
const doc = new Docxtemplater(zip, {
modules: [
new HTMLModule({
ignoreCssErrors: true,
// the styleSheet is invalid, it has only an opening tag
styleSheet: `
p {
`,
warnFn(errors) {
console.log("My errors :");
for (const error of errors) {
console.log(error.message);
}
},
}),
],
});
doc.render({
html: `<img src="data:image/webp;base64,UklGRhwDAABXRUJQVlA4WAoAAAAgAAAACQAACQAASUNDUKACAAAAAAKgbGNtcwQwAABtbnRyUkdCIFhZWiAH5wAHAAoACQAxABRhY3NwQVBQTAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9tYAAQAAAADTLWxjbXMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1kZXNjAAABIAAAAEBjcHJ0AAABYAAAADZ3dHB0AAABmAAAABRjaGFkAAABrAAAACxyWFlaAAAB2AAAABRiWFlaAAAB7AAAABRnWFlaAAACAAAAABRyVFJDAAACFAAAACBnVFJDAAACFAAAACBiVFJDAAACFAAAACBjaHJtAAACNAAAACRkbW5kAAACWAAAACRkbWRkAAACfAAAACRtbHVjAAAAAAAAAAEAAAAMZW5VUwAAACQAAAAcAEcASQBNAFAAIABiAHUAaQBsAHQALQBpAG4AIABzAFIARwBCbWx1YwAAAAAAAAABAAAADGVuVVMAAAAaAAAAHABQAHUAYgBsAGkAYwAgAEQAbwBtAGEAaQBuAABYWVogAAAAAAAA9tYAAQAAAADTLXNmMzIAAAAAAAEMQgAABd7///MlAAAHkwAA/ZD///uh///9ogAAA9wAAMBuWFlaIAAAAAAAAG+gAAA49QAAA5BYWVogAAAAAAAAJJ8AAA+EAAC2xFhZWiAAAAAAAABilwAAt4cAABjZcGFyYQAAAAAAAwAAAAJmZgAA8qcAAA1ZAAAT0AAACltjaHJtAAAAAAADAAAAAKPXAABUfAAATM0AAJmaAAAmZwAAD1xtbHVjAAAAAAAAAAEAAAAMZW5VUwAAAAgAAAAcAEcASQBNAFBtbHVjAAAAAAAAAAEAAAAMZW5VUwAAAAgAAAAcAHMAUgBHAEJWUDggVgAAAJACAJ0BKgoACgAAwBIlsAJ0ugH4AUYAC3ve1rUAAP72kROQfTn/HwYkM//0NVFtX+v8fKV/9sG3BvM23w+f7/9K+bmHirW/Pe/+eUk/WCfHX/+eKAAA">`,
});
This will show the two following warnings in the console :
It is possible to configure the HTML module to work when using tags with no prefix, as in the following template :
With following code :
const doc = new Docxtemplater({
paragraphLoop: true,
linebreaks: true,
modules: [new HTMLModule({ prefix: "" })],
// When you set the prefix to "~", the HTML inline tags will be : {~html}
// When you set the prefix to "*", the HTML inline tags will be : {*html}
// When you set the prefix to "", the HTML inline tags will be : {html}
});
doc.render({
name: "<b>John</b>",
});
Will render
Hello John
Will Render
It is possible to highlight tags that were not replaced.
The following template, when having no "age" property :
Will render :
Hello John, age {age}
function surroundHighlight(text) {
return `<mark>${surround(text)}</mark>`;
}
function surround(text) {
return `{${text}}`;
}
const doc = new Docxtemplater({
paragraphLoop: true,
linebreaks: true,
modules: [new HTMLModule({ prefix: "" })],
nullGetter(part) {
if (!part.module) {
return surround(part.value);
}
if (
part.module ===
"pro-xml-templating/html-module-inline"
) {
return surroundHighlight(`${part.value}`);
}
if (
part.module ===
"pro-xml-templating/html-module-block"
) {
return surroundHighlight(`~~${part.value}`);
}
if (part.module === "rawxml") {
return "";
}
return "";
},
});
doc.render({
first_name: "John",
});
It is possible to highlight all replaced tags.
The following template
Will render :
Hello John, age 12
Using following code :
const doc = new Docxtemplater({
paragraphLoop: true,
linebreaks: true,
modules: [
new HTMLModule({
prefix: "",
styleSheet: `
* {
background-color: yellow;
}
`,
}),
],
});
doc.render({
name: "John",
age: "12",
});
It is possible to use markdown instead of HTML in your data passed to docxtemplater using the marked library.
First install it with :
npm install marked
In your code, use a custom parser that will translate your markdown to HTML :
const { marked } = require("marked");
function parser(tag) {
return {
get(scope, context) {
let result;
// in our example above, scope is `{ "name": "John" }`
// because that is the data passed to docxtemplater
if (tag === ".") {
result = scope;
} else {
// return the property "name" of the scope object.
result = scope[tag];
}
if (
[
"pro-xml-templating/html-module-block",
"pro-xml-templating/html-module-inline",
].indexOf(context.meta.part.module) !== -1
) {
result = marked.parse(result.toString());
}
return result;
},
};
}
const doc = new Docxtemplater(zip, {
parser,
paragraphLoop: true,
linebreaks: true,
modules: [new HTMLModule()],
});
doc.render({
htmlDescription:
"Hello **John**, did you hear about [duckduckgo](https://ddg.gg) ?",
});
The HTML module does not use altchunks, because those do not support all kind of tags, and also, not all Word readers can read alt chunks (WPS Office, Google Docs, Libreoffice do not support altchunks.
This is why we've implemented our own conversion system, that really converts HTML into OpenXML.
Since version 3.54.0, it is possible to use the CSS property : break-inside:avoid
on <table>
elements in order to avoid breaking the page inside the table.
It is possible to specify that a table should not break across multiple pages using following setting (available since 3.49.1).
const doc = new Docxtemplater(zip, {
modules: [
new HTMLModule({
styleSheet: `
table {
break-inside: avoid;
}
`,
}),
],
});
doc.render({
html: `
${"<p>Hello</p>".repeat(15)}
<table>
${"<tr><td>Ho</td><td>Ho</td></tr>".repeat(20)}
</table>
`,
});
Improve warning message when using block tags such as <table>
or <p>
, inside inline tags {~html}
For example, the following will now be logged :
Warning parsing HTML content : In tag '{~html}', element '<p>' of type block is not allowed in inline tag, instead of {~~html}, use {~~html},In tag '{~html}', element '<table>' of type block is not allowed in inline tag, instead of {~~html}, use {~~html},In tag '{~html}', element '<tr>' of type block is not allowed in inline tag, instead of {~~html}, use {~~html},In tag '{~html}', element '<td>' of type block is not allowed in inline tag, instead of {~~html}, use {~~html}
This means that if you use a <table>
tag, you should be using a block tag, ie {~~html}
.
The italic tag now creates both <w:i/>
and <w:iCs/>
. This is because some software (PDFTron) doesn't respect the italic setting if using just <w:i/>
.
When setting the "blockPrefix" and the "prefix" to "", the library will now automatically use docxtemplater html block tags or docxtemplater html inline tags depending on whether there is some other content in the same paragraph.
This allows to write all HTML tags with just {name}, by using following configuration :
const htmlOptions = {
prefix: "",
blockPrefix: "",
};
const doc = new Docxtemplater(zip, {
modules: [new HTMLModule(htmlOptions)],
});
doc.render({
html: "Text",
});
Bugfix issue when having
tag right before a font tag, like this :
<p>
<font>
<font>
XX
</font>
</font>
<br>
<font>
<font>
XX
</font>
</font>
</p>
The br tag would in this case be ignored
Add support for <font color="713ffe">
tag. Previously, using a font tag caused an error.
Add support for break-inside: avoid;
on tables (which uses keepNext setting).
Update default warnFn to avoid showing duplicated errors.
Add support for async mode when using img.getSrcSize
.
When using lists (ordered or unordered lists), the paragraph style of the HTML tag will now be kept if it exists.
Previously, the pstyle called "TextBody" was always used, which is incorret.
The module now also apply the <w:keepNext>
parameter on list items if it is set.
If the text that contains the {~~html}
tag has the following set as a run property : <w:spacing w:after="200" w:before="0">
, this value will be used as the default value for spacing for paragraphs, lists, and all other tags.
Add support for margin-top
and margin-bottom
on list containers (<ul>
and <ol>
).
Add support for padding-top
and padding-bottom
on paragraphs.
Correctly handle <ins>
and <del>
around <ul>
and <ol>
The following will now work correctly :
<del>
<ul>
<li>List which is deleted</li>
</ul>
</del>
<ins>
<ul>
<li>List which is inserted</li>
</ul>
</ins>
Previously the "underline" or the "strikethrough" would be ignored in this case.
Bugfix to work correctly with *
selector even on block tags.
The following will work :
const htmlOptions = {
styleSheet: `
* {
color: blue;
}
`,
};
const doc = new Docxtemplater(zip, {
modules: [new HTMLModule(htmlOptions)],
});
doc.render({
html: "Text",
});
Make it possible to use prefix from the constructor
Add typescript typings to be able to change the module prefix
Bugfix to improve keepNext support (added in 3.49.1)
Even when having empty cells, keepNext is still applied.
The following code previously did not apply keepNext to empty cells, but now iit works :
const doc = new Docxtemplater(zip, {
modules: [
new HTMLModule({
elementCustomizer(element) {
// note that you could also add a more complex CSS selector, such as td.keepnext
if (element.matches("td")) {
return { keepNext: true };
}
},
}),
],
});
doc.render({
html: ` <p>Hello</p>
<table>
<tr>
<td>Title1</td>
<td>Title2</td>
</tr>
<tr>
<td></td>
<td>
</td>
</tr>
<tr>
<td>C1</td>
<td>C2</td>
</tr>
</table>`,
});
Add support for setting keepNext
to be able to avoid breaking pages in a table or in a group of paragraphs.
Add support for :
<center>
tag to place a paragraph to the center<template>
tag to ignore some part of the HTML<p hidden>Hidden</p>
to hide a given elementBugfix when having multiple colspan, like this :
<table border="1">
<tbody>
<tr>
<td colspan='8'>ABC</td>
</tr>
<tr>
<td colspan='8'>DEF</td>
</tr>
<tr>
<td colspan='4'>GHI</td>
<td colspan='4'>KLM</td>
</tr>
</tbody>
</table>
Previously, some cells would have a width of 0, which meant that some cells were completly hidden.
Now, the cells width are equally distributed in this case.
Make it possible to use block images and align the image to the left or to the right.
In order to do this (align to the right), you have to use the following in your code :
const htmlOptions = {
styleSheet: `
img {
display: block;
margin-left: auto;
width: 30px;
}
`,
};
const doc = new Docxtemplater(zip, {
modules: [new HTMLModule(htmlOptions)],
});
doc.render({ html: "<img src='.....'>" });
You can align to the left with the following styleSheet :
const htmlOptions = {
styleSheet: `
img {
display: block;
margin-right: auto;
width: 30px;
}
`,
};
const doc = new Docxtemplater(zip, {
modules: [new HTMLModule(htmlOptions)],
});
doc.render({ html: "<img src='.....'>" });
Add support for text-transform: uppercase
.
Also, when using font-variant: normal
, both small caps and all caps style will be overwritten correctly (previously only small caps was overwritten).
Add containerType
key to each part, which contains one of the following string :
Correctly calculate the width of each table cell, even when using colGrid and when having merged cells.
Allow to customize tblStyle from styleTransformer :
const htmlOptions = {
styleTransformer(tags) {
tags.table.data.tblStyle = ["TableGrid1"];
return tags;
},
};
const doc = new Docxtemplater(zip, {
modules: [new HTMLModule(htmlOptions)],
});
doc.render(/* data */);
Note that this will change the tblStyle for each table.
It is also possible to match a class by using the more powerful elementCustomizer method :
const htmlOptions = {
elementCustomizer({ classNames, name }) {
if (
classNames.indexOf("newtable") !== -1 &&
name === "table"
) {
return {
tblStyle: "Grid1",
};
}
},
};
const doc = new Docxtemplater(zip, {
modules: [new HTMLModule(htmlOptions)],
});
doc.render(/* data */);
Should be handled when some other text is present in the paragraph.
See this Create React App issue and this @adobe/css-tools issue.
line-height
attribute on a paragraph that has no pStyle (this now uses the "w:docDefaults" default font size.Add support for <figure>
and <figcaption>
tag (which renders exactly like a div).
Add support for <hr>
tag.
Allow to set props in styleTransformer
, to create new tags, such as this :
const htmlOptions = {
styleTransformer(tags) {
tags.highlight = {
type: "inline",
data: {
props: [
{
type: "string",
tag: "w:b",
value: "<w:b/>",
},
{
type: "string",
tag: "w:highlight",
value: '<w:highlight w:val="yellow"/>',
},
],
},
};
return tags;
},
};
Allow to create customTag and render all children using handleChildren
.
Add support for <mark>
tag (for highlighting text in yellow).
Add support for "customTags" API to create new handlers for some HTML tags.
Avoid stacktrace if setting line-height to 0, like this :
doc.render({
html: '<p style="line-height: 0">Test</p>',
});
The following error was thrown previously :
Now, the document will be generated with a small line-height in this case.
On some versions of Word (on the Microsoft Word version in Windows), following "border"-like elements would sometimes appear :
(See lines between x-A-B,D-E)
This was happening when using the padding property.
This issue should no more occur again.
Bugfix issue with line-height when using font-size in rem, like in this example :
doc.render({
html: '<p style="font-size: 2rem; line-height: 1.4">Test</p>',
});
The following stacktrace was shown :
Now the document is rendered correctly.
More generally, support for the units "rem" and "em" has been added.
Also, support for the "%" unit on font-size has been added, like in this example :
doc.render({
html: '<p style="font-size: 30px;">30-<span style="font-size: 50%;">15</span></p>',
});
Upgrade module to use NodeNext moduleResolution setting. See explanation here
Bugfix issue when using a document that contains a <w:sectPrChange>
(which is a tracked "section" change, ie a tracked "header" or "footer" change :
Use new resolvedId
API => requires docxtemplater@3.43.0
Bugfix when using pagebreak before inside div, like this :
doc.render({
html: `
<div>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
</p>
<p style='break-before: page'>
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
</p>
<p>
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
</p>
<p>
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>
<p>
Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo.
</p>
</div>`,
});
Previously, all paragraphs would have the break-before page propert set.
Now, only the correct paragraph has that property set.
When using styleSheet option with "inline" tag, such as {~html}
, the following stylesheet would not correctly apply.
const htmlOptions = {
styleSheet: `
* {
color: red;
}
`,
};
const doc = new Docxtemplater(zip, {
modules: [new HTMLModule(htmlOptions)],
});
doc.render({ html: "My Text" });
Now, even in inline mode, simple text will use the style defined by the *
selector.
Add support for changing font-variant
(to set some text to be in "small-caps").
Like this :
const htmlOptions = {
styleSheet: `
* {
font-variant: small-caps;
}
`,
};
const doc = new Docxtemplater(zip, {
modules: [new HTMLModule(htmlOptions)],
});
doc.render({
html: "<span>Foobar</span>",
});
This also allows to remove the "small-caps" variant by using * { font-variant: normal; }
.
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
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
Multiple bugfixes when used in async mode (for some templates/data only) :
Avoid corruption because of duplicate link to "numbering.xml".
This issue would appear only in certain cases on certain particular word versions.
It would appear if your template contained list items, and the HTML data also contained list items.
When having following HTML :
<ol>
<li style="font-size: 40px;">Big list</li>
<li style="font-size: 8px;">Small list</li>
</ol>
In previous versions, the bullet was not resized in the resulting docx.
Now, the bullet (or numbering element) will also be resized, not just the text in the list item.
This also works now with other run properties such as text color, italic, bold, …
Make html module compatible with the image module version 3.23.6
If you don't upgrade your HTML module to 3.41.3, you will see that images are missing when you use the <img>
tag
Add support for nth-child(3n+1)
, and nth-child(0n+3)
and nth-child(-n+3)
.
Add correct support for nth-child(even) and nth-chld(odd).
Correctly inherit background-color from thead into td.
Add correct support for line-height
Previously there was a bug : line-height was working only when also setting the margin-top or margin-bottom property.
Now, the line-height alsow works with percentages or numbers (acts as multiplier to the fontsize), as in :
p {
line-height: 200%;
line-height: 1.3;
line-height: 20pt;
font-size: 12px;
}
Correctly calculate pageHeight by removing marginTop and marginBottom
Add pageWidth
This release needs version 3.40.1 of docxtemplater open-source.
When the docx document is the following
The pageHeight was not correctly added to the "part".
Now, the pageHeight should always be present, inside loops, outside loops, and in async and sync mode.
Add correct typings for part.section
Add support for text-align: justify
on <li>
elements.
Add support to retrieve the pageHeight
of the section that contains the current tag.
(The value is in pixels)
const imageOptions = {
// getImage: as usual
getSize(img, value, tagName, context) {
const pageHeight = context.part.pageHeight;
console.log(pageHeight); // will log 1112
return [100, 100];
// or return anything you like
},
};
It is also now possible to view the context.part.section
for more information about the current section (number of columns, …).
Bugfix when using following HTML :
doc.render({
html: '<h2><strong style="color: rgb(0, 0, 0); background-color: transparent;">General</strong></h2>',
});
Previously, the background was rendered to black in this case.
Add customization to be able to remove list style, when using the following template for example :
With following code :
const doc = new Docxtemplater(zip, {
modules: [
new HTMLModule({
elementCustomizer(element) {
if (element.matches("td")) {
return { resetList: true };
}
},
}),
],
});
doc.render({
html: "<table><tr><td>Foobar</td></tr></table>",
});
This will now output a table without any list items
Update module.clone() internal to make module work well with subsegment module (passthrough module.prefix)
Add support for list-style: none
to completely hide bullets.
Add correct typescript typings for element.parsedStyle.
const htmlOptions = {
getProps({ element }) {
// the parsedStyle has following shape :
element.parsedStyle = [
{
property: "width",
value: "100px",
},
{
property: "text-align",
value: "center",
},
];
},
};
Bugfix : Correctly calculate "parsedStyle" inside "getSize" function of image module even in async mode.
Correctly render <ol>
when tag is present inside a list, even when the list is referenced by a pStyle.
Now the HTML will keep the existing style
Remove css dependency which is no more updated since 2020.
We replace it by @adobe/css-tools which gets regular updates.
Add support to have a shape that contains some drawing + HTML inside the shape.
Previously, if the shape contained {~~html}
,
Then the result would contain the string "~~html", followed by the rendered value of the html
Now, the string "~~html" is no more present in the output.
Add support for percent values in colgroup, like this :
<table>
<colgroup>
<col style="width: 25.9%;" />
<col style="width: 74.1%;" />
</colgroup>
<tbody>
<tr>
<td>A</td>
<td>B</td>
</tr>
</tbody>
</table>
Show warning if using element of type <table>
, or of type block (<p>
, <h1>
, …) inside an inline HTML tag such as {~html}
.
You have to use block html tags : {~~html}
to include block elements.
Do not throw Error when having "colgroup" tag inside "inline" element : {~inline}
Add support for passing array of strings to the HTMLModule.
const doc = new Docxtemplater(zip, {
modules: [new HTMLModule({})],
});
doc.render({
html: [
`
<p>Foobar</p>
`,
`
<p>Foobar</p>
`,
],
});
This allows to simplify the template in some cases from :
into :
Add support for CSS specificity.
Now, style rules will follow CSS specificity : #id
is more specific to .class
, and .class
is more specific than p
, so the rules are applied in the same order than in browsers now.
Add support for break-after: avoid;
This can be used to make sure that multiple paragraphs of text will be kept on the same page. Thus the Word engine will break in order to keep the paragraphs together.
One common use case would be to write the following :
const doc = new Docxtemplater(zip, {
modules: [
new HTMLModule({
styleSheet: `
p, h1 { break-after: avoid; }
p:last-child { break-after: unset; }
`,
}),
],
});
doc.render({
html: `
<p>Foobar</p>
<p>Foobar</p>
<p>Foobar</p>
<p>Foobar</p>
`,
});
Add warnFn to be able to catch warnings.
The HTML module is like HTML in the real world : forgiving.
Now, it is possible to catch warnings in a warning function, and by default warnings will be printed to the console using console.error();
Bugfix when using following template :
The following error would be thrown when using the angular expressions parser :
Bugfix when having the following HTML :
<table style="width:100%;border-style:none;break-after:page">
<thead>
<tr style="background-color:#0057ab;color:white">
<th>Bang</th>
</tr>
</thead>
</table>
Previously, this would throw the following error :
Now, the break-after:page
property is properly parsed.
Allow HTML data to be an integer (it will then be autoconverted into a string).
When the HTML data is not a string nor an integer, it will now error and show the type of the passed object ("Object", "Promise", "Array", …)
(This improves a change that was added in 3.37.4).
The message will now be, for example :
If you get this message with type Promise, it probably means that you should be using "doc.renderAsync()" instead of doc.render()
, see this page for docs about async mode.
If you get this message with some other type, check your dataset, or the expressionFilters that you have defined, they are probably returning an object instead of a string.
Take into account max-width
of table even when using colGroup. Take into account width
of table even when using colGroup.
Throw specific error if the data passed to the HTML module is not a string.
Previously, with following code :
const doc = new Docxtemplater(zip, {
modules: [new HTMLModule()],
});
doc.render({
html: { foo: "bar" },
});
The stacktrace would be :
Bugfix, to make it possible to customize getProps of the image module when used together with the HTML module.
This release also needs version Image module 3.21.1 or later
Call nullGetter function if the resolved value is null.
This allows to set some default value for the HTML tags if the value is null.
Make list items : <li> <ol> <ul>
work correctly for dotx
templates and other less common : docm
, …
It is now possible to add a tabstop using the "-xt-tab-stop" CSS property, see sample code in the Docs.
Fix a corruption that would happen when using a table with the vertical-align: inherit
property.
Now the document is no more corrupt.
Bugfix a corruption that would happen when placing an HTML tag in the header of a document.
Previously, the image would become corrupt.
Now, the image is correctly kept.
When writing {~~html} inside a bullet list, the generated paragraph will use the bullet list.
Bugfix to avoid corruption when having textbox with image on the same paragraph as some HTML data
Add support for setting the pStyle for block images, using the following code :
const doc = new Docxtemplater(zip, {
modules: [
new HTMLModule({
elementCustomizer(element) {
if (element.name === "img") {
return {
pStyle: "Image",
};
}
},
}),
],
});
doc.render(data);
Correctly work if using img.getValue function that returns null : in this case, the module will not return a <w:r></w:r>
, but instead it will return ""
Bugfix when using the following code :
const doc = new Docxtemplater(zip, {
modules: [
new HTMLModule({
elementCustomizer({ name }) {
if (name === "li") {
return {
pStyle: "Heading1",
};
}
},
}),
],
});
doc.render({
html: `
<ul>
<li style="margin: 0;">HiHo</li>
<li style="margin-top: 0; margin-bottom: 0px;">HiHo</li>
<li style="margin-top: 0px; margin-bottom: 0px;">HiHo</li>
</ul>
`,
});
This was failing with following stacktrace :
Now the document is generated correctly
Bugfix when input docx did not contain any "word/styles.xml" file, the following stacktrace was shown :
Now, the docx file is generated without any Error
Add support for colgroup tag to define width of table.
Bugfix to work correctly with files that have tp/document-orig.xml
.
Requires version 3.34.0 of docxtemplater core
Bugfix to avoid adding styles with w:default="1"
.
Fix getSize
function to call it with 4 parameters instead of one.
Add support for <span style="white-space:pre">Hello Foo</span>
Bugfix of duplicate decoding of string.
When passing following data :
const html = "<p>&lt;</p>";
doc.render({ html });
The following would be shown in the template <
, but this should instead show <
.
Remove deviceWidth
option.
If you were not using the deviceWidth
option or the getDxaWidth
, then this change won't affect you.
Instead, you should now use the dpi
option.
The default deviceWidth was previously : 470.10416666666663
The now default dpi is now 75
.
If you were previously setting the deviceWidth to 1000, than, to calculate, the dpi, you have to use the formula : dpi = deviceWidth / 470.10416666666663 * 75
.
For example, here are the deviceWidth to dpi mapping
deviceWidth = 1000 => dpi = 159.53
deviceWidth = 750 => dpi = 119.65
deviceWidth = 500 => dpi = 79.76
Allow to set the size of checkboxes using following style :
doc.render({
html: `<input type="checkbox" style="height: 7px; width: 7px;" />`,
});
Keep existing text boxes that are contained in paragraphs that contain an {~~html} tag.
Previously such templates would fail with the following error :
This also means that in that particular case, the paragraph will be kept if the HTML data value is empty.
Avoid possible issue of "Maximum call stack size exceeded"
Simplify internal generation of lists.
Improve support for nested lists together with divs.
Even li>div>div>ol
should work correctly now.
<div>
testing list
<ol>
<li>
<div>first level</div>
<div>
<div>
<ol>
<li>
<div>second level</div>
<div>
<ol>
<li>
<div>third level</div>
</li>
</ol>
</div>
</li>
</ol>
</div>
</div>
</li>
</ol>
</div>
Improve support for setting tableStyle of a table.
When using the tableStyle option, now the colors of the used table will be correctly copied from word/styles.xml, taking into account the "firstRow", "lastRow", "firstCol", …
Avoid corruption when having a <table>
tag inside a Word table that results in a width of 0 in async mode, which corrupts the document
Fix error when using a loop that contains some inline HTML tag.
This would fail when using the following template (on some occasions when the tag was written in the same run, <w:r>
) :
{#html}The html is {~html}{/}
Bugfix to take into account img { display: block; margin:auto; }
when using docxtemplater in async mode.
Avoid corruption when using img { display: block; margin:auto; }
with images inside <li>
elements.
See : Github Issue #655
Now, <img>
tags that are inside <li>
tags will always be rendered as "inline-block" elements.
Bugfix to stop adding empty paragraphs after tables.
Please update the main docxtemplater library to 3.29.4 to fix this problem correctly
Do not add an empty paragraph after each <table>
Make it possible to specify table { margin-bottom: 20px; }
to add a margin after tables.
Bugfix to make it possible to have a Promise returned in the getSize function.
Previously the message shown was :
"Uncaught (in promise) Error: Size for image is not valid (it should be an
array of two numbers, such as [ 1024, 1024 ])
Improve typescript definitions
Bugfix corruption when having one column with fixed width, and 3 columns with auto width.
Bugfix to use the synonym of "Heading1" style if the synonym exists.
Bugfix when using a dotx template and using a table.
The table would appear as zero-width, which would cause a corruption.
Now the template is handled correctly.
Bugfix to take into account border="0"
property in table, like this :
<table border="0">
<tr>
<td>Table with no borders</td>
</tr>
</table>
Make package size smaller
Bugfix corrupt document when adding HTML link inside header
Avoid using styles that reference non-existing styles
Make module compatible with docxtemplater@3.28.0. Please make sure to update docxtemplater to 3.28.0 at the same time you update this module. The internal change made is the use of the new matchers API which fixes bugs that were triggered depending on the order of the modules that are attached to the instance. Now the order of the modules should not matter as expected.
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
Add support for <table align="right">
. It is also possible to use <table style="margin-left: auto">
to align a table to the right.
Add support for bordercolor attribute on <table bordercolor="#bbb">
.
Add support for cellpadding attribute on <table cellpadding="5">
.
Make img.getValue optional, even when running docxtemplater in async mode.
Update typing to allow ArrayBuffer or Promise
Update typing files to add types for using together with image module, with
const htmlOptions = {
ignoreUnknownTags: true,
img: {
Module: ImageModule,
getValue() {
return Promise.resolve(Buffer.from("hhh"));
},
getSize() {
return [100, 100];
},
},
};
const doc = new Docxtemplater(zip, {
modules: [new HTMLModule(htmlOptions)],
});
doc.render(data);
Add internal clone method (to use image tags with the Subtemplate.Segment module)
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/html-module.js
The .min.js file is also created now.
Add support for <ol start="3"><li>An item</li></ol>
to start the list items at a different position, to render :
Add support for images without src when using following CSS :
img {
display: block;
margin: auto;
}
Previously this would result in a corrupt document
Add support for setting the prefix to an empty string (to be able to replace normal tags by inline HTML).
To change the prefix for block tags, one will have to change the prefix like this :
For example to use {!!html}
for block html, and {tag} for inline html :
function getHTMLModule() {
const htmlModule = new HTMLModule();
htmlModule.prefix = "";
htmlModule.blockPrefix = "!!";
return htmlModule;
}
const doc = new Docxtemplater(zip, {
modules: [getHTMLModule()],
});
doc.render(data);
Add support for centering images in the output word document.
To use it, you need to add following styleSheet :
const doc = new Docxtemplater(zip, {
modules: [
new HTMLModule({
styleSheet: `
img {
display: block;
margin:auto;
}
`,
}),
],
});
doc.render(data);
Add typescript definitions for public API
Improve support for columns width, so that tables inside columns which are of unequal width will render correctly.
For example, if you have a document with two columns, one of width of 2/3 of the document, and an other one of 1/3 of the document width, a table with width of 100% will be calculated correctly.
Previously, the width would be in this case always splitted equally, so you would have a smaller table on the column with 2/3 of the space.
Move webpack from dependency to devDependency (which triggered an error during installation on node version 10)
Bugfix issue when using "text-align: right", on a table cell, where the {~~html} tag was explicitly left-aligned.
Now, the text-alignment from the HTML style will take precedence and show the text aligned correctly.
Add support for table-layout: fixed;
CSS property (which translates to <w:tblLayout w:type="fixed"/>
)
Add support to customize pStyle for <pre>
tags, for example
const htmlOptions = {};
htmlOptions.elementCustomizer = function (element) {
if (element.name === "pre") {
return { pStyle: "Code" };
}
};
const doc = new Docxtemplater(zip, {
modules: [new HTMLModule(htmlOptions)],
});
doc.render({
html: `<pre>Hello from
pre tag</pre>`,
});
Add support for repeatHeaderRow and cantSplit on table row elements with elementCustomizer
For example, you can now do :
const htmlOptions = {};
htmlOptions.elementCustomizer = function (element) {
if (element.matches("tr.header")) {
return {
cantSplit: true,
repeatHeaderRow: true,
};
}
if (element.matches("tr")) {
return {
cantSplit: true,
};
}
};
const doc = new Docxtemplater(zip, {
modules: [new HTMLModule(htmlOptions)],
});
doc.render({
html: `
<tr class="header">
<td>Head1</td>
<td>Head2</td>
</tr>
<tr class="header">
<td>Head3</td>
<td>Head4</td>
</tr>
<tr><td>Some Text</td><td>Other Text</td></tr>
....
....
<tr><td>Some Text</td><td>Other Text</td></tr>
`,
});
And this will set the two header table rows to be repeated across each page when the table overflows. The cantSplit property can also be used to avoid the table row to be splitted between two pages.
Add support for <ol type="I">
to show ordered lists with uppercase roman numbers.
Here are the possible types :
type="1"
The list items will be numbered with numbers (default)type="A"
The list items will be numbered with uppercase letterstype="a"
The list items will be numbered with lowercase letterstype="I"
The list items will be numbered with uppercase roman numberstype="i"
The list items will be numbered with lowercase roman numbersAdd support for style list-style-type
and list-style
, to use CSS to customize numbering.
For example :
const htmlOptions = {
styleSheet: `
ol {
list-style-type: upper-alpha;
}
ol.roman {
list-style: upper-roman;
}
`,
};
const doc = new Docxtemplater(zip, {
modules: [new HTMLModule(htmlOptions)],
});
doc.render(data);
The list of possible values are : decimal-leading-zero, decimal, lower-alpha, lower-latin, upper-alpha, upper-latin, lower-roman, upper-roman
Add support for background-color on table element (previously it could only be set on tr or td)
Add support to customize bullet colors and font-family using elementCustomizer
Add support to customize li pStyle using elementCustomizer
To use this version with the image-module, you need to use the image-module version 3.8.4
Allow to retrieve containerWidth in getSize
function when using <img>
tags.
For example :
const ImageModule = require("docxtemplater-image-module");
const htmlOptions = {
img: {
Module: ImageModule,
getSize({ part }) {
return [
part.containerWidth || 100,
part.containerWidth || 100,
];
},
},
};
const doc = new Docxtemplater(zip, {
modules: [new HTMLModule(htmlOptions)],
});
doc.render({ html: "<b>Hello</b>, Foo !" });
This allows to for example show all images as being the size of the container (most commonly, the size of the page, except when the HTML tag is inside a table).
Allow to have comments in stylesheets
Bugfix to take into account "border:none" on <table>
elements
Correctly keep <w:rtl>
tag in order to allow to insert "right-to-left" languages such as Hebrew, Arabic, Urdu, …
Add support for <style>
tag inside HTML tags
Disallow to pass something other than a string to the stylesheet option (because this option only allows to pass a given global stylesheet)
Bugfix, when having text surrounding the HTML inline tag, such as in :
Hello {~name}, how are you ?
The HTML module would sometimes misplace the replacement of {~name} and put it at the end of the paragraph.
Now, the module correctly puts the replacement at the correct position.
Use w:lineRule="exact"
when using CSS line-height
Add support for line-height
attribute.
Improvements for cell widths. Now, when you declare only the widths of td (without defining the width of the table itself), the cell widths will be correct (the table width will be the sum of all cell widths).
For example : this will work :
const htmlOptions = {
styleSheet: `
td {
width: 50px;
}
`,
};
const doc = new Docxtemplater(zip, {
modules: [new HTMLModule(htmlOptions)],
});
doc.render(data);
Previously, this would result in having a default table width of 450px, and scaling of the cell widths.
Bugfix when having <br>
in "implicit paragraph", for example in :
<h1>Hello</h1>
<br />
<h1>Hello</h1>
<br />
<h1>Hello</h1>
In previous versions, this would render two empty paragraphs between each title, now it correctly renders only one
Avoid importing unused styles, such as :
"Heading Car" "Heading 1 Car" "Heading 2 Car" "Citation Car"
Those styles are now imported only if the corresponding style does not exist in the templated document.
Add support for :
<table>
that contains some empty <tr>
elements (it would generate a corrupt document)<input type="text">
<form>
tag (no specific style currently)<textarea>
tag (no specific style currently)<button>
tag (no specific style currently)<label>
tag (no specific style currently)Fix issue with css module :
Now, the module requires only the part that it uses, which removes this error.
Add support for "dotted" border-style.
Add support for border-style with multiple values (one to four values)
Bugfix to ignore <br>
at the end of block elements.
Bugfix support for border styles, such as border: 1px dashed black;
List of handled styles : solid, dashed, double, outset, none, inset
Add third argument to styleTransformer() containing styleIds of the current document.
Bugfix to render space in inline HTML tag when using : <b>Foo</b> <i>Bar</i>
Fix error when using <img>
tag without any src. The error message was TypeError: Cannot read property 'replace' of undefined at base64DataURLToArrayBuffer
. Now, those images are ignored but do not fail with an error.
Improve table border support :
Add support for border-width
property on border
Add support to change default for table borders with elementCustomizer, for example :
const htmlOptions = {
elementCustomizer({ name }) {
if (name === "table") {
return {
tblStyle: "TableauNormal",
defaultBorder: null,
};
}
},
};
const doc = new Docxtemplater(zip, {
modules: [new HTMLModule(htmlOptions)],
});
doc.render(/* data */);
This makes it possible to use border style defined in the Word style.
Add support for <ins>
and <del>
tags (which will render underline and striked text)
Do not produce corrupt output when having either :
Tr element without any child : <table><tr></tr></table>
Table element without any child : <table></table>
Instead, the table will not be shown at all.
Correctly ignore width='0'
on <table>
element.
Do not render newline when it is at the end of a <li>
element, for example, in :
<ul>
<li>Hello<br /></li>
<li>Hello<br /></li>
</ul>
Render text that is inside an <ul>
even if it is not in a ul.
In previous versions, the tag <ul>Hello</ul>
would produce an empty paragraph. Now it will render a paragraph with the word "Hello".
Add support for "padding" property.
Previously, only "padding-left", "padding-right", "padding-top" and "padding-top" were working, but not she shorthand padding: 0
property for example.
For table cell margins, support all common units (not just px
unit).
Make it possible to specify margin: 0
(or margin-left: 0
) on table element. (It was ignored in previous versions)
Return an empty paragraph when using <p><br></p>
instead of having a two-line paragraph
Bugfix Cannot read property 'getElementsByTagName' of undefined
at addRelationship (es6/relation-utils.js:25:32)
when using docx file saved from the online office 365 web app.
Add styleIds to elementCustomizer API to be able to know which styles are defined in the document when changing pStyle.
Remove tableRatio option (you should use deviceWidth instead)
Add support for "cm", "in", "mm", "pc", "pt" for all measurements
Bugfix do not produce a corrupt document when having escape codes such as an "escape character" (String.fromCharCode(27)
). These characters are now ignored, like what a real browser does.
Add support for pt unit in font-size, for example : font-size: 15pt
The pt
unit is for now not supported on all measures however.
Declare supportedFileTypes, which allows to use this module with the new docxtemplater constructor which was introduced in docxtemplater 3.17.
Add element.parsedStyle
which contains the parsed CSS style for usage in getSize of image module
Add support for text-indent
to indent first line of a paragraph.
Bugfix : Do not fail if using more list levels than are defined in pStyle.
For example :
const htmlOptions = {
styleTransformer: (tags, docStyles) => {
tags.ul.data.pStyle = ["bulletLevel1"];
tags.ul.data.useNumPr = false;
return tags;
},
};
const doc = new Docxtemplater(zip, {
modules: [new HTMLModule(htmlOptions)],
});
doc.render(/* data */);
will use bulletLevel1
for each level of bullets.
Previously, this was failing with the following error code :
TypeError: Cannot read property 'oneOf' of undefined
Bugfix : Previously, when having text just before an inline HTML tag, like in :
Hello{~inlineHTML}
The text Hello was removed from the output.
This is no longer the case, the text on the left and on the right of the inline tag will be kept.
If using ignoreUnknownTags to true, hide images instead of throwing an error.
Add support for caption on images when using the image module version 3.7.0 or above.
The runProperties (w:rPr
) used where the first encountered, instead of using the one inside the run itself (w:r
).
For table
tag, when the {~~htmlTag} is inside a multi-column session, the width:"100%"
will use the width of one column instead of the width of one page.
Add support for margin-left
on paragraphs
Add support for font-family
in CSS
Add support for break-after: page
and break-before: page
in CSS
Add support for <pre>
tag
Make it possible to have width: 100%
for images inside tables
Fix the calculation of width for images so that a table with a width of 200px shows the same width as an image with width of 200px. Before this release, the images were smaller than expected.
Keep paragraph style including indents and alignment
Add support for pt
values on table width
Add support for margin: 0
(without any unit)
Add support for colspan + rowspan on the same cell.
Multiple improvements for rowspan
Add support for Right-To-Left support with w:bidi
tag.
Add support for margin-top and margin-bottom on li tags
Bugfix corrupted document when using margin-top or margin-bottom
Add support for margin-top and margin-bottom on paragraphs
Bugfix spacing in li :
<p>
<ul>
<li><em>Lorem ipsum dolor si amet</em> <strong>Test</strong></li>
</ul>
</p>
The space will now be correctly rendered
Bugfix : support vertical-align: middle;
for td
Add initial support for rowspan on table td
Bugfix of propagation of style to all paragraphs.
For example, when having :
<div>
<p>Uncentered</p>
<p style="text-align:center">Centered</p>
</div>
The first paragraph was centered even if it should not.
Bugfix to avoid Cannot read property 'concat' of undefined"
when defining styles on some elements (such as th).
Always generate output with w:sz as integer (instead of float) by using Math.round
Add support for td { width: 20% }
in CSS
Bugfix issue of width of all cols being smaller than width of whole table
Add support for :
:first-child
, :last-child
, :nth-child(3)
selectorsborder-left
, border-top
, border-right
and border-bottom
on td and th for tablestext-align:center
on th/tdborder-style
double propertyBugfix for "Cannot read property 'getAttribute' of undefined" when having styles without names.
Bugfix [object Object]
shown when using async mode (resolveData
) with null value
Bugfix corrupt document when having empty w:sdtContent
Add support for async image generation
Keep fontFamily if set in run properties
Do not corrupt document if having empty value in block html inside table cell
Do not fail if they are no sections at all in the document (return a default size).
Bugfix corrupt document when using table colspan with just one row.
margin: 0 auto;
Inherit paragraph properties inside tables.
Improve list support when ul
is a direct child of ol
or or
is a direct child of ul
.
Add the style (run properties) of the {~~htmlTag}
to bullet points so that the bullet points have the same size as the text
font-weight:bold
of font-weight:700
styleSheet
option in module constructormargin-left
on ul
and ol
Better support for ul and ol : when using ols inside uls, if the TextBody
style did not exist, the ul and ol style were missing bullets.
Add way to customize bullets in the elementCustomizer API
Update html-parser require calls to work well with Rollup
Improve table support (background && background-color, color, font-size.
Do not duplicate runProps anymore
Add support for inline and block <code>
tags
Update to support the new image module v3.4.2
Update to support new image module with <svgs>
(3.4.1 of the image-module)
Add support for <a name="mark"></a>
to generate docx bookmarks
Add support for <a href="#mark">Go to mark</a>
and <p id="mark">Mark</p>
by using docx bookmarks
Links with no content are now hidden from the generated document (ignored)
Add two additional options for determining the meaning of 1 pixel.
The deviceWidth
option explicitly permits to say that you want to have a window of for example 1200 pixels.
The getDxaWidth
option to select how many dxas (20th of a point, or 1440 of an inch) your page is.
With these two options, docxtemplater can then accordingly convert any pixel value to a coherent size in your word document.
Add support for setting properties on multiple levels of divs/blockquotes or any block element.
For example :
<div style="text-align: justify;">
<blockquote>
Sit aliquid vitae non magni ex Eius saepe molestias
minima non tempore amet! Accusamus corrupti at ipsa
necessitatibus consequatur. Corporis autem debitis
reiciendis illo modi, inventore. Delectus magni sint
doloremque?
</blockquote>
</div>
Add support for images inside link and inside lists, for example :
<ul>
<li>
<img
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAIAAAACUFjqAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4QIJBywfp3IOswAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAAAkUlEQVQY052PMQqDQBREZ1f/d1kUm3SxkeAF/FdIjpOcw2vpKcRWCwsRPMFPsaIQSIoMr5pXDGNUFd9j8TOn7kRW71fvO5HTq6qqtnWtzh20IqE3YXtL0zyKwAROQLQ5l/c9gHjfKK6wMZjADE6s49Dver4/smEAc2CuqgwAYI5jU9NcxhHEy60sni986H9+vwG1yDHfK1jitgAAAABJRU5ErkJggg=="
/>
Docxtemplater
</li>
</ul>
<p>
<a>
Docxtemplater
<img
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAIAAAACUFjqAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4QIJBywfp3IOswAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAAAkUlEQVQY052PMQqDQBREZ1f/d1kUm3SxkeAF/FdIjpOcw2vpKcRWCwsRPMFPsaIQSIoMr5pXDGNUFd9j8TOn7kRW71fvO5HTq6qqtnWtzh20IqE3YXtL0zyKwAROQLQ5l/c9gHjfKK6wMZjADE6s49Dver4/smEAc2CuqgwAYI5jU9NcxhHEy60sni986H9+vwG1yDHfK1jitgAAAABJRU5ErkJggg=="
/>
</a>
</p>
Add part argument to getSize
Add support for : text-align: justify
Add support for : bgcolor
attribute on td and tr
Add support for : padding-top,padding-bottom,padding-left,padding-right
on td
Add support for valign
attribute on td
Add support for color in more CSS formats for background-color, color, border-color, for example : <span style='color: white;background-color: hsl(120, 100%, 50%); '>color output</span>
will now work.
Make it possible to use text-align inside td
Add support for :
vertical-align
style on td
background-color
style on tr
border-color
on td
Make it possible to customize pStyle for list items, for example :
const ulpStyles = ["ListBullet", "ListBullet2", "ListBullet3"];
const htmlOptions = {
elementCustomizer({ name, listLevel }) {
if (name === "ul") {
return {
pStyle: ulpStyles[listLevel],
useNumPr: false,
};
}
},
};
listLevel will be 0, 1, 2 depending on the nested level of the item in the HTML.
Do not apply elementCustomizer on implicit paragraphs.
For example, if you had in your html :
<table>
<tr>
<td>Lorem</td>
</tr>
</table>
and wrote :
const htmlOptions = {
// ...,
elementCustomizer(element) {
if (element.matches("td")) {
return {
pStyle: "TextBody",
};
}
if (element.matches("p")) {
return {
pStyle: "Heading",
};
}
},
};
Then, before this version, the text "Lorem" would use the "Heading" style.
In this new version the implicit paragraph <p>Lorem</p>
would not trigger a call to elementCustomizer at all, thus using "TextBody", which is the correct style to apply !
Make it possible to style implicit paragraphs in td by setting a pStyle on the td element from elementCustomizer.
The style property takes precendence over the style attribute, for example :
<td width="100" style="width: 400px" align="center">John</td>
will resolve to a width of 400px.
Add ignoreCssErrors to ignore CSS parse errors.
Add new selector API that makes it possible to style elements with CSS like selectors , for example :
const htmlOptions = {
// ...,
elementCustomizer(element) {
if (
element.matches(
"th h3.p1, tr>th>h3.p3, tr>h3.nomatch"
)
) {
return {
htmlStyle: "background-color: #ff0000;",
};
}
},
};
Add way to remove all table borders by specifying :
For example
<table style="border: none;">
<tr>
<td>Hello</td>
</tr>
</table>
Bugfix add possibility to style <a>
element (link)
Update browser build to use XMLSerializer instead of xmldom
Use requiredAPIVersion
Nodes of type '#document' may not be inserted inside nodes of type ...
<div><p>Hello</p></div>
Add support for :
align attribute on table cell
enhance colspan support when widths are not all fixed
table width as percentage
Add support for :
Background-color in tables (in css format)
Better use width in tables (which now generates colgrid and gridspan)
Add support for align="center"
Background-color in span (in css format)
{part}
argument to elementCustomizerExplanation : On some versions of npm (notably 5.8.0), when having a package containing docxtemplater-html-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.
paragraphCustomizer
api (which was added in 3.8.4), for a more generic elementCustomizer
API.Make it possible to customize docxstyles depending on classnames.
Explanation : Recently, the scopemananger API (internal API) has changed, this new version of the html module makes the module work with both versions newer than 3.6 and older than 3.6 of docxtemplater.
Add support for svg tag (needs the image module too) (this format is only readable on newer Word version : Microsoft Word, PowerPoint, Outlook, and Excel 2016 on Windows, Mac, Android and Windows Mobile).
Add meta context argument to custom parser with information about the tag for each types of tags
<p style="padding-left:15px">Hello</span>
<span style="font-size: 15px">Hello</span>
img
tag : GIF, JPEG, BMP, PNG work nowblockquote
tags:
in style attributes (parsed as :
).Add support for <img>
if using imagemodule.
Throw explicit error when using pptx instead of docx
Fix bug introduced in 3.5.5 : When using <li>
elements, all child tags are now correctly rendered (before, only the first child was rendered).
When using <a>Link</a>
without href, set the Target to "" instead of "undefined"
Handle multiple occurences of noBreakHyphen in same tag
Handle noBreakHyphen
Improve whitespace support.
{~html}
, for example :<p><b>Foo</b> <u>Bar</u></p>
will now correctly render "Foo Bar" instead of "Foobar"
{~~html}
, for example :<p><b>Foo</b> <u>Bar</u></p>
will now correctly render "Foo Bar" instead of "Foobar"
<ul>
,eg :
this.options.styleTransformer = function (tags) {
tags.ul.data.pStyle = [
"ListBullet",
"ListBullet2",
"ListBullet3",
];
tags.ul.data.useNumPr = false;
return tags;
};
This will set the "ListBullet" for level 0 of <ul>
, "ListBullet2" for level 1 and so on.
styleTransformer
to customize styles.<w:spacing w:before="0" w:after="0"/>
for each paragraph, but use the one that is set in the paragraph containing the {~~blockTag}, if present.This release needs version 3.1.11 of docxtemplater.
Bugfix issue with styles of TextBody or BodyText being wrongly changed.
Bugfix issue with bullet lists no more appearing
<ul><li><em>Test</em> after</li></ul>
 
, ∧
, and all html handled escapestext-align:center
and text-align:right
h5
and h6
"
&
'
>
<
<sub>
and <sup>
Add support for style="text-decoration: underline"
Handle nested ul/li:
<ul>
<li>Foo</li>
<li>
<ul>
<li>Nested 1</li>
<li>Nested 2</li>
</ul>
</li>
</ul>
Multiple fixes for tables :
Add support for tables that have :
<tbody>
, and directly <tr>
<thead>
or <tfoot>
<th>
instead of <td>
Also, allow td
to be empty, for example :
<table><tr><td>First</td><td></td><td>Third</td></tr></table>
Fixes links containing dom children to be shown as "undefined", for example :
<a href="https://ddg.gg">Foobar <span>Foo</span></a>
Make it possible to add paragraphs nested inside paragraphs, for example :
```
Paragraph1
Paragraph2
Paragraph3
```
Fix issues with &
and others not getting decoded
Add support for background-color on p
element. It uses the fill property of word, which sets the background-color for a full paragraph.
Add auto wrapping of inline elements in block-elements, so that <span>Foobar</span>
is also valid in {~~blockElement}. Also, this makes it possible to use <td>Foobar</td>
(the wrapping of the <p>
is done for you).
Add support for inline style background-color:blue
Fixes following error in version 3.1.2 : "Cannot find module '../static/styles.json'"
Bugfix when using multiple <ol>
, the numbering is reset correctly for each <ol>
Bugfixes when using elements other than <p>
inside a <td>
(eg now <ul>
works)
Bugfixes when using :
<ul>
, <li>
)Fix bug when using tags inside lists, for example, <ul><li><i>Foo</i></li></ul>
now works as expected
Update rendering of <ol>
to use the default symbol.
Do not change style of Title, Heading1 - Heading6 of current document
Add support for <input type="checkbox">
and <input type="checkbox" checked>
Fix right borders for tables
Fix corrupted documents with some templates
Add support for <a href="URL">LinkText</a>
Add support for inline style color:#ef0000
Keep word-run style for inline replacement. For example if, the text that the {~html}
tag is written in is red, it will also be the base style for the generated elements of the html tag.
Keep existing style. For example, if the html is : <p>Foobar</p>
, the text should be styled the same as the rest of the document.
Add support for ol
,ul
and li
tags
Update demo and readme
Initial release