<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-htmlimport Html from 'react-pdf-html';
const html = `<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>
);import ReactDOMServer from 'react-dom/server';
const element = (
  <html>
    <body>
      <style>
        {`
        .heading4 {
          background: darkgreen;
          color: white;
        }
        pre {
          background-color: #eee;
          padding: 10px;
        }`}
      </style>
      <h1>Heading 1</h1>
      <h2 style={{ backgroundColor: 'pink' }}>Heading 2</h2>
      ...
    </body>
  </html>
);
const html = ReactDOMServer.renderToStaticMarkup(element);
return (
  <Document>
    <Page>
      <Html>{html}</Html>
    </Page>
  </Document>
);type HtmlProps = {
  children: string; // the HTML
  collapse?: boolean; // Default: true. Collapse whitespace. If false, render newlines as breaks
  renderers?: HtmlRenderers; // Mapping of { tagName: HtmlRenderer }
  style?: Style | Style[]; // Html root View style
  stylesheet?: HtmlStyles | HtmlStyles[]; // Mapping of { selector: Style }
  resetStyles?: false; // If true, style/CSS reset
};const stylesheet = {
  // clear margins for all <p> tags
  p: {
    margin: 0,
  },
  // add pink background color to elements with class="special"
  ['.special']: {
    backgroundColor: 'pink',
  },
};
return (
  <Document>
    <Page>
      <Html stylesheet={stylesheet}>{html}</Html>
    </Page>
  </Document>
);const html = `<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';
const html = `<html>
  <head>
    <link
      rel="stylesheet"
      href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
      integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN"
      crossorigin="anonymous" />
  </head>
  <body>
    <div></div>
  </body>
</html>`;
const stylesheets = await fetchStylesheets(html, {
    ...fetchOptions
});
...
return (
  <Document>
    <Page>
      <Html stylesheet={stylesheets}>{html}</Html>
    </Page>
  </Document>
);Reset browser default styles (see CSS reset)
return (
  <Document>
    <Page>
      <Html resetStyles>{html}</Html>
    </Page>
  </Document>
);The default styesheet roughly matches browser defaults, using a rough emulation of ems:
const em = (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>
      <Html style={{ 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',
    },
  ],
});