@shad0wz7/nestjs-pdf
v2.3.2
Published
A NestJS library for generating PDFs with Puppeteer and Handlebars.
Maintainers
Readme
nestjs-pdf
A small NestJS library to generate and manipulate PDFs using Puppeteer and multiple template engines, including Handlebars, EJS, Pug, MJML, Nunjucks, Eta and Mustache.
Main features:
- Generate PDFs from HTML, Handlebars, EJS, Pug, MJML, Nunjucks, Eta or Mustache templates
- Concurrency limiting for Puppeteer jobs (p-limit)
- Add signature fields based on a text anchor in an existing PDF
- Simple API (module and service) to integrate easily into a Nest application
Installation
To add the library inside your project :
npm install @shad0wz7/nestjs-pdf
# or
pnpm add @shad0wz7/nestjs-pdf
# or
yarn add @shad0wz7/nestjs-pdf
# If using the local source, from the other project:
pnpm add ../path/to/nestjs-pdfQuick start
Import the module and configure it in your Nest application:
To use a template engine, you need to install the corresponding package as a dependency in your project:
- For Handlebars:
npm install @gboutte/nestjs-hbs - For EJS:
npm install ejs - For Pug:
npm install pug - For MJML:
npm install mjml - For Nunjucks:
npm install nunjucks - For Eta:
npm install eta - For Mustache:
npm install mustache
import { Module } from '@nestjs/common';
import { NestjsPdfModule } from 'nestjs-pdf';
@Module({
imports: [
NestjsPdfModule.forRoot({
// default Puppeteer / PDF options
headless: true,
pdfOptions: { format: 'A4' },
}),
],
})
export class AppModule {}Inject the service and generate a PDF:
import { Controller, Get } from '@nestjs/common';
import { NestjsPdfService } from 'nestjs-pdf';
@Controller()
export class AppController {
constructor(private readonly pdfService: NestjsPdfService) {}
@Get('pdf')
async getPdf() {
const html = '<h1>Hello</h1><p>PDF generated by nestjs-pdf</p>';
const buffer = await this.pdfService.generatePdfFromHtml(html);
return buffer; // return a Buffer / Uint8Array depending on your controller
}
}Use a Handlebars template (string or file):
const template = '<h1>{{title}}</h1><p>{{content}}</p>';
const pdf = await pdfService.generatePdfFromTemplateHbsString(template, {
title: 'T',
content: '...',
});const pdf = await pdfService.generatePdfFromTemplateHbsFile(filePath, {
title: 'T',
content: '...',
});Add a signature field to an existing PDF (anchor-based):
const originalPdfBytes = await this.pdfService.generatePdfFromHtml(html);
const modifiedPdf = await pdfService.addSignatureFieldSignatureDebtorRaw(
originalPdfBytes,
'SignatureDebtor',
'__SIG_DEBTOR_ANCHOR__',
);If the anchor is not found, the signature field will be added at a default position.
Warning: if you encounter issues like "Failed to load pdfjs-dist." Make sure to install @napi-rs/canvas as a dependency in your project, as it's required by the library for PDF manipulation.
Options and configuration
The library exposes Puppeteer options via the PuppeteerParameters interface (see src/puppeteer/puppeteer-parameters.interface.ts). You can configure:
| | Description |
|-----------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| pdfOptions | The pdf options can be found on: https://pptr.dev/api/puppeteer.pdfoptions. Native Puppeteer options for page.pdf |
| hbsOptions | The handlebars can be found on @gboutte/nestjs-hbs as it use a peer dependency and not handlebars directly |
| ejsOptions | The ejs options can be found on EJS documentation |
| pugOptions | The pug options can be found on Pug documentation |
| mjmlOptions | The mjml options can be found on MJML documentation |
| nunjucksOptions | The nunjucks options can be found on Nunjucks documentation |
| etaOptions | The eta options can be found on Eta documentation |
| mustacheOptions | The mustache options can be found on Mustache documentation |
| browser | The browser to use for the PDF generation. By default: Browser.CHROMIUM. Allowed values Browser.CHROMIUM, Browser.CHROMEHEADLESSSHELL, Browser.CHROME, Browser.FIREFOX, Browser.CHROMEDRIVER (Official documentation of Browser) |
| browserTag | The version of the browser to use for the PDF generation. By default: BrowserTag.LATEST if Browser is CHROMIUM else BrowserTag.STABLE. Allowed values BrowserTag.STABLE, BrowserTag.LATEST, BrowserTag.BETA, BrowserTag.DEV, BrowserTag.CANARY |
| browserInstallBaseUrl | The baseUrl used for the installation of the browser. This baseUrl is passed to the install method of @puppeteer/browsers |
| headless | Define if you want to use chromium headless or not, or the old headless version (shell). By default it's true. Allowed values: true,false,"shell" |
| useLockedBrowser | Define if you want to use the locked version of the browser. By default it's false. Allowed values: true,false |
| buildId | You can force the build id. Should be string |
| cleanupBrowserCacheOnExit | Define if you want to clean up the browser cache folder on exit. By default it's true. Allowed values: true,false |
| extraPuppeteerArgs | It passes some extra arguments to Puppeteer's launch method. You can check the default args at bellow. Should be string[] |
| executablePath | The path to the browser executable to use. If not specified, Puppeteer will install Chromium in cache dir. (useLockedBrowser is useless with this param specified) |
these are the default extra arguments passed to Puppeteer:
[
'--autoplay-policy=user-gesture-required',
'--disable-background-networking',
'--disable-background-timer-throttling',
'--disable-backgrounding-occluded-windows',
'--disable-breakpad',
'--disable-client-side-phishing-detection',
'--disable-component-update',
'--disable-default-apps',
'--disable-dev-shm-usage',
'--disable-domain-reliability',
'--disable-extensions',
'--disable-features=AudioServiceOutOfProcess',
'--disable-hang-monitor',
'--disable-ipc-flooding-protection',
'--disable-notifications',
'--disable-offer-store-unmasked-wallet-cards',
'--disable-popup-blocking',
'--disable-print-preview',
'--disable-prompt-on-repost',
'--disable-renderer-backgrounding',
'--disable-setuid-sandbox',
'--disable-speech-api',
'--disable-sync',
'--hide-scrollbars',
'--ignore-gpu-blacklist',
'--metrics-recording-only',
'--mute-audio',
'--no-default-browser-check',
'--no-first-run',
'--no-pings',
'--password-store=basic',
'--use-gl=swiftshader',
'--use-mock-keychain',
'--disable-accelerated-2d-canvas',
'--no-zygote',
'--disable-gpu',
];You can use forRootAsync(...) if you need to provide configuration asynchronously.
Tests
This repository includes unit and integration tests (Jest). To run the tests:
pnpm run test
pnpm run test:e2eContributing
If you want to contribute:
- Open an issue to discuss the change
- Fork the repo, create a feature/fix branch, then open a PR
- Follow Conventional Commits for automated releases
License
MIT — see the LICENSE file.
