@rainbow-o23/n5
v1.0.50
Published
o23 pdf print
Downloads
326
Readme
o23/n5
o23/n5
provides a pipeline step that converts HTML templates to PDF, implemented based on Puppeteer.
Environment Parameters
| Name | Type | Default Value | Comments |
|-------------------------------------------|---------|---------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| puppeteer.executable.path
| string | | Chromium path. |
| puppeteer.browser.args
| string | | Chromium browser launch arguments.Format follows --disable-gpu[,--no-sandbox[...]]
.See https://peter.sh/experiments/chromium-command-line-switches/ for more details. |
| puppeteer.browser.cache
| boolean | true | Use browser cache or not. |
| puppeteer.devtools.enabled
| boolean | false | Open devtools or not. |
| puppeteer.headless.enabled
| boolean | true | Use headless mode or not. |
| puppeteer.max.pages
| number | 50 | Maximum pages(tabs) in single browser, only works when browser cache is enabled. |
| puppeteer.viewport.width
| number | 1920 | Default viewport width, only works when viewport
not present by constructor. |
| puppeteer.viewport.height
| number | 1080 | Default viewport height, only works when viewport
not present by constructor. |
| puppeteer.pdf.header.and.footer.display
| boolean | false | Show pdf header and footer or not, only works when pdfOptions.displayHeaderFooter
not present by constructor. |
| puppeteer.pdf.background
| boolean | false | Print background or not, only works when pdfOptions.printBackground
not present by constructor. |
| puppeteer.pdf.format
| string | a4 | Print page format, only works when pdfOptions.format
not present by constructor. |
| puppeteer.pdf.timeout
| number | 30 | Print timeout, in seconds, only works when pdfOptions.timeout
not present by constructor. |
| puppeteer.page.keep
| boolean | false | Keep browser page after printed, enable this feature will disable headless mode automatically, also, recommend to disable browser cache.Only for debug purpose, never enable it in production. |
Constructor Parameters
| Name | Type | Default Value | Comments |
|-------------|----------------------|---------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| browserArgs | string | | Additional browser arguments.Format follows --disable-gpu[,--no-sandbox[...]]
.See https://peter.sh/experiments/chromium-command-line-switches/ for more details. |
| viewport | puppeteer.Viewport | | |
| pdfOptions | puppeteer.PDFOptions | | |
Request and Response
export interface PrintPdfPipelineStepInFragment {
/** it is a html */
template: Buffer | string;
data: any;
}
export interface PrintPdfPipelineStepOutFragment {
file: Buffer;
}
An Example
Data
const data = {
type: 'Test Pdf',
information: [
{name: 'John', age: 25, birthday: '1998-03-27', addresses: ['address line 1', 'address line 2']},
{name: 'Jane', age: 27, birthday: '1996-08-12', addresses: ['address line 3']},
{name: 'Mike', age: 21, birthday: '2002-11-20'}
],
policy: [
{id: 1000001, productName: 'PRDT-001', productInfo: 'PRDT-001-INFO'},
{id: 1000002, productName: 'PRDT-002', productInfo: 'PRDT-002-INFO'}
]
};
Template
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div>
<h1 style="color: red" data-print="field" data-print-field="type">Name</h1>
<table>
<thead>
<tr>
<th>Name</th>
<th>Age</th>
<th>Birthday</th>
</tr>
</thead>
<tbody>
<tr data-print="loop" data-print-field="information">
<td data-print="field" style="color: red" data-print-field="name">Name</td>
<td data-print="field" data-print-field="age">Age</td>
<td data-print="field" data-print-field="birthday">Birthday</td>
<td>
<span data-print="loop" data-print-field="addresses">
<span data-print="field" data-print-field="" style="display: block">Address</span>
</span>
</td>
</tr>
</tbody>
</table>
<table>
<thead>
<tr>
<th>Id</th>
<th>Product Name</th>
<th>Product Info</th>
</tr>
</thead>
<tbody>
<tr data-print="loop" data-print-field="policy">
<td data-print="field" style="color: red" data-print-field="id">id</td>
<td data-print="field" data-print-field="productName">productName</td>
<td data-print="field" data-print-field="productInfo">productInfo</td>
</tr>
</tbody>
</table>
</div>
</body>
</html>
- Supports nested loops,
data-print=loop
represents loop,data-print=field
represents property,data-print-field
represents property name,- Supports multi-level property names, connected by
.
. For example,person.name
represents thatperson
is an object andname
is a property underperson
,
- Supports multi-level property names, connected by
- `` or
.
represents use loop array itself, - All properties are relative paths, calculated relative to their parent node. Therefore, within a loop, only the values of each element can be accessed.
Use Sub-templates
Use <data-print-template data-code="YOUR-TEMPLATE-CODE"></data-print-template>
to use sub-template. Sub-templates replacement are executed
before data replacement, accessed through the findSubTemplate
function provided pipeline step constructor.
Sub-templates also use the data from the page, so sub-templates do not need to prepare data separately.
Post Data Prepare
After the data preparation phase is completed, but before obtaining the header, footer, and printing parameters, the system will
automatically detect and invoke the postDataPrepare
function in order to incorporate additional custom logic. This function receives a
parameter of the current printing data, and custom logic can be written based on the data.
Please note that this function is executed synchronously, so it is not recommended to perform time-consuming operations.
Page Header and Footer
Both headers and footers are supported simultaneously, and you only need to use standard HTML node definitions with specified IDs. Additionally, thanks to the support provided by Puppeteer itself, the following fixed usage patterns can be used to obtain the specified information:
| HTML | Description |
|------------------------------------|------------------------------------|
| <header id="header"></header>
| Page header, can include anything. |
| <footer id="footer"></footer>
| Page footer, can include anything. |
| <span class=”date”></span>
| Current date |
| <span class=”title”></span>
| Document title |
| <span class=””url></span>
| Document URL |
| <span class=”pageNumber”></span>
| Current page number |
| <span class=”totalPages”></span>
| Total pages in the document |
PDF Options
Furthermore, pdfOptions
can also be specified by the template, allowing each template to have its own settings. The syntax is as follows:
<!-- format of data-attr follows pdfOptions signature -->
<template id="pdfOptions" data-attr='{"margin": {"top": "100px", "bottom": "100px", "left": "50px", "right": "50px"}}'></template>
In the example above, the margin of the print page header is set. Typically, when using headers and footers, it is necessary to manually set the page margin information as well.
Installation
Generally speaking, when installing dependencies, Node
will automatically download Chromium.
If it is not automatically installed, you can use the following command for installation.
The installed Chromium can be found in the puppeteer
directory.
// workspace mode
node ../node_modules/puppeteer/install.mjs
// single project mode
node ./node_modules/puppeteer/install.mjs
Use
puppeteer.config.cjs
to provide the location of chromium, see https://pptr.dev/guides/configuration for more details.
Performance Benchmark
This benchmark was conducted on the following hardware and environment:
- CPU: 2.6 GHz 6-Core Intel Core i7,
- Memory: 64 GB 2667 MHz DDR4,
- OS: macOS Sonoma 14.2.1,
- MySQL: 8.2.0,
- NodeJS: v18.19.0,
- NPM: v10.2.3.
With scenario:
- With one headless Chrome instance,
- Flow:
- Load template from database,
- Print file,
- Write printed file to database,
- Return to client,
- Template size: 1.7mb, 9 pages,
- No command inside.
- Output size: 1.1mb, 9 pages.
| # | Item | Max CPU Usage | Max Memory Usage | Avg. Response Time (ms) | |---|--------------------------------------|---------------|------------------|-------------------------| | 1 | 100 iterations, single thread | 25% | 400M | 2128 | | 2 | 100 iterations, 4 concurrent threads | 60% | 450M | 2541 | | 3 | 100 iterations, 8 concurrent threads | 70% | 450M | 3991 |