Puppeteer从多个HTMLS生成PDF

时间:2018-01-29 21:22:36

标签: html-to-pdf puppeteer google-chrome-headless

我正在使用Puppeteer从HTML字符串生成PDF文件。 阅读文档我发现了两种生成PDF文件的方法:

首先,传递一个url并按如下方式调用方法goTo

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

第二个,就是我的情况,调用方法setContent如下

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

问题是我有3个不同的HTML字符串从客户端发送,我想生成一个包含3页的PDF文件(如果我有3个HTMLS)。

我想知道是否有办法与木偶操作者一起做这件事? 我接受其他建议,但我需要使用chrome-headless。

提前致谢。

3 个答案:

答案 0 :(得分:3)

我能够从以下代码中的多个网址生成多个PDF:

<强>的package.json

{
 ............
 ............

 "dependencies": {
    "puppeteer": "^1.1.1",
    "easy-pdf-merge": "0.1.3"
 }

 ..............
 ..............
}

<强> index.js

const puppeteer = require('puppeteer');
const merge = require('easy-pdf-merge');

var pdfUrls = ["http://www.google.com","http://www.yahoo.com"];

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();

  var pdfFiles=[];

  for(var i=0; i<pdfUrls.length; i++){
    await page.goto(pdfUrls[i], {waitUntil: 'networkidle2'});
    var pdfFileName =  'sample'+(i+1)+'.pdf';
    pdfFiles.push(pdfFileName);
    await page.pdf({path: pdfFileName, format: 'A4'});
  }

  await browser.close();

  await mergeMultiplePDF(pdfFiles);
})();

const mergeMultiplePDF = (pdfFiles) => {
    return new Promise((resolve, reject) => {
        merge(pdfFiles,'samplefinal.pdf',function(err){

            if(err){
                console.log(err);
                reject(err)
            }

            console.log('Success');
            resolve()
        });
    });
};

RUN命令:节点index.js

答案 1 :(得分:2)

我能够通过以下方式做到这一点:

  1. 使用puppeteer生成3个不同的PDF。您可以选择在本地保存文件或将其存储在变量中。

  2. 我在本地保存了这些文件,因为我发现的所有PDF Merge插件都只接受URL而且他们不接受缓冲区。在本地同步生成PDF后,我使用PDF Easy Merge合并它们。

  3. 代码是这样的:

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

答案 2 :(得分:0)

pdf-merger-js 是另一种选择。 page.setContent 应该与以下 page.goto 的直接替代品一样工作:

const PDFMerger = require("pdf-merger-js"); // 3.1.0
const puppeteer = require("puppeteer"); // 8.0.0

const urls = [
  "https://news.ycombinator.com",
  "https://en.wikipedia.org",
  "https://www.example.com",
  // ...
];
const filename = "merged.pdf";

let browser;
(async () => {
  browser = await puppeteer.launch();
  const [page] = await browser.pages();
  const merger = new PDFMerger();

  for (const url of urls) {
    await page.goto(url);
    merger.add(await page.pdf());
  }

  await merger.save(filename);
})()
  .catch(err => console.error(err))
  .finally(async () => await browser.close())
;