import fs from "fs"; import Handlebars from 'handlebars'; import i18next from "i18next"; import Backend from 'i18next-fs-backend'; import path from 'path'; import puppeteer from "puppeteer"; import { Runner } from './models/Runner'; /** * This class is responsible for all things pdf creation. * This uses the html templates from src/templates. */ export class PdfCreator { private templateDir = path.join(__dirname, '/templates'); private browser; private static interpolations = { eventname: "Lauf für Kaya! 2021", sponsoring_receipt_minimum_amount: '10', currency_symbol: "€" } /** * Main constructor. * Initializes i18n(ext), Handlebars and puppeteer. */ constructor() { i18next .use(Backend) .init({ fallbackLng: 'en', lng: 'en', backend: { loadPath: path.join(__dirname, '/locales/{{lng}}.json') } }); Handlebars.registerHelper('__', function (str) { return i18next.t(str, PdfCreator.interpolations).toString(); } ); puppeteer.launch({ headless: true }).then(browser => { this.browser = browser; }); } /** * Generate sponsoring contract pdfs. * @param runner The runner you want to generate the contracts for. * @param locale The locale used for the contracts (default:en) */ public async generateSponsoringContract(runners: Runner[], locale: string = "en"): Promise { i18next.changeLanguage(locale); const template_source = fs.readFileSync(`${this.templateDir}/sponsoring_contract.html`, 'utf8'); const template = Handlebars.compile(template_source); const result = template({ runners }) console.log(template) return await this.renderPdf(result, { format: "A5", landscape: true }); } /** * This method manages the creation of pdfs via puppeteer. * @param html The HTML that should get rendered. * @param options Puppeteer PDF option (eg: {format: "A4"}) */ public async renderPdf(html: string, options): Promise { const page = await this.browser.newPage(); await page.setContent(html); const pdf = await page.pdf(options); await page.close(); return pdf; } }