Puppeteer generate PDF from HTML

In puppeteer generate pdf is possible using the special page.pdf() page method. This function generates a pdf document from html markup.

Generating a pdf is currently only supported in Chrome headless!

  1. Generation pdf
  2. Save pdf
  3. Print media and screen media
  4. Display header, footer and page background
  5. Range pdf page
  6. Scale, sizes, landscape and margin pdf page
  7. Header and footer template

Generation pdf

To get started, let’s try to generate pdf pages without specifying any options in the pdf() method. For example, we’ll pdf the main page of PocketAdmin.tech:

const puppeteer = require('puppeteer');         // include library

(async () => {                                  // declare function
  const browser = await puppeteer.launch();     // run browser
  const page = await browser.newPage();         // create new tab
  await page.goto('https://pocketadmin.tech');  // go to page
  await page.pdf();                             // generate pdf current page
  await browser.close();                        // close browser
})();

We generated pdf pages. But where to look for this document? Because we did not specify any options in the pdf () method, then the document was not saved on our disk.

Save pdf

Let’s get acquainted with the main parameter of the pdf () method – path. This parameter specifies the path to save the pdf document generated in puppeteer.

If path is a relative path, then it is resolved relative to current working directory. If no path is provided, the PDF won’t be saved to the disk!

Let’s fix our first code:

const puppeteer = require('puppeteer');         // include library

(async () => {                                  // declare function
  const browser = await puppeteer.launch();     // run browser
  const page = await browser.newPage();         // create new tab
  await page.goto('https://pocketadmin.tech');  // go to page
  await page.pdf({path: 'page.pdf'});           // generate pdf and save it in page.pdf file
  await browser.close();                        // close browser
})();

In the directory with the script, we have the document page.pdf. Open it and see the result:

Print media and screen media

It can be seen that in puppeteer generate pdf was done on our main page, but it looks somehow different. The fact is that page.pdf() by default generates pdf for printing (print css media). To make pdf look like the original page, you must call page.emulateMedia (‘screen’) before page.pdf(), i.e. use screen media:

const puppeteer = require('puppeteer');         // include library

(async () => {                                  // declare function
  const browser = await puppeteer.launch();     // run browser
  const page = await browser.newPage();         // create new tab
  await page.goto('https://pocketadmin.tech');  // go to page
  await page.emulateMedia('screen');            // use screen media
  await page.pdf({path: 'page.pdf'});           // generate pdf
  await browser.close();                        // close browser
})();

As a result of this, we get:

Display header, footer and page background

Yes, now the pdf document is similar to our main page. But there are not enough colors … Conventionally, two parameters can be assigned to those responsible for the “graphics” (in addition to screen media):

  1. displayHeaderFooter – display header and footer (defaults to false)
  2. printBackground – print background graphics (defaults to  false)

Let’s set their value to true. The code will take the following form:

const puppeteer = require('puppeteer');         // include library

(async () => {                                  // declare function
  const browser = await puppeteer.launch();     // run browser
  const page = await browser.newPage();         // create new tab
  await page.goto('https://pocketadmin.tech');  // go to page
  await page.emulateMedia('screen');            // use screen media
  await page.pdf({path: 'page.pdf', displayHeaderFooter: true, printBackground: true});  // generate pdf
  await browser.close();                        // close browser
})();

And our document page.pdf will become similar to the page of the site:

Range pdf page

In puppeteer create pdf is similar to taking a screenshot with the fullPage parameter, i.e. the resulting pdf may contain more than one page (the number depends on the page size of the site). To limit the number of pages or specify specific pages, you can use the pageRanges parameter, for example, display only the first page – ‘1’, the range – ‘1-5’, or all at once:

await page.pdf({path: 'page.pdf', displayHeaderFooter: true, printBackground: true, pageRanges: '1, 3-5'});

Scale, sizes, landscape and margin pdf page

When generating a pdf page, you can scale it, resize, orient it, specify the print format, etc. (a full list of parameters can be found in the documentation). Let’s talk about some of them:

  • scale – scale of the webpage rendering. Scale amount must be between 0.1 and 2 (defaults to 1).
  • landscape – page orientation: false – vertical, true – horizontal (default is false)
  • format – paper format (default to Letter). Possible values ​​(all sizes are indicated in inches):
    • Letter: 8.5 x 11
    • Legal: 8.5 x 14
    • Tabloid: 11 x 17
    • Ledger: 17 x 11
    • A0: 33.1 x 46.8
    • A1: 23.4 x 33.1
    • A2: 16.54 x 23.4
    • A3: 11.7 x 16.54
    • A4: 8.27 x 11.7
    • A5: 5.83 x 8.27
    • A6: 4.13 x 5.83
  • width – paper width
  • height – paper heigth
  • margin – paper margins (default to none):
    • top – top margin
    • bottom – bottom margin
    • left – left margin
    • righht – righnt margin

The following values ​​can be used for page width, height and margins:

  • px – pixel
  • in – inch
  • cm – centimeter
  • mm – millimeter

The default pixels are:

await page.pdf({width: 1024, heigth: 768});

If you need to specify the dimensions, for example in centimeters, then the value is enclosed in quotation marks:

await page.pdf({{width: '20cm', heigth: '10cm'});

An example of specifying page margins in pixels:

await page.pdf(
      {margin: {
          top: 80,
          bottom: 80,
          left: 30,
          right: 30,
          top: 80
          }
       });

The format parameter takes precedence over the width and height parameters.

Header and footer template

When generating pdf from html markup in puppeteer, you can set inscriptions (headers and footers) in the header and footer according to templates. There are two options for this:

  • headerTemplate – HTML template for the print header
  • footerTemplate – HTML template for the print footer

Indicated parameters should be valid HTML markup with following classes used to inject printing values into them:

  • date –  formatted print date
  • title – document title
  • url – document location
  • pageNumber – current page number
  • totalPages – total pages in the document

To use headerTemplate and footerTemplate it is necessary that displayHeaderFooter is set to true, and margin field sizes must be sufficient to display labels (headers and footers)!

Add a header with the inscription This is a PocketAdmin page with the page number to our pdf document. Here is the final code listing for the topic “Puppeteer generate pdf“:

const puppeteer = require('puppeteer');         // include library

(async () => {                                  // declare function
  const browser = await puppeteer.launch();     // run browser
  const page = await browser.newPage();         // create new tab
  await page.goto('https://pocketadmin.tech');  // go to page

  // declare html markup for header
  html = `<div style="font-size: 15px; padding-top: 8px; text-align: center; width: 100%;">
            <span>This is a PocketAdmin page</span> - <span class="pageNumber"></span>
          </div>
        `;

  await page.emulateMedia('screen');            // use screen media
  await page.pdf({
        path: 'page.pdf',                       // path to save pdf file  
        displayHeaderFooter: true,              // display header and footer (in this example, required!)
        printBackground: true,                  // print background
        landscape: true,                        // use horizontal page layout
        headerTemplate: html,                   // indicate html template for header
        margin: {                               // increase margins (in this example, required!)
          top: 80,
          bottom: 80,
          left: 30,
          right: 30
          }
        });
  await browser.close();                        // close browser
})();

The resulting pdf document will look like this:

Leave a Comment