Table pagination in generated PDFs
Tables that break across pages, and still look like tables
JetPage splits a long table across pages row by row, re-emits the header rows on every page including multi-row headers carrying colSpan, and repairs the table frame at the point where the split happens, so a table continuing onto page four still has a top border and a header. Products that render PDFs by driving a headless browser, such as PDFMonkey and APITemplate, inherit the print CSS page-break model, where breaking behaviour is a request the browser may decline. CraftMyPDF documents page breaks as a common issue in a dedicated troubleshooting page of its own. JetPage measures pagination in the render engine instead, so where a table breaks is a computed result rather than a hint.
This page covers how a table breaks. For how long documents perform and what they cost to generate at volume, see bulk PDF generation.
Why table page breaks go wrong
JetPage decides page breaks in the render engine, so a break is measured rather than requested
Print CSS expresses page breaks as properties such as break-inside and break-after, which a browser treats as preferences it may honour or ignore depending on the layout it has already committed to. That is why the same template produces a clean break in one browser version and a stranded header row in the next. Any PDF product built on a headless browser inherits this model along with the engine, which is the situation PDFMonkey and APITemplate are in.
A team that has been fighting break-inside rules is fighting the engine rather than the template, and changing template tools without changing the engine changes nothing.
JetPage re-emits table headers on every page, including multi-row headers with colSpan
A table that runs to a second page without its header becomes a grid of unlabelled numbers. Single-row headers are the easy case, and most tools manage them. Real documents use grouped headers, where a header spans two or three rows and upper cells carry colSpan across the columns they group, and that is where repeat logic in template builders usually stops.
A statement or a report with grouped column headers stays readable on page seven of a JetPage document.
JetPage repairs the table frame where a split happens
Splitting a table leaves two raw edges. Without repair, the last row on one page has no bottom border and the first row on the next page has no top border, so both fragments read as an unfinished table. This detail is what separates a table that survived pagination from a table that was cut. It compounds with per-row and per-cell border erasure, which designers use to group rows visually, because an erased border and a split edge are easy to confuse.
A JetPage table that continues over a page boundary is bordered on both sides of the break without a designer adding anything.
What JetPage tables do beyond splitting cleanly
JetPage hides a column conditionally and shrinks the spans above it automatically
One template usually has to serve several document variants: a discount column that appears only when a discount exists, a tax column that appears only for certain jurisdictions. Hiding a column is straightforward until a grouped header spans it, at which point the header above a hidden column is one cell too wide and the whole grid shears. This is why most builders offer conditional rows but not conditional columns.
A JetPage template covers the variant with a discount column and the variant without it as one template rather than two.
JetPage allows nested content inside cells, including nested tables, with grid integrity validated
Line-item tables frequently need structure inside a cell: a description with its own sub-items, a small breakdown table, a list. Drag-and-drop builders typically stop at one level of nesting, which CraftMyPDF documents as its limit. Merging and splitting cells around nested content is where a grid quietly becomes invalid, with overlapping spans that render differently on every engine.
A JetPage line-item table can hold a nested breakdown without the designer checking by hand whether the grid still adds up.
JetPage holds 21 CI-blocking golden scenarios that a table regression cannot pass
Every PDF tool claims reliable page breaks. The difference between a claim and a guarantee is whether a change that breaks pagination can reach production. Most template products verify layout by looking at it, which finds the regression after a customer does. A visual regression gate compares rendered output against a stored reference and fails the build on any difference.
Pagination behaviour in JetPage is enforced by the build rather than promised in documentation.
How the PDF generation market handles complex tables
| Capability | PDF Generator API | CraftMyPDF | APITemplate.io | Carbone | PDFMonkey | JetPage |
|---|---|---|---|---|---|---|
| Pagination model | Proprietary engine | Proprietary engine | Browser print CSS | LibreOffice conversion | Browser print CSS | Measured by a typesetting engine |
| Page breaks in tables | Editor slows on complex templates | Documented as a common issue | Hand-coded HTML and print CSS | Word layout limits | Hand-coded HTML and print CSS | Row by row, with frame repair |
| Repeating headers | Not documented | Not documented | Hand-coded | Not documented | Hand-coded | Multi-row, colSpan preserved |
| Nested tables in cells | Not documented | One nesting level | Possible in HTML | Word layout limits | Possible in HTML | Yes, grid integrity validated |
| Conditional columns | Not documented | Not documented | Hand-coded | Not documented | Hand-coded | Yes, with automatic span shrink |
| Regression gate on layout | None published | None published | None published | None published | None published | 21 CI-blocking golden scenarios |
Competitor rows summarise the JetPage competitive analysis of August 2026, which draws on vendor documentation and pricing pages and on published G2, Capterra, and Trustpilot reviews. "Not documented" means the vendor publishes no statement on that capability, not that the capability is absent.
Frequently asked questions
Does JetPage repeat the table header on every page?
Yes, including multi-row grouped headers. JetPage re-emits header bands on every page a table occupies and preserves colSpan on each repeated row rather than flattening grouped headers into one row.
Why do page breaks work in my browser preview but not in the exported PDF?
Because a headless browser treats print CSS break properties as preferences rather than instructions, and the screen layout and the print layout are computed differently. Any PDF product built on a browser inherits that behaviour. JetPage computes breaks in a typesetting engine from measured row heights, and the JetPage preview comes from the same engine as the PDF.
What happens to table borders where a table splits?
JetPage repairs the table frame at the split, so the fragment ending one page and the fragment starting the next are both bordered. Intentional per-row and per-cell border erasure is preserved and not confused with a split edge.
Can a JetPage table hold a nested table inside a cell?
Yes. JetPage supports nested content in cells including nested tables, and validates grid integrity when cells are merged or split so an inconsistent grid is rejected rather than rendered.
Can a column disappear when there is no data for it?
Yes. JetPage supports conditional per-column show and hide, and shrinks the colSpan of every header cell that spanned a hidden column automatically, so one template serves the variant with the column and the variant without it.
How is table pagination tested?
The JetPage build holds at least 21 golden scenarios rendered to SVG and compared byte by byte, covering table splits, repeated headers, conditional columns, Cyrillic coverage, and an injection probe. A difference in any of them fails continuous integration.
Put a 40-page table through JetPage
JetPage is free to try without a credit card, and the free plan includes the render API, so the honest test is available immediately: bring the document whose tables break badly today and generate it.