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 getPrinterPaperspaperFormat 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

Usually set both pdfOptions and printOptions (omit to use default rules—see “Default rules” below). Skipping either side often causes clipping or wrong layout on custom stock or multi-tray printers.

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

When 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 paperFormat uses that printer’s preferred stock.

pdfOptions (HTML → PDF)

FieldType / defaultDescription & tips
paperFormatstring · A4Fixed names: paperFormat deep dive. Mutually exclusive with width/height; labels/thermal use mm and omit paperFormat.
width / heightstring|numberCustom size with px/in/cm/mm. Pick paperFormat or width/height. Tip: margin 0 on all sides for label stock.
marginobject · 0Edge margins, default 0. With displayHeaderFooter, reserve top/bottom (e.g. 18mm) so headers do not overlap body text.
landscapeboolean · falsefalse portrait, true landscape. Must match printOptions.landscape: true to take effect.
printBackgroundboolean · falseDefault false—background colors/images are dropped. Set true for receipts and colored tables.
preferCSSPageSizeboolean · falseWhen true, CSS @page { size: ... } wins over paperFormat. Useful for mixed templates; can surprise you with A4 jobs.
displayHeaderFooterboolean · falseEnables headerTemplate/footerTemplate. Classes: date, title, url, pageNumber, totalPages.
headerTemplate / footerTemplatestringHTML snippets; inline styles work best. Header/footer area is outside body margin—leave space.
watermarkobjectText: text, color, size, rows, cols, angle, opacity. Pitfall: color must be rgb(r,g,b); angle ≥ 0. Image watermarks use base64.
pageNumberobjectOverlay with format: '{{page}}/{{totalPage}}'. Pitfall: color must be rgb; not the same as headerTemplate pageNumber class.
pageRangesArray · []e.g. [{from:1,to:3}]; empty = all pages.

printOptions (PDF → printer)

FieldType / defaultDescription & tips
printerNamestringMust match name from utils.getPrinterList(). Omit for default printer—do not hard-code names from another PC.
paperFormatstringBuilt-in enums + driver names—see paperFormat deep dive. Call utils.getPrinterPapers(printer) and use returned name.
colorfulboolean · falsefalse mono, true color; may downgrade if unsupported.
landscapeboolean · falsefalse portrait, true landscape. Must match pdfOptions.landscape: true; controls dispatch orientation, not physical tray rotation in the driver.
copiesnumberCopy count.
duplexModestring · simplexsimplex, duplex, duplexshort, duplexlong. Unsupported duplex may fail or fall back.
scaleModestring · shrinknoscale, shrink (default), fit. Use extraOptions.action: "preview" to compare.
binnumber|stringInput tray/bin per driver.
pageRangesArray · []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: true in 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
Download client free Open live demos