Search code examples
html-to-pdfpuppeteergoogle-chrome-headless

Puppeteer Generate PDF from multiple HTML strings


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 goto method as follows:

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

The second one, which 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 HTML strings).

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


Solution

  • 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!');
    })