Skip to main content
Tables display structured data in rows and columns with optional headers, styling, captions, and variable data binding.

Basic table

{
  "type": "table",
  "headers": ["Name", "Role", "Email"],
  "rows": [
    ["Alice", "Engineer", "alice@example.com"],
    ["Bob", "Designer", "bob@example.com"]
  ]
}

Properties

PropertyTypeRequiredDefaultDescription
typestringYesMust be "table"
idstringNoUnique identifier. Auto-generated if not provided. Max: 100 chars.
headersarrayNoHeader row cells. Max: 20 cells.
rowsarrayNoData rows. Each row is an array of cells. Max: 100 rows, 20 cells per row.
dataSourcestringNoBind to a table variable instead of inline rows. See Variable data binding.
mappingstring[]NoColumn keys to select from the data source. Max: 20 items.
captionstringNoCaption text for table numbering (e.g., "Revenue by quarter"). Max: 500 chars.
anchorstringNoAnchor ID for internal references (e.g., "tab-revenue"). Pattern: ^[a-zA-Z][a-zA-Z0-9_-]*$. Max: 100 chars.
invisiblebooleanNofalseHide all borders and backgrounds (borderless table).
hideHeadersbooleanNofalseHide the header row.
styleobjectNoInline table style override. See Table style.
spacingobjectNoSpacing override with before and after in pt (0–100).

Cell format

Each cell in headers and rows can be either a simple string or a cell object: Simple string:
["Alice", "Engineer", "alice@example.com"]
Cell object (for alignment or embedded images):
[
  { "text": "Alice", "align": "left" },
  { "text": "Engineer", "align": "center" },
  { "image": { "src": "https://example.com/photo.png", "width": 40, "height": 40 } }
]

Cell object properties

PropertyTypeDescription
textstringCell text content. Max: 1000 chars. Supports {{varName}} substitution.
imageobjectEmbedded cell image (see below).
alignstringCell alignment: "left", "center", or "right"

Cell image properties

PropertyTypeDescription
srcstringImage URL. Max: 2000 chars.
captionstringAlt text. Max: 200 chars.
widthnumberWidth in px (10–1000).
heightnumberHeight in px (10–1000).
When a cell contains exactly one {{varName}} reference that resolves to an image variable, the cell is automatically rendered as an image. See Variables — Image variables in table cells.

Variable data binding

Instead of defining rows inline, bind a table to a table variable via dataSource. Use mapping to select and reorder columns.
{
  "variables": {
    "employees": {
      "type": "table",
      "columns": ["name", "department", "email", "salary"],
      "data": [
        ["Alice", "Engineering", "alice@example.com", "$120k"],
        ["Bob", "Marketing", "bob@example.com", "$95k"]
      ]
    }
  },
  "sections": [{
    "type": "flow",
    "content": [{
      "type": "table",
      "headers": ["Name", "Department"],
      "dataSource": "employees",
      "mapping": ["name", "department"]
    }]
  }]
}
When mapping is provided, only the specified columns (matched by name against the variable’s columns) are included. Without mapping, all data columns are used as-is.

Table style

Override the default table styling inline via the style property. This has the same structure as defaults.styles.table.
{
  "type": "table",
  "headers": ["Plan", "Price"],
  "rows": [["Starter", "$9"], ["Pro", "$29"]],
  "style": {
    "borders": {
      "outer": { "width": 1, "color": "#000000", "style": "solid" },
      "inner": { "width": 0.5, "color": "#DDDDDD", "style": "solid" }
    },
    "header": {
      "backgroundColor": "#1a1a2e",
      "color": "#FFFFFF",
      "fontWeight": "bold"
    },
    "rows": {
      "alternateBackgroundColor": "#F5F5F5"
    },
    "cellPadding": { "top": 6, "right": 8, "bottom": 6, "left": 8 }
  }
}
borders.outer / borders.inner
PropertyTypeDescription
widthnumberBorder width in pt (0–10).
colorstringBorder color in hex.
stylestring"solid", "dashed", or "dotted"
header
PropertyTypeDescription
backgroundColorstringHeader background color in hex.
colorstringHeader text color in hex.
fontSizenumberHeader font size in pt (6–72).
fontWeightstring"normal" or "bold"
fontStylestring"normal" or "italic"
alignstring"left", "center", or "right"
rows
PropertyTypeDescription
backgroundColorstringRow background color in hex.
alternateBackgroundColorstringAlternate row background for striped tables.
colorstringRow text color in hex.
fontSizenumberRow font size in pt (6–72).
fontWeightstring"normal" or "bold"
fontStylestring"normal" or "italic"
alignstring"left", "center", or "right"
cellPadding
PropertyTypeDescription
topnumberTop padding in pt (0–50).
rightnumberRight padding in pt (0–50).
bottomnumberBottom padding in pt (0–50).
leftnumberLeft padding in pt (0–50).

Captions and anchors

Add a caption for automatic table numbering and an anchor for cross-referencing.
{
  "sections": [{
    "type": "flow",
    "content": [
      {
        "type": "table",
        "caption": "Quarterly revenue",
        "anchor": "tab-revenue",
        "headers": ["Q1", "Q2", "Q3", "Q4"],
        "rows": [["$100k", "$120k", "$115k", "$140k"]]
      },
      { "type": "text", "text": "As shown in [Table 1](#tab-revenue), revenue grew steadily." }
    ]
  }]
}
The caption prefix (e.g., “Table”) and style are controlled by defaults.styles.tableCaption. See Defaults — Table caption style.

Defaults

Tables without an inline style inherit from defaults.styles.table:
{
  "defaults": {
    "styles": {
      "table": {
        "borders": {
          "outer": { "width": 1, "color": "#000000" },
          "inner": { "width": 0.5, "color": "#DDDDDD" }
        },
        "header": { "backgroundColor": "#F0F0F0", "fontWeight": "bold" },
        "rows": { "alternateBackgroundColor": "#FAFAFA" },
        "cellPadding": { "top": 4, "right": 6, "bottom": 4, "left": 6 }
      },
      "tableCaption": { "fontSize": 9, "fontStyle": "italic", "prefix": "Table" }
    }
  }
}