pdfOptions & printOptions explained
The 2nd argument pdfOptions controls how HTML is laid out into PDF; the 3rd printOptions controls how PDF is sent to the physical printer. Same field names can mean different stages—configure them in pairs to avoid “preview OK, paper clipped” issues.
Two stages: layout to PDF, then print
Pipeline: HTML render → PDF file → system print queue. pdfOptions affects layout; printOptions only affects the final dispatch.
await webPrintPdf.printHtml(
html,
pdfOptions, // arg 2: HTML → PDF layout
printOptions, // arg 3: PDF → physical printer
extraOptions // arg 4: preview/print, timeout, cookies, etc.
);
extraOptions (4th arg) is behavioral: action: "preview" generates PDF without printing; requestTimeout affects URL loads. Use preview to tune layout before changing printOptions.Shared field names (easy to misconfigure)
These fields share names but apply at different stages. Set them consistently in pairs or you may see clipped output or odd margins.
| Field | pdfOptions | printOptions | Tips / pitfalls |
|---|---|---|---|
paperFormat |
Built-in 12 ISO/US names (see section below); overrides width/height |
Two value types: ① 10 built-in names; ② name from getPrinterPapers (must match that printer—do not invent). Unknown values fall back to default |
Office stock: usually set the same enum on both sides (A4/Letter). Thermal/labels: pdf width/height, print getPrinterPapers — paperFormat deep dive |
landscape |
PDF page orientation (portrait/landscape) | Content orientation—does not rotate the physical tray | Set landscape: true on both sides together with matching paperFormat; one side alone often has no effect |
pageRanges |
Trim pages when generating PDF | Trim pages when printing | Usually set the same range on both sides |
paperFormat deep dive (shared field)
paperFormat shares a name in pdf and print but each stage has its own job: pdf sizes the HTML page; print picks printer stock. Usually set both sides explicitly (omit to use defaults)—they do not sync automatically. See allowed values below, then pair using the two scenarios.
pdfOptions.paperFormat — layout stage
Allowed values
Letter, Legal, Tabloid, Ledger, A0, A1, A2, A3, A4, A5, A6 (default A4).
Use width + height (px / in / cm / mm) instead—mutually exclusive with paperFormat. 80mm receipts, 100×60mm labels, etc.
printOptions.paperFormat — print stage
Allowed values
Built-in: A2, A3, A4, A5, A6, Letter, Legal, Tabloid, Ledger, Statement (current printer’s default paper). Stock not in the list (thermal, labels, etc.)—see Scenario 2 below: use getPrinterPapers for that printer’s name; do not invent names.
const printers = await webPrintPdf.utils.getPrinterList();
const target = printers.find(p => p.isDefault) || printers[0];
const papers = await webPrintPdf.utils.getPrinterPapers(target);
// papers[].name → printOptions.paperFormat
console.log(papers.map(p => p.name));
How to pair both sides
Scenario 1: office paper. These names exist on both sides—use the same string: A2, A3, A4, A5, A6, Letter, Legal, Tabloid, Ledger. Example: pdfOptions.paperFormat: 'A4', printOptions.paperFormat: 'A4' (use Letter the same way in North America). Never mix pdf A4 with print Letter—physical sizes differ and content may clip.
Scenario 2: receipts, labels, custom stock. pdf uses width + height (e.g. 80mm) and omits pdfOptions.paperFormat. print should usually set paperFormat too: call getPrinterPapers on the target printer and pick the name whose physical size matches pdf (e.g. 80mm Series); strings may differ. Use action: 'preview' to verify before printing.
// pdf side: 80mm receipt — omit paperFormat
const pdfOptions = { width: '80mm', height: '200mm', margin: { top: '0', bottom: '0', left: '0', right: '0' } };
// print side: pick a driver paper name that matches physical size
const papers = await webPrintPdf.utils.getPrinterPapers('Thermal printer');
const printOptions = {
printerName: 'Thermal printer',
paperFormat: papers.find(p => p.name.includes('80'))?.name ?? papers[0].name
// When you know the exact name: paperFormat: '80mm Series'
};
Also note: A0, A1 are pdf-only—on print, use getPrinterPapers for the closest stock; Statement is print-only—do not use on pdf (use Letter or width/height). Re-query paper names when the printer changes.
Default rules
paperFormat is omitted in code, the SDK applies:- pdfOptions.paperFormat: omitted and no
width/height→ layout defaults to A4. - printOptions.paperFormat: omitted → print uses the current printer’s default paper. If you set a preferred paper for a printer on the client printer list page, omitted print
paperFormatuses that printer’s preferred stock.
pdfOptions (HTML → PDF)
| Field | Type / default | Description & tips |
|---|---|---|
paperFormat | string · A4 | Fixed names: paperFormat deep dive. Mutually exclusive with width/height; labels/thermal use mm and omit paperFormat. |
width / height | string|number | Custom size with px/in/cm/mm. Pick paperFormat or width/height. Tip: margin 0 on all sides for label stock. |
margin | object · 0 | Edge margins, default 0. With displayHeaderFooter, reserve top/bottom (e.g. 18mm) so headers do not overlap body text. |
landscape | boolean · false | false portrait, true landscape. Must match printOptions.landscape: true to take effect. |
printBackground | boolean · false | Default false—background colors/images are dropped. Set true for receipts and colored tables. |
preferCSSPageSize | boolean · false | When true, CSS @page { size: ... } wins over paperFormat. Useful for mixed templates; can surprise you with A4 jobs. |
displayHeaderFooter | boolean · false | Enables headerTemplate/footerTemplate. Classes: date, title, url, pageNumber, totalPages. |
headerTemplate / footerTemplate | string | HTML snippets; inline styles work best. Header/footer area is outside body margin—leave space. |
watermark | object | Text: text, color, size, rows, cols, angle, opacity. Pitfall: color must be rgb(r,g,b); angle ≥ 0. Image watermarks use base64. |
pageNumber | object | Overlay with format: '{{page}}/{{totalPage}}'. Pitfall: color must be rgb; not the same as headerTemplate pageNumber class. |
pageRanges | Array · [] | e.g. [{from:1,to:3}]; empty = all pages. |
printOptions (PDF → printer)
| Field | Type / default | Description & tips |
|---|---|---|
printerName | string | Must match name from utils.getPrinterList(). Omit for default printer—do not hard-code names from another PC. |
paperFormat | string | Built-in enums + driver names—see paperFormat deep dive. Call utils.getPrinterPapers(printer) and use returned name. |
colorful | boolean · false | false mono, true color; may downgrade if unsupported. |
landscape | boolean · false | false portrait, true landscape. Must match pdfOptions.landscape: true; controls dispatch orientation, not physical tray rotation in the driver. |
copies | number | Copy count. |
duplexMode | string · simplex | simplex, duplex, duplexshort, duplexlong. Unsupported duplex may fail or fall back. |
scaleMode | string · shrink | noscale, shrink (default), fit. Use extraOptions.action: "preview" to compare. |
bin | number|string | Input tray/bin per driver. |
pageRanges | Array · [] | Same shape as pdfOptions. |
Common pitfalls
- paperFormat + width/height together — paperFormat wins; custom size ignored.
- Mismatched paperFormat — PDF A4 on Letter stock clips or leaves gaps. See paperFormat deep dive for pairing rules.
- watermark/pageNumber color as #hex or named colors — use
rgb(102,102,102). - landscape set on only one side — set
landscape: truein both pdfOptions and printOptions; one side alone may preview OK but print portrait or clip. - Thermal/label without margin:0 — default margins shrink 80mm receipts.
- printBackground: false — striped tables and header fills print blank.
- displayHeaderFooter without extra margin — headers overlap first line of body.
- batchPrint merge direction — per-task options override batch defaults, not the other way around.
Recipes (copy-paste)
A4 office doc with backgrounds
const pdfOptions = {
paperFormat: 'A4',
margin: { top: '15mm', bottom: '15mm', left: '12mm', right: '12mm' },
printBackground: true
};
const printOptions = {
paperFormat: 'A4',
printerName: 'Default printer',
scaleMode: 'shrink'
};
await webPrintPdf.printHtml(html, pdfOptions, printOptions);
100×60mm label (custom size)
const pdfOptions = {
width: '100mm',
height: '60mm',
margin: { top: '0', bottom: '0', left: '0', right: '0' }
// Do not set paperFormat at the same time
};
const printOptions = {
printerName: 'Label printer',
paperFormat: '100x60' // use name from getPrinterPapers
};
await webPrintPdf.printHtml(labelHtml, pdfOptions, printOptions);
A4 landscape (wide tables, Gantt)
const pdfOptions = {
paperFormat: 'A4',
landscape: true,
margin: { top: '10mm', bottom: '10mm', left: '8mm', right: '8mm' },
printBackground: true
};
const printOptions = {
paperFormat: 'A4',
landscape: true // pdfOptions and printOptions must both be true
};
await webPrintPdf.printHtml(html, pdfOptions, printOptions);
Duplex contract + preview scale compare
// Try preview to compare scaleMode, then switch to print
await webPrintPdf.printHtml(html,
{ paperFormat: 'A4', printBackground: true },
{ paperFormat: 'A4', duplexMode: 'duplexlong', scaleMode: 'fit' },
{ action: 'preview' }
);
batchPrint merge rules
batchPrint(list, pdfOptions, printOptions, extraOptions) — last three are batch defaults. Each task may include its own options; task-level overrides batch-level.
await webPrintPdf.batchPrint(
[
{ type: 'printHtml', data: html1, pdfOptions: { width: '80mm', height: '200mm' } },
{ type: 'printHtml', data: html2 }
],
{ margin: { top: '2mm' } }, // batch default pdfOptions
{ printerName: 'Thermal printer' }, // batch default printOptions
{ requestTimeout: 20 }
);
// Per-task pdfOptions / printOptions override batch defaults