Documentation
Creating PDFs
PDFs in Vue
PDFs in Nuxt
PDFs in React
PDFs in Angular
Columns since beta.5
Text that runs down one column and continues in the next, then on the next page. SplitView is the
ready-made newspaper. Flow and Region build any other layout: a title area, a sidebar, columns of
different widths.
Everything inside paginates as it does on a page. A paragraph splits at its lines, a table repeats its
header, keepTogether holds, orphans and widows count.
Newspaper columns
import { Document, Page, Text, SplitView } from "@jasy/pdf";
Document([
Page({ size: "A4", margin: 56, gap: 12 }, [
Text("The Valley Courier", { size: 28, bold: true, color: "#1450aa" }),
SplitView({ columns: 3, colGap: 16, rowGap: 8 }, paragraphs),
Text("This line follows the columns, right where they end.", { italic: true }),
]),
]);
The content fills the first column, then the next, then the next page. On its last page the columns balance: they come out about equally tall, as CSS columns do, and what follows sits right below them.
| Option | Default | What it does |
|---|---|---|
columns | 2 | how many columns, side by side and equally wide |
gap | 0 | space between the columns and between the content's elements |
colGap | gap | space between the columns |
rowGap | gap | space between the content's elements |
balance | true | equal columns on the last page; false fills one column, then the next |
Breaking to the next column
ColumnBreak() starts the next column. From the last column, it starts the first one on the next page.
SplitView({ columns: 2, gap: 16 }, [
Text("Summary", { bold: true }),
Text(summary),
ColumnBreak(),
Text("Details", { bold: true }),
Text(details),
]);
A ColumnBreak outside a column (in a Row, a table row, or no column at all) does nothing, and
reports it once as column-break-ignored. To start a new page, use PageBreak.
A layout of your own
Flow takes a template: a function that builds one page of the layout. Put a Region wherever the
content should go. The content fills the Regions in the order they appear, then continues on the next
page with a fresh template.
import { Document, Page, Column, Row, Box, Text, Expanded, Flow, Region } from "@jasy/pdf";
Document([
Page({ size: "A4", margin: 56 }, [
Flow(
{
gap: 8,
template: ({ index }) =>
Column({ gap: 12 }, [
index === 0
? Text("Annual Report", { size: 22, bold: true, color: "#1450aa" })
: Text("Annual Report, continued", { size: 9, italic: true, color: "gray" }),
Row({ gap: 16 }, [
Expanded(Region()),
Box({ bg: "#f3f5f9", padding: 8 }, [Region({ width: 150 })]),
]),
]),
},
report,
),
]),
]);
The template gets { index, pageNumber }: index counts the pages of this Flow from 0, so the first
page can carry the title and the others a running head. A ColumnBreak in the content moves on to the
sidebar.
A Region is sized by the layout around it, like any element: Expanded, a width or height in
points or %, min and max. With nothing given, it fills what it is offered.
Flow option | Default | What it does |
|---|---|---|
template | - | ({ index, pageNumber }) => element, built for every page |
gap | 0 | space between the content's elements |
balance | false | on the last page, spread the content so the Regions end about equal |
A SplitView is exactly this: a Flow whose template is a Row of Expanded(Region()).
Where a Flow gets its height
A Flow has no height of its own. It takes the rest of the page, or the height of the box it sits in. On its last page it shrinks to what the content used, so whatever follows sits right below.
In a box with a fixed height, the Flow cannot continue on the next page. What does not fit is cut off
and handled by onOverflow, like any other block that is too tall.
What jasy refuses
A mistake in a layout like this would otherwise lose content without a word. Each one throws a named error that says what to change:
| Error | When |
|---|---|
FlowWithoutRegionError | the template holds no Region, so the content has nowhere to go |
RegionOutsideFlowError | a Region in the content, or anywhere outside a template |
RegionReusedError | one Region on two pages - build the Regions inside the template function |
FlowUnboundedError | the Flow has no height to take, e.g. in a Row without a height |
FlowRegionsEmptyError | every Region ends up 0 wide or 0 tall |
RegionInPageBuilderError | a Region inside a PageBuilder, which builds again for every page |
In Vue, the template is the #page slot - see Components. In React,
it is the page render prop - see Components.