Skip to content

Repository files navigation

react-pdf-html

<Html> component for react-pdf

  • Support for CSS via <style> tags and style attributes (limited to Style properties supported by react-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)

How it Works

  1. Parses the HTML string into a JSON tree of nodes using node-html-parser
  2. Parses any <style> tags in the document and style attributes using css-tree
  3. Renders all nodes using the appropriate react-pdf components, applying cascading styles for each node as an array passed to the style prop:
    • 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>

Installation

npm i react-pdf-html

OR

yarn add react-pdf-html

Usage

importHtmlfrom'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>);

Rendering React Components

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>);

Props

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};

Overriding Element Styles

Provide a Stylesheet

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>);

Inline Styles

consthtml=`<div style="width: 200px; height: 200px; background-color: pink">Foobar</div>`;return(<Document><Page><Html>{html}</Html></Page></Document>);

Remote Styles

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>);

Resetting Styles

Reset browser default styles (see CSS reset)

return(<Document><Page><HtmlresetStyles>{html}</Html></Page></Document>);

Font Sizes

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

Fonts for bold, italic, etc.

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',},],});

About

Render HTML in react-pdf

Resources

Stars

215 stars

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors

Languages