import { Browser, Page, PDFOptions } from 'puppeteer' import { PdfOptions, pdfOptionsFactory } from './PdfOptions' import { enhanceContent } from '../util' import { extractPDFToc } from '../util/pdf' export const PAPER_FORMATS = ['A3', 'A4', 'A5', 'Legal', 'Letter', 'Tabloid'] export const PAGE_ORIENTATIONS = ['portrait', 'landscape'] export class Pdf { private browser: Browser constructor(browser: Browser) { this.browser = browser } public async generate(options: PdfOptions): Promise<Buffer> { options = pdfOptionsFactory(options) const page = await this.browser.newPage() await enhanceContent(options) try { const pdfBuffer = await Pdf.generateContent(options, page) return await Pdf.generateToc(pdfBuffer, options, page) } catch (e) { throw e } finally { await page.close() } } private static async generateContent(options: PdfOptions, page: Page): Promise<Buffer> { await page.setContent(options.content, { waitUntil: 'networkidle0' }) const pdfOptions = Pdf.buildPdfArguments(options, false) return await page.pdf(pdfOptions) } private static async generateToc(pdfBuffer: Buffer, options: PdfOptions, page: Page): Promise<Buffer> { if (options.tocTemplate) { await extractPDFToc(pdfBuffer, options) await page.setContent(options.content, { waitUntil: 'networkidle0' }) const pdfOptions = Pdf.buildPdfArguments(options, false) return await page.pdf(pdfOptions) } return pdfBuffer } private static buildPdfArguments(options: PdfOptions, toc: boolean): PDFOptions { return { format: options.format, landscape: options.orientation == 'landscape', margin: options.margin, printBackground: true, displayHeaderFooter: toc ? false : options.displayHeaderFooter, headerTemplate: options.header, footerTemplate: options.footer, } } }