Puppeteer Generate PDF from multiple HTMLS

Juan Rivillas picture Juan Rivillas · Jan 29, 2018 · Viewed 12.4k times · Source

I am using Puppeteer to generate PDF files from HTML strings. Reading the documentation I found two ways of generating the PDF files:

First, passing an url and call the method goTo as follows

page.goto('https://example.com');
page.pdf({format: 'A4'});

The second one, that is my case, calling the method setContent as follows

page.setContent('<p>Hello, world!</p>');
page.pdf({format: 'A4'});

The thing is that I have 3 different HTML strings that are sent from the client and I want to generate a single PDF file with 3 pages (in case I have 3 HTMLS).

I wonder if there exist a way of doing this with puppeteer ? I accept other suggestions, but I need to use chrome-headless.

Thanks in advance.

Answer

Juan Rivillas picture Juan Rivillas · Jan 31, 2018

I was able to do this by doing the following:

  1. Generate 3 different PDFs with puppeteer. You have the option of saving the file locally or to store it in a variable.

  2. I saved the files locally, because all the PDF Merge plugins that I found only accept URLs and they don't accept buffers for instance. After generating synchronously the PDFs locally, I merged them using PDF Easy Merge.

The code is like this:

const page1 = '<h1>HTML from page1</h1>';
const page2 = '<h1>HTML from page2</h1>';
const page3 = '<h1>HTML from page3</h1>';

const browser = await puppeteer.launch();
const tab = await browser.newPage();
await tab.setContent(page1);
await tab.pdf({ path: './page1.pdf' });

await tab.setContent(page2); 
await tab.pdf({ path: './page2.pdf' });

await tab.setContent(page3);
await tab.pdf({ path: './page3.pdf' });

await browser.close();

pdfMerge([
  './page1.pdf',
  './page2.pdf',
  './page3.pdf',
],
path.join(__dirname, `./mergedFile.pdf`), async (err) => {
  if (err) return console.log(err);
  console.log('Successfully merged!');
})