Skip to main content
The table block renders rows, optional headers, optional column sizing, and an optional style.
{ type: "table", rows: TableRow[], headers?: TableRow, columns?: number | number[], style?: StyleProperties }

Rows and cells

A row is an array of cells, and a cell is either a string or a TableCell.
type TableCell = { text: InlineContent; align?: "left" | "center" | "right" };
type TableRow = Array<string | TableCell>;
A cell text accepts inline content, so bold, links, and inline formulas all work inside cells. See Inline content for the full set of inline nodes.
doc.page().content({
  type: "table",
  headers: ["Metric", "Q3", "Q4"],
  rows: [
    ["Revenue", "1.2M", { text: { type: "strong", text: "1.6M" }, align: "right" }],
    ["Margin", "18%", { text: "24%", align: "right" }],
  ],
});

Column sizing

The columns field is optional and controls how column widths are computed.
columns
number | number[]
Omit it to size columns equally from the header or first row. Set it to a count for equal columns, or to an array of absolute widths in points where 0 means auto.
Columns are sized equally, derived from the header row or the first data row.
A count produces that many equal width columns.
{ type: "table", columns: 3, headers: ["A", "B", "C"], rows: [["1", "2", "3"]] }
Each entry is an absolute width in points. A 0 entry is sized automatically from the remaining space.
{ type: "table", columns: [180, 0, 100], rows: [["Name", "Description", "Total"]] }
Array values are absolute widths in points, not fractional weights. [2, 1, 1] means 2pt, 1pt, 1pt, not a 2:1:1 ratio.