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.

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.

ProofJetPage renders on a typesetting engine of the class used to produce books, where pagination is the primary job rather than an afterthought of screen layout. JetPage computes where a table splits from the measured height of each row against the remaining space on the page, as described in why a typesetting engine differs from HTML to PDF.

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.

ProofJetPage repeats multi-row header bands on every page a table occupies, preserving colSpan on every repeated row rather than flattening grouped headers into a single row. Header re-emission across a page break is one of the scenarios held in the JetPage visual regression suite and checked on every build.

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.

ProofJetPage supports per-row and per-cell border erasure and repairs the table frame when a table splits across pages, so an intentionally erased border stays erased and a split edge gains the border it needs. Table split behaviour is byte-diffed as SVG in the JetPage visual regression suite.

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.

ProofJetPage supports conditional per-column show and hide with automatic span shrink, so hiding a column reduces the colSpan of every header cell that spanned it and the grid stays aligned. Conditional columns are held as a scenario in the JetPage visual regression suite alongside table splits.

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.

ProofJetPage supports nested content in cells including nested tables, and validates grid integrity when cells are merged or split, rejecting a merge that would leave the grid inconsistent. JetPage also supports repeat bands over arrays, elastic stretch rows, and soft-wrapping of long unbroken tokens such as reference numbers.

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.

ProofThe JetPage build holds at least 21 golden scenarios that block continuous integration when they differ, each rendered to SVG and compared byte by byte, covering table splits, conditional columns, repeated headers, Cyrillic coverage, and an injection probe. A rendering change that moves a single edge in any of those scenarios fails the build rather than shipping.

Pagination behaviour in JetPage is enforced by the build rather than promised in documentation.

How the PDF generation market handles complex tables

CapabilityPDF Generator APICraftMyPDFAPITemplate.ioCarbonePDFMonkeyJetPage
Pagination modelProprietary engineProprietary engineBrowser print CSSLibreOffice conversionBrowser print CSSMeasured by a typesetting engine
Page breaks in tablesEditor slows on complex templatesDocumented as a common issueHand-coded HTML and print CSSWord layout limitsHand-coded HTML and print CSSRow by row, with frame repair
Repeating headersNot documentedNot documentedHand-codedNot documentedHand-codedMulti-row, colSpan preserved
Nested tables in cellsNot documentedOne nesting levelPossible in HTMLWord layout limitsPossible in HTMLYes, grid integrity validated
Conditional columnsNot documentedNot documentedHand-codedNot documentedHand-codedYes, with automatic span shrink
Regression gate on layoutNone publishedNone publishedNone publishedNone publishedNone published21 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.