Composite jobs
Put images, PDFs and templates into one job: one preview, one print, one sheet.
Last updated
The feel of one multi-page PDF, but with content from different places:
page 1 a photo
pages 2–4 pages 2–4 of a report PDF
page 5 a packing slip with order data boundThe user sees one preview and clicks print once; the print queue holds one job.
Ten lines
const session = await client
.compose({ queueId })
.paper('A4') // one sheet, set once
.pageLayout('auto') // job-wide preset
.addImage(photoA).imageLayout({ mode: 'custom', scalePercent: 80 })
.addPdf(reportPdf).pageRange('2-4') // item methods affect one item
.addImage(photoB).imageLayout({ mode: 'fill' })
.addDocument(labelDoc).data({ orderNo: 'A-1024' })
.preview();
console.log(session.pageCount); // 5
console.log(session.source.items); // which output pages each item covers
await client.previewPrint(session.previewSessionId);To skip the preview use .printAndWait(); to see exactly what was sent use
.toParams().
Key rules
One job, one sheet. options.paper is the single size for the whole job and
every page lands on it. No content item has a paper size of its own. To change
paper, change the job's paper.
Order is page order. The order of add* calls is the output page order.
Item methods affect one item. .pageRange() follows the preceding addPdf,
.data() follows the preceding addDocument, .imageLayout() follows the
preceding image. The types also reject invalid combinations — for example
.addImage(x).pageRange() is a compile error.
Copies do not duplicate thumbnails. copies is repeated by the printer; the
preview still shows one set.
Limits
| Limit | Value |
|---|---|
| Content items | 1–50 (an empty array gives SOURCE_EMPTY) |
| Web page items among them | at most 10 |
| Total merged pages | ≤ 1000 |
| Total merged bytes | ≤ 256 MiB |
Exceeding a limit is an error, never a silent truncation. For more than 50 pages,
consider a repeat element or submitting in batches.
Batching with repeat
Do not print N labels by looping print() — share one job:
const job = client.compose({ queueId }).paper('100x150');
for (const order of orders) job.addDocument(template).data(order);
await job.printAndWait();Or move the loop into the template with a repeat element, in which case the
data is a single payload. See
content sources.
What the preview shows
- Thumbnails in output-page order; with mixed content each carries a source badge (image / PDF / web page / template).
- A status bar like
12 output pages · 4 sources · A4 210×297 mm. - Selecting a page shows where it came from, e.g. "page 3 · PDF 2/3".
- Changing paper or the job-wide preset regenerates the artefact for the whole batch; changing an image layout affects only that image.
Common mistakes
- Looping
print()over files: that becomes N jobs and N preview windows. Always use onecompose()or oneitemsarray. - Trying to set a paper size on one item: there is no such field; paper is job-level.
- Using
pageRangeto reorder: it only filters; reorder by adding items. - Sharing one
dataacross templates: data travels with the item, so call.data()per item.