Convert HTML code to PDFMake format with ease, bridging the gap between HTML content and PDFMake document definitions
npx @tessl/cli install tessl/npm-html-to-pdfmake@2.5.0html-to-pdfmake is a JavaScript library that converts HTML markup into PDFMake document definitions, allowing you to generate PDFs from HTML content while maintaining basic styling and structure. It supports a wide range of HTML elements, CSS properties, and works seamlessly in both browser and Node.js environments.
npm install html-to-pdfmakehtml-to-pdfmake/browser.js// CommonJS (Node.js)
const htmlToPdfmake = require('html-to-pdfmake');
// ES6 (with bundler)
import htmlToPdfmake from 'html-to-pdfmake';For browser usage:
<script src="https://cdn.jsdelivr.net/npm/html-to-pdfmake/browser.js"></script>
<!-- Creates global htmlToPdfmake function -->const htmlToPdfmake = require('html-to-pdfmake');
const jsdom = require('jsdom');
const { JSDOM } = jsdom;
const { window } = new JSDOM('');
// Simple HTML conversion
const html = '<h1>Hello World</h1><p>This is a <strong>bold</strong> paragraph.</p>';
const pdfmakeContent = htmlToPdfmake(html, { window });
// Use with PDFMake
const pdfMake = require('pdfmake/build/pdfmake');
const docDefinition = { content: pdfmakeContent };
pdfMake.createPdf(docDefinition).getBuffer((buffer) => {
require('fs').writeFileSync('output.pdf', buffer);
});html-to-pdfmake is built around several core components:
Main conversion function that transforms HTML markup into PDFMake document definitions.
/**
* Transform HTML code to a PDFMake object
* @param {string} htmlText - The HTML code to transform
* @param {object} [options] - Configuration options
* @returns {object|{content: object, images: object}} PDFMake document definition or content with images
*/
function htmlToPdfmake(htmlText, options);Parameters:
htmlTextoptionsReturns:
options.imagesByReference{content, images}{text: string}Comprehensive options object for customizing conversion behavior.
interface ConversionOptions {
/** Override default styles for HTML elements */
defaultStyles?: {
[elementName: string]: object;
};
/** Enable automatic table sizing based on content and CSS properties */
tableAutoSize?: boolean;
/** Handle images by reference instead of embedding (browser only) */
imagesByReference?: boolean;
/** Remove extra blank spaces that may cause extra lines in PDF */
removeExtraBlanks?: boolean;
/** Display elements with display:none or visibility:hidden */
showHidden?: boolean;
/** Don't add 'html-TAG' classes to converted elements */
removeTagClasses?: boolean;
/** Array of CSS property names to ignore during conversion */
ignoreStyles?: string[];
/** Font sizes array for legacy <font> tag size attribute (1-7) */
fontSizes?: number[];
/** Custom function to handle non-standard HTML tags */
customTag?: (params: CustomTagParams) => object;
/** The window object (required for Node.js server-side use) */
window?: Window;
/** Custom text replacement function to modify text content during conversion */
replaceText?: (text: string, parents: Element[]) => string;
}
interface CustomTagParams {
/** The HTML element being processed */
element: Element;
/** Array of parent elements */
parents: Element[];
/** Current PDFMake object being built */
ret: object;
}Default Styles Object:
The library includes built-in default styles for HTML elements, which can be overridden:
const defaultStyles = {
b: { bold: true },
strong: { bold: true },
u: { decoration: 'underline' },
del: { decoration: 'lineThrough' },
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, marginLeft: 5 },
table: { marginBottom: 5 },
th: { bold: true, fillColor: '#EEEEEE' }
};Usage Examples:
// Override default styles
const options = {
window,
defaultStyles: {
h1: { fontSize: 28, bold: true, marginBottom: 8, color: 'darkblue' },
p: { margin: [0, 6, 0, 12], lineHeight: 1.2 },
a: { color: 'purple', decoration: null } // Remove underline from links
}
};
// Enable automatic table sizing
const tableOptions = {
window,
tableAutoSize: true
};
// Handle images by reference (browser only)
const imageOptions = {
imagesByReference: true
};
const result = htmlToPdfmake('<table><tr><td width="200">Cell</td></tr></table>', tableOptions);
// Custom text replacement
const textOptions = {
window,
replaceText: function(text, parents) {
// Replace soft hyphens with non-breaking hyphens for better PDF rendering
return text.replace(/-/g, "\\u2011");
}
};
const htmlWithHyphens = '<p>Some hy-phenated text that might break across lines</p>';
const resultWithReplacement = htmlToPdfmake(htmlWithHyphens, textOptions);Block Elements:
divph1h2h3h4h5h6tabletheadtbodytfoottrthtdulolliprehrInline Elements:
spanstrongbemiusdelstrikeasubsupimgsvgbrfontSpecial Elements:
customTagdiv[data-pdfmake-type="columns"]data-pdfmakeTypography:
font-familyfont-sizefont-weightfont-styleline-heightcolortext-aligntext-decorationtext-indentwhite-spaceLayout:
marginwidthheightbackground-colorborderTable-Specific:
rowspancolspanfillColorfillOpacitydata-pdfmake: Add custom PDFMake properties via JSON data attribute.
<!-- Table layout -->
<table data-pdfmake='{"layout":"noBorders"}'>
<tr><td>No border table</td></tr>
</table>
<!-- Custom HR styling -->
<hr data-pdfmake='{"width":400,"thickness":2,"color":"red"}'>
<!-- Custom element properties -->
<div data-pdfmake='{"pageBreak":"before","margin":[0,10,0,10]}'>
Content with page break
</div>data-pdfmake-type: Special element type handling.
<!-- Create PDFMake columns layout -->
<div data-pdfmake-type="columns">
<div>Column 1</div>
<div>Column 2</div>
<div>Column 3</div>
</div>Custom Tag Handling:
const options = {
window,
customTag: function({ element, parents, ret }) {
if (element.nodeName === 'HIGHLIGHT') {
ret.background = 'yellow';
ret.color = 'black';
} else if (element.nodeName === 'CALLOUT') {
ret.margin = [10, 5, 10, 5];
ret.fillColor = '#f0f0f0';
ret.border = [true, true, true, true];
}
return ret;
}
};
const html = '<p>Normal text <highlight>highlighted text</highlight> more text</p>';
const result = htmlToPdfmake(html, options);Image Handling by Reference:
// Browser environment only
const html = '<img src="https://example.com/image.jpg" width="200">';
const result = htmlToPdfmake(html, { imagesByReference: true });
// Result structure:
// {
// content: [{ image: 'img_ref_abc123', width: 200, style: ['html-img'] }],
// images: { 'img_ref_abc123': 'https://example.com/image.jpg' }
// }
// Use with PDFMake
pdfMake.createPdf(result).download();Complex Table with Auto-sizing:
const tableHtml = `
<table style="width:100%">
<colgroup>
<col width="30%">
<col width="70%">
</colgroup>
<tr style="height:50px">
<td style="width:200px;background-color:#eee">Header 1</td>
<td>Header 2</td>
</tr>
<tr>
<td rowspan="2" style="height:100px">Spanning cell</td>
<td>Regular cell</td>
</tr>
<tr>
<td>Another cell</td>
</tr>
</table>
`;
const result = htmlToPdfmake(tableHtml, {
window,
tableAutoSize: true
});// Return type when imagesByReference is false (default)
interface PDFMakeDocumentDefinition {
text?: string | PDFMakeElement[];
stack?: PDFMakeElement[];
table?: {
body: PDFMakeElement[][];
widths?: (number | string)[];
heights?: (number | string)[];
};
ul?: PDFMakeElement[];
ol?: PDFMakeElement[];
image?: string;
svg?: string;
canvas?: CanvasElement[];
// ... other PDFMake properties
}
// Return type when imagesByReference is true
interface PDFMakeWithImages {
content: PDFMakeDocumentDefinition;
images: {
[key: string]: string;
};
}
interface PDFMakeElement {
text?: string | PDFMakeElement[];
style?: string[];
bold?: boolean;
italics?: boolean;
decoration?: string[];
color?: string;
background?: string;
fontSize?: number;
font?: string;
alignment?: string;
margin?: number[];
border?: boolean[];
borderColor?: string[];
fillColor?: string;
fillOpacity?: number;
opacity?: number;
lineHeight?: number;
leadingIndent?: number;
noWrap?: boolean;
preserveLeadingSpaces?: boolean;
width?: number | string;
height?: number | string;
colSpan?: number;
rowSpan?: number;
link?: string;
linkToDestination?: string;
nodeName?: string;
id?: string;
[key: string]: any; // Custom data-pdfmake properties
}
interface CanvasElement {
type: string;
x1: number;
y1: number;
x2: number;
y2: number;
lineWidth: number;
lineColor: string;
}