首页 > 解决方案 > 使用 Puppeteer 打印除最后一页之外的所有 pdf 页

问题描述

我需要为最后一个 pdf 页面生成不同的页脚。经过调查,我意识到最好的方法是生成两个不同的 pdf 并将它们组合起来。当我需要为第一页更改页脚或使用不同的模板时,或者当我知道哪些页面应该看起来不同(使用pageRanges选项)但我找不到仅获取最后(最后 n)页的方法时,它工作正常如果总页码未知。有什么想法可以只为最后(最后 n)页生成 pdf 吗?

任何答案将不胜感激。
我正在使用 Puppeteer v 2.1.0 和 node.js v 8.16.0

这是我现在用来生成 pdf 文件的脚本。

const puppeteer = require('puppeteer');
const fs = require('fs');

const DEFAULT_HEADER = '<span></span>';
const DEFAULT_FOOTER_HEIGHT = 90;
const DEFAULT_PAGE_PADDING = 36;

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

    const [, , bodyFilePath, outputFilePath, footerFilePath] = process.argv;

    await page.goto(`file:${bodyFilePath}`, { waitUntil: 'networkidle0' });

    let footerTemplate = DEFAULT_HEADER;

    if (footerFilePath) {
      footerTemplate = fs.readFileSync(footerFilePath, 'utf8');
    }

    await page.pdf({
      path: outputFilePath,
      format: 'A4',
      margin: {
        top: DEFAULT_PAGE_PADDING,
        right: DEFAULT_PAGE_PADDING,
        bottom: DEFAULT_FOOTER_HEIGHT,
        left: DEFAULT_PAGE_PADDING,
      },
      printBackground: true,
      displayHeaderFooter: true,
      headerTemplate: DEFAULT_HEADER,
      footerTemplate,
    });
  } catch (err) {
    console.log(err.message);
  } finally {
    if (browser) {
      browser.close();
    }
    process.exit();
  }
};

createPdf();

我正在转换为 pdf 的模板是.html.erb文件

标签: node.jsruby-on-railsgoogle-chromeselenium-chromedriverpuppeteer

解决方案


也许有更好的方法来解决这个问题,但此时我已经使用了这种方法 - 我正在使用与上面相同的脚本生成导出,而不是使用另一个脚本来打开以前的 pdf 文件,计算页数并生成两个新文件(我将它们合并到后端的一个文件中) - 除了最后一个之外的所有页面,并且只有最后一页具有不同的页脚。

const puppeteer = require('puppeteer');
const fs = require('fs');
const pdf = require('pdf-parse');

const DEFAULT_HEADER = '<span></span>';
const DEFAULT_FOOTER_HEIGHT = 90;
const DEFAULT_PAGE_PADDING = 36;

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

    const [
      ,
      ,
      bodyFilePath,
      outputFilePath,
      footerFilePath,
      lastPagePath,
      lastPageFooterPath,
    ] = process.argv;

    await page.goto(`file:${bodyFilePath}`, { waitUntil: 'networkidle0' });

    let footerTemplate = DEFAULT_HEADER;
    let lastPageFooterTemplate = DEFAULT_HEADER;

    if (footerFilePath) {
      footerTemplate = fs.readFileSync(footerFilePath, 'utf8');
    }

    if (lastPageFooterPath) {
      lastPageFooterTemplate = fs.readFileSync(lastPageFooterPath, 'utf8');
    }

    const dataBuffer = fs.readFileSync(outputFilePath);
    const pdfInfo = await pdf(dataBuffer);
    const numPages = pdfInfo.numpages;

    const baseOptions = {
      path: outputFilePath,
      format: 'A4',
      margin: {
        top: DEFAULT_PAGE_PADDING,
        right: DEFAULT_PAGE_PADDING,
        bottom: DEFAULT_FOOTER_HEIGHT,
        left: DEFAULT_PAGE_PADDING,
      },
      printBackground: true,
      displayHeaderFooter: true,
      headerTemplate: DEFAULT_HEADER,
      pageRanges: `${numPages}`,
      footerTemplate: lastPageFooterTemplate,
    };

    if (numPages === 1) {
      await page.pdf(baseOptions);
    } else {
      await page.pdf({
        ...baseOptions,
        footerTemplate,
        pageRanges: `-${numPages - 1}`,
      });

      await page.pdf({
        ...baseOptions,
        path: lastPagePath,
        footerTemplate: lastPageFooterTemplate,
      });
    }
  } catch (err) {
    console.log(err.message);
  } finally {
    if (browser) {
      browser.close();
    }
    process.exit();
  }
};

createPdf();

希望这对有同样问题的人有所帮助。


推荐阅读