Print all pdf pages except the last one using Puppeteer

Viewed 1620

I need to generate different footer for the last pdf page. After investigation I realised that the best way is to generate two different pdfs and combine them. It works fine when I need to change footer or use different templates for first page, or in cases when I know which pages should looks different (using pageRanges option), but I can't find a way to get only last (last n) pages in case when total page number is unknown. Any ideas how I can generate pdf for only last (last n) pages?

Will be appreciated for any answers.
I'm using Puppeteer v 2.1.0 with node.js v 8.16.0

This is a script which I'm using for generating pdf files now.

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();

Templates which I'm converting to pdf are .html.erb files

1 Answers

Maybe there is better ways to solve this problem but at this point I've used this approach - I'm generating export using same script as above, and than I'm using one more script which opens previous pdf file, count pages and generates two new files (which I'm combining to one file on the backend) - All pages except last one, and only last page with different footer.

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();

Hope this will be helpful for someone with same issue.

Related