<Html> component for react-pdf
- Support for CSS via
<style>tags andstyleattributes (limited toStyleproperties supported byreact-pdf) - Browser CSS defaults with option for style reset
- Basic
<table>(attempted using flex layouts)<ul>and<ol>support - Ability to provide custom renderers for any tag
- Support for inline
<style>tags and remote stylesheets (using fetch)
- Parses the HTML string into a JSON tree of nodes using node-html-parser
- Parses any
<style>tags in the document andstyleattributes using css-tree - Renders all nodes using the appropriate
react-pdfcomponents, applying cascading styles for each node as an array passed to thestyleprop:- block/container nodes using
<View> - inline/text nodes using
<Text>, with appropriate nesting and collapsing of whitepace <img>nodes using<Image><a>nodes using<Link>
- block/container nodes using
npm i react-pdf-htmlOR
yarn add react-pdf-htmlimportHtmlfrom'react-pdf-html';consthtml=`<html> <body> <style> .my-heading4 { background: darkgreen; color: white; } pre { background-color: #eee; padding: 10px; } </style> <h1>Heading 1</h1> <h2 style="background-color: pink">Heading 2</h2> <h3>Heading 3</h3> <h4 class="my-heading4">Heading 4</h4> <p> Paragraph with <strong>bold</strong>, <i>italic</i>, <u>underline</u>, <s>strikethrough</s>, <strong><u><s><i>and all of the above</i></s></u></strong> </p> <p> Paragraph with image <img src="${myFile}" /> and <a href="http://google.com">link</a> </p> <hr /> <ul> <li>Unordered item</li> <li>Unordered item</li> </ul> <ol> <li>Ordered item</li> <li>Ordered item</li> </ol> <br /><br /><br /><br /><br /> Text outside of any tags <table> <thead> <tr> <th>Column 1</th> <th>Column 2</th> <th>Column 3</th> </tr> </thead> <tbody> <tr> <td>Foo</td> <td>Bar</td> <td>Foobar</td> </tr> <tr> <td colspan="2">Foo</td> <td>Bar</td> </tr> <tr> <td>Some longer thing</td> <td>Even more content than before!</td> <td>Even more content than before!</td> </tr> </tbody> </table> <div style="width: 200px; height: 200px; background: pink"></div> <pre>function myCode() { const foo = 'bar';}</pre> </body></html>`;return(<Document><Page><Html>{html}</Html></Page></Document>);importReactDOMServerfrom'react-dom/server';constelement=(<html><body><style>{` .heading4 { background: darkgreen; color: white; } pre { background-color: #eee; padding: 10px; }`}</style><h1>Heading 1</h1><h2style={{backgroundColor: 'pink'}}>Heading 2</h2>
...
</body></html>);consthtml=ReactDOMServer.renderToStaticMarkup(element);return(<Document><Page><Html>{html}</Html></Page></Document>);typeHtmlProps={children: string;// the HTMLcollapse?: boolean;// Default: true. Collapse whitespace. If false, render newlines as breaksrenderers?: HtmlRenderers;// Mapping of { tagName: HtmlRenderer }style?: Style|Style[];// Html root View stylestylesheet?: HtmlStyles|HtmlStyles[];// Mapping of { selector: Style }resetStyles?: false;// If true, style/CSS reset};conststylesheet={// clear margins for all <p> tagsp: {margin: 0,},// add pink background color to elements with class="special"['.special']: {backgroundColor: 'pink',},};return(<Document><Page><Htmlstylesheet={stylesheet}>{html}</Html></Page></Document>);consthtml=`<div style="width: 200px; height: 200px; background-color: pink">Foobar</div>`;return(<Document><Page><Html>{html}</Html></Page></Document>);Remote styles must be resolve asynchronously, outside of the React rendering, because react-pdf doesn't support asynchronous rendering
import{fetchStylesheets}from'react-pdf-html';consthtml=`<html> <head> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" /> </head> <body> <div></div> </body></html>`;conststylesheets=awaitfetchStylesheets(html,{
...fetchOptions});
...
return(<Document><Page><Htmlstylesheet={stylesheets}>{html}</Html></Page></Document>);Reset browser default styles (see CSS reset)
return(<Document><Page><HtmlresetStyles>{html}</Html></Page></Document>);The default styesheet roughly matches browser defaults, using a rough emulation of ems:
constem=(em: number,relativeSize: number=fontSize)=>em*relativeSize;StyleSheet.create({h1: {fontSize: em(2),marginVertical: em(0.67,em(2)),fontWeight: 'bold',},
...
});By default, the basis for the font size ems is based on the fontSize from props.style:
return(<Document><Page><Htmlstyle={{fontSize: 10}}>{html}</Html></Page></Document>);If this is not defined, it falls back to a default of 18
Please note that react-pdf has some constraints with how fonts are applied (see https://react-pdf.org/fonts). You must provide a different font file for each combination of bold, italic, etc. For example:
Font.register({family: 'OpenSans',fonts: [{src: fonts+'/Open_Sans/OpenSans-Regular.ttf'},{src: fonts+'/Open_Sans/OpenSans-Bold.ttf',fontWeight: 'bold'},{src: fonts+'/Open_Sans/OpenSans-Italic.ttf',fontStyle: 'italic'},{src: fonts+'/Open_Sans/OpenSans-BoldItalic.ttf',fontWeight: 'bold',fontStyle: 'italic',},],});