generate PDF with multiple pages with puppeteer

Viewed 6643

I created a React App, and nodejs server. I have a big problem with my puppeteer. I want to create a PDF with multiple pages. But when the PDF is rendering, i have only one page and not all my content.

I am using puppeteer v-4.0.0

Can anybody help me ? thank you enter image description here

2 Answers

You have hidden code for this example, therefore I cannot tell what is happening 100%.

There are two approaches to this. You can add all the content of your web app in one page or have Puppeteer looping through a list of pages. The idea of creating multiple pages has to do with CSS paged media. In other words, if a website was already printing in multiple pages for a given document, Puppeteer follows along and will do the same thing.

In a nutshell, you know when your print is ready when you can simply do this in Chrome as a user:

Windows

Control + P > Hit on the Print Button

Mac

Command + P > Hit on the Print Button

What you saw there, is what you will be getting.

Nevertheless, if your code is indicating the headless browser to behave as screen e.g. await page.emulateMediaType('screen'); You are going to end up with a single huge chunk of PDF in some cases, similar to what a user would have done trying to print that page using Chrome.

If you are printing things like documentations, maybe amending to the concept of a print page is not a bad idea. For instance the print page would know how to gather all documents and bundle all of it to a single format which could then be printed afterwards. This results in a single PDF file, you would then have full control of from the client-side.

But sometimes, this sort of bundling may be too cumbersome or not ideal, you then would have to loop through pages like this:

const pages = [
   'relative-path-1',
   'relative-path-2',
   'relative-path-3'
];

let index = 0;

for (let link of pages){
  index++;
  await page.goto('the website address' + link);
  await page.pdf({
    path: 'Page-' + index + '.pdf'
  });
}

Puppeteer.js =>

const puppeteer = require('puppeteer');

(async () => {
    const browser = await puppeteer.launch({ headless: true })
    const page = await browser.newPage();

    await page.setUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) 
         AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3419.0 Safari/537.36');
    await page.goto('http://localhost:1234/pdf');
    await page.emulateMedia('screen');
    await page.pdf({ path: 'src/components/reportPdf.pdf'});
    await browser.close();
})()

Package.json =>

{
  "name": "copro-expert",
  "homepage": ".",
  "version": "1.0.0",
  "description": "Copro Expertises",
  "main": "index.js",
  "scripts": {
  "clean": "rm dist/bundle.js",
  "start": "parcel public/index.html",
  "build": "parcel build public/index.html --out-dir build --no-source-maps --no- 
  content-hash",
  "deploy": "npm run build && firebase deploy",
  "generate": "npx babel-node src/server/puppeteer.js"
  },
  "repository": {
  "type": "git",
  "url": "git+https://github.com/ovieokeh/lists-pwa.git"
  },
   "keywords": [
     "firebase",
     "pwa",
     "react"
   ],
  "author": "Ovie Okeh",
  "license": "Apache-2.0",
  "bugs": {
    "url": "https://github.com/ovieokeh/lists-pwa/issues"
 },
 "dependencies": {
 "@babel/core": "^7.10.3",
 "@babel/node": "^7.10.3",
 "axios": "^0.19.2",
 "body-parser": "^1.19.0",
 "express": "^4.17.1",
 "faker": "^4.1.0",
 "fetch-base64": "^2.1.2",
 "firebase": "^7.15.1",
 "hookrouter": "^1.2.3",
 "moment": "^2.24.0",
 "node": "^14.4.0",
 "nodemon": "^2.0.4",
 "puppeteer": "^4.0.0",
 "react": "^16.12.0",
 "react-dom": "^16.10.1",
 "react-router-dom": "^5.1.2",
 "redux": "^4.0.5",
 "save": "^2.4.0",
 "semantic-ui-css": "^2.4.1",
 "semantic-ui-react": "^0.88.2",
 "wkhtmltopdf": "^0.3.4",
 "ws": "^7.3.0"
 },
 "devDependencies": {
   "less": "^3.10.3",
   "parcel-bundler": "^1.12.3"
 }
}

PdfReport.jsx =>

import React, { useState, useEffect } from "react";
import { Button, Modal } from "semantic-ui-react";

const PdfReport = () => { 
  return (
    <div className="PdfReport page">                     
        <div>a</div>         
        <div>a</div>
        <div>a</div>
        <div>a</div>
        <div>a</div>
        <div>a</div>
        <div>a</div>
        <div>a</div>
        <div>a</div>
        <div>a</div>
        <div>a</div>
        <div>a</div>
        <div>a</div>
        <div>a</div>
        <div>a</div>
        <div>a</div>
        <div>a</div>
        <div>a</div>
        <div>a</div>
        <div>a</div>
        <div>a</div>
        <div>a</div>
        <div>a</div>
        <div>a</div>
        <div>a</div>
        <div>a</div>
        <div>a</div>
        <div>a</div>
        <div>a</div>
        <div>b</div>
        <div>b</div>
        <div>b</div>
        <div>b</div>
        <div>b</div>
        <div>b</div>
        <div>b</div>
        <div>b</div>
        <div>b</div>
        <div>b</div>
        <div>b</div>
        <div>b</div>
        <div>b</div>
        <div>b</div>
        <div>b</div>
        <div>b</div>
        <div>b</div>
        <div>b</div>
    </div>
  )
}

export default PdfReport;

Then i run the command => "npm run generate" And I got only one page. I tried puppeteer with another new project react, and it works. So i don't know what's wrong in my project.

Related