This module permits to convert HTML to the PDFMake format
pdfmake permits to easily create a PDF with JavaScript; however there is no support of HTML code, so I decided to create a module to handle this feature.
You can find the online demo at https://aymkdn.github.io/html-to-pdfmake/index.html
This module will convert some basic and valid HTML code to its equivalent in pdfmake.
npm install html-to-pdfmake
var htmlToPdfmake = require("html-to-pdfmake"); // or: // import htmlToPdfmake from "html-to-pdfmake"
Example:
var pdfMake = require("pdfmake/build/pdfmake"); var pdfFonts = require("pdfmake/build/vfs_fonts"); pdfMake.vfs = pdfFonts.pdfMake.vfs; var htmlToPdfmake = require("html-to-pdfmake");var html = htmlToPdfmake(
<div> <h1>My title</h1> <p> This is a sentence with a <strong>bold word</strong>, <em>one in italic</em>, and <u>one with underline</u>. And finally <a href="https://www.somewhere.com">a link</a>. </p> </div>
);/* it will return: { stack:[ { text: 'My title', fontSize: 24, bold: true, marginBottom: 5, style: ['html-h1'] }, { text: [ { text: 'This is a sentence with a ' }, { text: 'bold word', bold: true, style: ['html-strong'] }, { text: ', ' }, { text: 'one in italic', italics: true, style: ['html-em'] }, { text: ', and ' }, { text: 'one with underline', decoration: 'underline', style: ['html-u'] }, { text: '. And finally ' }, { text: 'a link', color: 'blue', decoration: 'underline', link: 'https://www.somewhere.com', style: ['html-a'] }, { text: '.' } ], margin: [0, 5, 0, 10], style: ['html-p'] } ], style: ['html-div'] } */
Example:
html my example[…]
Some options can be passed to
htmlToPdfmakefunction as a second argument.
window
If you use Node, then you'll have to pass the
windowobject (see below).
defaultStyles
You can overwrite the default styles using
defaultStyles(see below).
fontSizes
You can overwrite the default sizes for the old HTML4 tag
by usingfontSizes. It must be an array with 7 values (see below).
tableAutoSize
By passing
tableAutoSizewith
true, then the program will try to define
widthsand
heightsfor the tables, based on CSS properties
widthand
heightthat have been provided to
THor
TD.
Example: ``
javascript var html = htmlToPdfmake(
height:100px / width:250px | height:100px / width:'auto' |
Here it will use 250px for the width because we have to use the largest col's width | height:200px / width:'auto' |
// it will return something like: [ { "table": { "body": [ [ … ] ], "widths": [ 188, "auto" ], "heights": [ 75, 151 ] } } ] ```
replaceText
By passing
replaceTextas a function with two parameters (
textand
nodes) you can modify the text of all the nodes in your HTML document.
Example:
javascript var html = htmlToPdfmake(`Lorem Ipsum is simply d-ummy text of th-e printing and typese-tting industry. Lorem Ipsum has b-een the industry's standard dummy text ever since the 1500s
`, { replaceText:function(text, nodes) { // 'nodes' contains all the parent nodes for the text return text.replace(/-/g, "\\u2011"); // it will replace any occurrence of '-' with '\\u2011' in "Lorem Ipsum is simply d-ummy text […] dummy text ever since the 1500s" } });
The below HTML tags are supported: - DIV / P / SPAN - BR - B / STRONG - I / EM - S - UL / OL / LI - TABLE / THEAD / TBODY / TFOOTER / TR / TH / TD - H1 to H6 - FONT - IMG - SVG
I've defined some default styles for the supported element.
For example, using a <STRONG> will display the word in bold. Or, a link will appear in blue with an underline, and so on...
Here is the list of defaults styles:
javascript { b: {bold:true}, strong: {bold:true}, u: {decoration:'underline'}, s: {decoration: 'lineThrough'}, em: {italics:true}, i: {italics:true}, h1: {fontSize:24, bold:true, marginBottom:5}, h2: {fontSize:22, bold:true, marginBottom:5}, h3: {fontSize:20, bold:true, marginBottom:5}, h4: {fontSize:18, bold:true, marginBottom:5}, h5: {fontSize:16, bold:true, marginBottom:5}, h6: {fontSize:14, bold:true, marginBottom:5}, a: {color:'blue', decoration:'underline'}, strike: {decoration: 'lineThrough'}, p: {margin:[0, 5, 0, 10]}, ul: {marginBottom:5}, li: {marginLeft:5}, table: {marginBottom:5}, th: {bold:true, fillColor:'#EEEEEE'} }
For the old HTML4 tag
, thesizeattributes can have a value from 1 to 7, which will be converted to 10pt, 14pt, 16pt, 18pt, 20pt, 24pt, or 28pt.
Please, note that the above default styles are stronger than the ones defined in the style classes. Read below how to overwrite them.
Each converted element will have an associated style-class called
html-tagname.
For example, if you want all <STRONG> tags to be highlighted with a yellow backgroud you can use
html-strongin the
stylesdefinition:
var html = htmlToPdfmake(`This sentence has a highlighted word, but not only.
`);var docDefinition = { content: [ html ], styles:{ 'html-strong':{ background:'yellow' // it will add a yellow background to all elements } } };
var pdfDocGenerator = pdfMake.createPdf(docDefinition);
The
classand
stylesfor the elements will also be added.
var html = htmlToPdfmake(`This sentence has a bold and red word.
`);/* It returns: { text: [ { text: 'This sentence has ' }, { text: 'a bold and red word', style: ['red', 'html-span'], // 'red' added because of
class="red"
bold: true // added because ofstyle="font-weight:bold"
}, { text: '.' } ], margin: [0, 5, 0, 10], style: ['html-p'] } */var docDefinition = { content: [ html ], styles:{ red:{ // we define the class called "red" color:'red' } } };
var pdfDocGenerator = pdfMake.createPdf(docDefinition);
Please, note that the default styles are stronger than the ones defined in the style classes. For example, if you define a class
html-ato change all links in purple, then it won't work because the default styles will overwrite it:
var docDefinition = { content: [ html ], styles:{ 'html-a':{ color:'purple' // it won't work: all links will remain 'blue' } } };
To make it work, you have to either delete the default styles, or change it with a new value. Starting
v1.1.0, an option parameter is available as a second parameter.
Example: you want
to be 'purple' and without 'underline' style: ```javascript var html = htmlToPdfmake('
var docDefinition = { content: [ html ], styles:{ 'with-margin':{ marginLeft: 30 // apply a margin with the specific class is used } } }; ```
PDFMake uses
ptunits for the numbers.
html-to-pdfmakewill check the inline style to see if a number with unit is provided, then it will convert it to
pt.
It only works for
px,
ptand
rem(for
remit's based on
1rem = 16px);
Examples: -
font-size:16pxwill be converted to
fontSize:12-
margin:1emwill be ignored because it's not a valid unit
The
tag is supported, however the
srcattribute must already be a base64 encoded content (as describe in the PDFMake documentation).
This is too complex and out of the scope of this module to find and convert the image source to a base64 format. You can check this Stackoverflow question to know the different ways to get a base64 encoded content from an image.
pageBreakBeforeand a CSS class that you'll apply to your elements to identify when to add a page break: ``
javascript var html = htmlToPdfmake(
This is my paragraph on page 1.
This is my paragraph on page 2.
var docDefinition = { content: [ html ], pageBreakBefore: function(currentNode) { return currentNode.style && currentNode.style.indexOf('pdf-pagebreak-before') > -1; } };
var pdfDocGenerator = pdfMake.createPdf(docDefinition); ```
See example.js to see another example.
PDFMake provides some special attributes, like
widthsor
heightsfor
table, or
fitfor
image, and more. To apply these special attributes, you have to use the attribute
data-pdfmakeon your HTML elements, and then pass the special attributes as a JSON string.
Table with widths=[100,"*","auto"] and heights=40 | ||
Cell1 | Cell2 | Cell3 |
The expression provided by
data-pdfmakemust be a valid JSON string because it will be translated with
JSON.parse().
An
can also be customized using
data-pdfmake. Some default styles are applied to this element:
javascript { left:0, // the left position width:514, // should be OK with a A4 page color:'black', // the color of the line thickness:0.5, // how thick the line must be margin:[0,12,0,12] // same order as PDFMake, meaning: [left, top, right, bottom] }
See the example.js file to see a
example.
To use it in a Node script you need to install
jsdom:
bash npm install jsdom
Then in your JS file: ```javascript var pdfMake = require("pdfmake/build/pdfmake"); var pdfFonts = require("pdfmake/build/vfs_fonts"); pdfMake.vfs = pdfFonts.pdfMake.vfs; var fs = require('fs'); var jsdom = require("jsdom"); var { JSDOM } = jsdom; var { window } = new JSDOM(""); var htmlToPdfMake = require("html-to-pdfmake");
var html = htmlToPdfMake(
, {window:window});the html code
var docDefinition = { content: [ html ] };
var pdfDocGenerator = pdfMake.createPdf(docDefinition); pdfDocGenerator.getBuffer(function(buffer) { fs.writeFileSync('example.pdf', buffer); }); ```
You can find more examples in example.js which will create example.pdf:
npm install node example.js
You can support my work by making a donation, or by visiting my Github Sponsors page. Thank you!