Choose a generation strategy
Choose the method that best fits your infrastructure and layout requirements:- Render via headless browser — build an HTML/CSS template and use a browser engine to render it to PDF. Best when you want full control over layout and styling via HTML/CSS.
- Construct programmatically — use a PDF library like PDFKit to build the document step-by-step in code. Highly performant and ideal for simple, repetitive layouts without the overhead of a browser.
- Use an external service — send your structured data to a third-party API that handles rendering and hosting, offloading document assembly entirely.
Render with a headless browser
Install Puppeteer:puppeteer-core with a pre-installed browser instead.
The template receives the processed data object and returns an HTML string. All values are pre-computed — the template is only responsible for layout:
generateStatementPdf returns a Buffer containing the PDF, ready to be stored or delivered.
Execute as a background task
Offload report generation to an asynchronous worker to keep long-running generation from blocking your API. By returning immediately, your application remains responsive while the worker handles data retrieval, formatting, and file storage in the background. End users don’t wait for a report — they request one and get notified when it’s ready. Process outline:- The end user requests a report. Your backend responds immediately with a reference to the background job.
- A worker runs the full pipeline: fetch → process → generate.
- When the report is ready, your backend notifies the end user — via a retrieval link, email, or any other delivery method.
For implementation details on
fetchPortfolioStatement and fetchAllTransactions check Fetching data. For details on processStatementData check Preparing data.