Skip to content

Matrix (cross-tab)

Two matrices over the same sales rows. The first groups revenue by region and product down the side and by month across the top, with a subtotal per region, a total per month and a grand total. The second shows units and revenue side by side for each region. A matrix is a table for screen readers: its column headers repeat on every page, and its row labels are row headers.

Standards: PDF/A-2b · PDF/UA-1, checked with veraPDF on every change. Download the PDF.

Page 1 of the matrix (cross-tab), rendered by Tagua.

The same report as an Excel workbook (download it), from tagua render matrix.report.yaml --out matrix.xlsx; see Excel export.

ABCDEFGHIJ
1Sales by region and month
2January to June 2026. Revenue in pounds sterling.
3Revenue by region, product and month
4RegionProductJanFebMarAprMayJunJan–Jun
5NorthBikes£11,760£15,960£20,160£14,700£18,900£23,100£104,580
6Helmets£2,340£2,860£1,885£2,405£2,925£1,950£14,365
7Lights£868£1,092£672£896£1,120£1,344£5,992
8Total£14,968£19,912£22,717£18,001£22,945£26,394£124,937
9SouthBikes£11,760£15,960£20,160£14,700£18,900£23,100£104,580
10Helmets£2,340£2,860£1,885£2,405£2,925£1,950£14,365
11Lights£868£1,092£672£896£1,120£1,344£5,992
12Total£14,968£19,912£22,717£18,001£22,945£26,394£124,937
13WestBikes£15,960£20,160£14,700£18,900£23,100£17,640£110,460
14Helmets£1,495£2,015£2,535£1,560£2,080£2,600£12,285
15Lights£1,148£728£952£1,176£756£980£5,740
16Total£18,603£22,903£18,187£21,636£25,936£21,220£128,485
17All regions£48,539£62,727£63,621£57,638£71,826£74,008£378,359
18Units and revenue by product and region
19NorthSouthWestAll regions
20ProductUnitsRevenueUnitsRevenueUnitsRevenueUnitsRevenue
21Bikes249£104,580249£104,580263£110,460761£319,620
22Helmets221£14,365221£14,365189£12,285631£41,015
23Lights214£5,992214£5,992205£5,740633£17,724
24All products684£124,937684£124,937657£128,4852,025£378,359
Sales by region and month
  • Nested row groups with subtotals and a grand total
  • A total column, and two values under each column group
  • Header and total styles
  • Tagged as a table with column and row headers (PDF/UA-1)
matrix.report.yaml
# yaml-language-server: $schema=../schema/template.schema.json
# Matrices (cross-tabs): the sales rows grouped down the side by region and product and across the top by month,
# with subtotals per region, a total per month and a grand total; then units and revenue side by side per region.
# A matrix is laid out and tagged as a table: its column headers repeat on each page, and its row labels are row
# headers for screen readers. PDF/A-2b and PDF/UA-1.
version: 1
title: Sales by region and month
culture: en-GB
document:
author: Acme Ltd
compliance: [pdf-a-2b, pdf-ua-1]
page:
size: A4
margins: 16mm
fonts:
Inter: { regular: fonts/Inter-Regular.ttf, bold: fonts/Inter-Bold.ttf }
styles:
default: { font: Inter, fontSize: 8.5pt, color: "#1F1F1F" }
head: { fontWeight: bold, color: "#6B6B6B", borderBottom: "0.75pt solid #1F1F1F", padding: 2pt 4pt 3pt 4pt }
total: { fontWeight: bold, background: "#F2F2F2", borderTop: "0.5pt solid #BDBDBD" }
cell: { padding: 2.5pt 4pt 2.5pt 4pt }
data:
sales:
fields: { Month: date, Region: string, Product: string, Revenue: decimal, Units: int32 }
body:
dataset: sales
reportHeader:
- padding: 0 0 12pt 0
content:
- { type: text, value: "Sales by region and month", fontSize: 18pt, fontWeight: bold, tag: h1 }
- { type: text, value: "January to June 2026. Revenue in pounds sterling.", color: "#6B6B6B" }
- padding: 0 0 18pt 0
content:
- { type: text, value: "Revenue by region, product and month", fontSize: 11pt, fontWeight: bold, tag: h2, padding: 0 0 6pt 0 }
- type: matrix
dataset: sales
sort: [Month]
headerStyle: head
totalStyle: total
rows:
- { group: "{Region}", header: Region, total: All regions, width: 70pt, style: cell }
- { group: "{Product}", header: Product, total: Total, width: 70pt, style: cell }
columns:
- { group: "{Month:MMM}", total: Jan–Jun }
values:
- { value: =Revenue, format: C0, style: cell }
- content:
- { type: text, value: "Units and revenue by product and region", fontSize: 11pt, fontWeight: bold, tag: h2, padding: 0 0 6pt 0 }
- type: matrix
dataset: sales
sort: [Product]
headerStyle: head
totalStyle: total
rows:
- { group: "{Product}", header: Product, total: All products, width: 90pt, style: cell }
columns:
- { group: "{Region}", total: All regions }
values:
- { header: Units, value: =Units, format: N0, style: cell }
- { header: Revenue, value: =Revenue, format: C0, style: cell }
detail: []
pageFooter:
- content:
- { type: text, value: "Page {PageNumber} of {TotalPages}", align: right, color: "#6B6B6B", fontSize: 8pt }

Save the template, put the fonts it names next to it (Inter and the Noto fonts are free, under the SIL Open Font License), and run:

Terminal window
tagua render matrix.report.yaml --open

Without a data file, tagua render makes up sample rows from the field types; see Preview as you edit.