Report viewer · banded reports

A banded report engine and viewer: groups with totals, headers that repeat on the next page, rows that grow to fit their text, charts, barcodes and QR codes, subreports, conditional styles and Page x of y. Find text, fill in parameters (⚙ on the sales report), export CSV or HTML, and print. Only the pages near the view are drawn, so try 20,000 rows. The layout engine has no DOM, so it can also run on a server.

Sales by region
GRAND TOTAL
$1,304,028.89
Orders from Jan 1 to Sep 27, 2026 · 240 orders · 13 countries
Sales by region0200k400k600kAmericas$452,002Asia Pacific$436,337Europe$415,690
Sales by month050k100k150k200k87.7k165.87k132.18k182.63k181k159.25k156.1k99.67k139.62kJanFebMarAprMayJunJulAugSep
#
DATE
REP
PRODUCT
QTY
AMOUNT
RUNNING
Americas
82 orders · $452,002
Brazil
1144
Jan 14
F. Silva
Designer add-on
12
2,076.55
2,076.55
1203
Feb 22
F. Silva
Templates pack
12
1,047.68
3,124.23
1048
Mar 07
F. Silva
Support plan
12
10,438.26
13,562.49
1210
Apr 12
D. Chen
Workshop day
1
1,305.33
14,867.82
1111
Apr 16
A. Yılmaz
Designer add-on
5
1,020.28
15,888.10
1155
May 02
C. Martin
Workshop day
7
7,600.09
23,488.19
1183
May 09
D. Chen
Workshop day
8
8,383.84
31,872.03
1085
Jun 06
F. Silva
Designer add-on
2
333.76
32,205.79
1130
Jun 12
F. Silva
Support plan
2
1,993.28
34,199.07
1186
Jun 20
B. Kaya
Support plan
9
8,160.08
42,359.15
1191
Jul 10
B. Kaya
Team licence
8
19,597.16
61,956.31
1156
Jul 11
A. Yılmaz
Designer add-on
8
1,304.70
63,261.01
1212
Jul 17
A. Yılmaz
Designer add-on
2
320.73
63,581.74
1102
Jul 19
E. Novak
Designer add-on
1
188.08
63,769.82
1205
Sep 06
B. Kaya
Team licence
5
13,786.90
77,556.72
1232
Sep 14
E. Novak
Designer add-on
4
818.71
78,375.43
1231
Sep 19
E. Novak
Support plan
9
9,920.64
88,296.07
Brazil: 17 orders
$88,296.07
Canada
1038
Feb 07
F. Silva
Support plan
8
8,526.97
8,526.97
1220
Feb 12
F. Silva
Designer add-on
10
1,539.49
10,066.46
1081
Feb 15
A. Yılmaz
Workshop day
2
2,198.49
12,264.95
1174
Feb 15
A. Yılmaz
Team licence
8
19,088.43
31,353.38
1207
Feb 20
D. Chen
Support plan
11
9,857.37
41,210.75
1214
Mar 06
F. Silva
Team licence
6
14,700.76
55,911.51
1151
Mar 27
F. Silva
Workshop day
10
10,744.28
66,655.79
1013
Apr 03
C. Martin
Designer add-on
7
1,354.72
68,010.51
1233
Apr 08
A. Yılmaz
Designer add-on
10
2,010.04
70,020.55
1225
Apr 11
A. Yılmaz
Support plan
2
1,993.94
72,014.49
Printed Sep 23, 2026 12:01
This page: 27 orders · $160,310.56
Page 1 of 7
#
DATE
REP
PRODUCT
QTY
AMOUNT
RUNNING
Americas (continued)
82 orders · $452,002
Canada (continued)
1021
Apr 18
B. Kaya
Team licence
11
25,155.26
97,169.75
1072
May 04
A. Yılmaz
Team licence
11
28,986.65
126,156.40
1181
May 19
A. Yılmaz
Designer add-on
3
491.82
126,648.22
1093
May 26
C. Martin
Support plan
8
7,180.07
133,828.29
1158
Jun 02
E. Novak
Team licence
12
30,692.99
164,521.28
1177
Jun 18
D. Chen
Designer add-on
6
1,199.50
165,720.78
1153
Jun 25
C. Martin
Support plan
4
3,981.42
169,702.20
1062
Jul 12
D. Chen
Templates pack
9
763.71
170,465.91
1184
Jul 26
A. Yılmaz
Support plan
1
896.32
171,362.23
1044
Aug 01
B. Kaya
Designer add-on
11
2,245.99
173,608.22
1219
Aug 01
C. Martin
Templates pack
2
179.40
173,787.62
1209
Aug 12
D. Chen
Templates pack
1
102.46
173,890.08
1213
Sep 05
B. Kaya
Workshop day
2
2,130.43
176,020.51
Canada: 23 orders
$176,020.51
Mexico
1196
Jan 01
C. Martin
Team licence
1
2,409.97
2,409.97
1043
Jan 04
E. Novak
Workshop day
7
7,157.08
9,567.05
1133
Jan 05
D. Chen
Designer add-on
3
549.99
10,117.04
1046
Jan 25
C. Martin
Team licence
6
13,569.41
23,686.45
1007
Feb 08
D. Chen
Templates pack
6
568.76
24,255.21
1061
Feb 20
B. Kaya
Designer add-on
11
1,725.30
25,980.51
1058
Feb 26
E. Novak
Team licence
1
2,387.88
28,368.39
1166
Feb 27
F. Silva
Templates pack
12
1,281.08
29,649.47
1109
Apr 01
E. Novak
Team licence
9
21,028.27
50,677.74
1027
Apr 16
F. Silva
Workshop day
4
4,768.90
55,446.64
1223
Apr 19
E. Novak
Templates pack
9
974.84
56,421.48
1150
Apr 22
B. Kaya
Workshop day
10
12,770.12
69,191.60
1064
May 03
E. Novak
Workshop day
1
1,119.96
70,311.56
1096
Jun 10
D. Chen
Workshop day
3
3,095.09
73,406.65
1123
Jun 10
B. Kaya
Templates pack
9
744.95
74,151.60
1122
Jun 18
C. Martin
Templates pack
7
581.31
74,732.91
1086
Jul 02
E. Novak
Designer add-on
6
925.26
75,658.17
1163
Jul 02
B. Kaya
Support plan
4
3,839.62
79,497.79
1015
Jul 13
F. Silva
Templates pack
1
86.35
79,584.14
1175
Jul 18
E. Novak
Team licence
5
11,393.88
90,978.02
1097
Jul 21
D. Chen
Templates pack
1
104.76
91,082.78
1228
Aug 15
F. Silva
Designer add-on
7
1,129.63
92,212.41
1024
Sep 01
B. Kaya
Templates pack
6
558.14
92,770.55
Mexico: 23 orders
$92,770.55
United States
1141
Jan 15
D. Chen
Templates pack
10
1,022.40
1,022.40
1063
Feb 09
E. Novak
Designer add-on
2
330.67
1,353.07
1105
Feb 09
F. Silva
Workshop day
5
5,562.24
6,915.31
1083
Feb 18
A. Yılmaz
Templates pack
1
84.58
6,999.89
Printed Sep 23, 2026 12:01
This page: 40 orders · $203,776.46
Page 2 of 7
#
DATE
REP
PRODUCT
QTY
AMOUNT
RUNNING
Americas (continued)
82 orders · $452,002
United States (continued)
1131
Feb 22
D. Chen
Support plan
9
9,763.44
16,763.33
1012
Feb 25
E. Novak
Designer add-on
5
953.92
17,717.25
1074
May 11
A. Yılmaz
Support plan
11
9,491.22
27,208.47
1087
May 20
E. Novak
Templates pack
7
724.98
27,933.45
1070
May 21
A. Yılmaz
Workshop day
9
11,451.71
39,385.16
1206
Jun 04
E. Novak
Designer add-on
7
1,409.16
40,794.32
1159
Jun 16
A. Yılmaz
Team licence
11
22,902.85
63,697.17
1068
Jun 27
A. Yılmaz
Templates pack
12
1,263.64
64,960.81
1006
Jul 09
F. Silva
Designer add-on
7
1,307.47
66,268.28
1020
Jul 13
F. Silva
Team licence
9
18,909.62
85,177.90
1067
Aug 16
B. Kaya
Designer add-on
6
934.25
86,112.15
1176
Aug 21
F. Silva
Team licence
2
5,165.34
91,277.49
1202
Aug 22
B. Kaya
Workshop day
2
2,192.39
93,469.88
1146
Sep 09
C. Martin
Designer add-on
3
616.65
94,086.53
1120
Sep 21
A. Yılmaz
Designer add-on
5
828.74
94,915.27
United States: 19 orders
$94,915.27
Americas total — 82 orders, avg $5,512.22
$452,002.40
34.7% of all sales
Asia Pacific
76 orders · $436,337
Australia
1200
Jan 05
B. Kaya
Designer add-on
12
2,246.02
2,246.02
1135
Feb 22
D. Chen
Designer add-on
8
1,386.78
3,632.80
1169
Mar 06
D. Chen
Designer add-on
1
163.83
3,796.63
1032
Mar 08
C. Martin
Templates pack
6
606.72
4,403.35
1208
Mar 23
C. Martin
Team licence
7
16,300.59
20,703.94
1182
May 03
F. Silva
Team licence
9
22,932.75
43,636.69
1121
May 11
D. Chen
Designer add-on
11
2,114.19
45,750.88
1049
May 24
B. Kaya
Support plan
2
1,647.39
47,398.27
1164
May 26
C. Martin
Templates pack
9
836.11
48,234.38
1108
Jun 16
B. Kaya
Support plan
9
9,358.40
57,592.78
1204
Jul 02
F. Silva
Support plan
6
6,264.02
63,856.80
1112
Jul 05
A. Yılmaz
Designer add-on
10
1,633.10
65,489.90
1211
Jul 09
F. Silva
Workshop day
8
9,353.38
74,843.28
1010
Aug 06
F. Silva
Templates pack
4
404.50
75,247.78
1185
Aug 07
B. Kaya
Workshop day
5
5,246.56
80,494.34
1003
Aug 11
A. Yılmaz
Support plan
6
6,190.51
86,684.85
1004
Sep 04
C. Martin
Designer add-on
3
476.50
87,161.35
1025
Sep 04
A. Yılmaz
Designer add-on
2
364.49
87,525.84
Australia: 18 orders
$87,525.84
India
1218
Jan 09
E. Novak
Designer add-on
7
1,100.15
1,100.15
1110
Jan 10
D. Chen
Support plan
2
1,702.60
2,802.75
Printed Sep 23, 2026 12:01
This page: 35 orders · $178,243.97
Page 3 of 7

Usage

JavaScript
import { ReportViewer } from "./components/report/viewer.js"; // A report is plain JSON: bands of positioned elements, in mm. Text holds// expressions in braces, with an optional format after the colon.const report = {  title: "Sales by region",  page: { size: "A4", margins: 14 },  dataSource: "orders",  parameters: [{ name: "minAmount", default: 0 }],  filter: "amount >= Param.minAmount",  groups: [{    name: "region", by: "region",    header: { height: 8, repeat: true, elements: [      { x: 0, y: 0, w: 180, h: 8, text: "{region}{iif(Repeated, ' (continued)', '')}", bold: true } ] },    footer: { height: 7, elements: [      { x: 100, y: 0, w: 80, h: 7, text: "{Sum(amount):C2}", align: "right", bold: true } ] },  }],  bands: {    pageHeader:   { height: 7, elements: [{ x: 0, y: 0, w: 60, h: 7, text: "DATE", bold: true }] },    detail:       { height: 5, stripe: "#f8fafc", elements: [      { x: 0,  y: 0, w: 60, h: 5, text: "{date:MMM dd}" },      { x: 60, y: 0, w: 80, h: 5, text: "{product}" },          // long text grows the row      { x: 140, y: 0, w: 40, h: 5, text: "{amount:N2}", align: "right" } ] },    reportFooter: { height: 10, elements: [{ x: 0, y: 2, w: 180, h: 8, text: "Total {Sum(amount):C2}", bold: true }] },    pageFooter:   { height: 6, elements: [{ x: 0, y: 0, w: 180, h: 6, text: "Page {Page} of {Pages}", align: "right" }] },  },}; const minAmount = signal(0);ReportViewer({ report, data: { orders }, params: () => ({ minAmount: minAmount() }), height: "780px" });// data may be a promise; report / data / params may be getters — the viewer lays out again when they change.// Sum · Count · Avg · Min · Max · DistinctCount · RunningSum over the group, 'page' or 'report'.// Formats: C2 N0 P1 F2 · dd.MM.yyyy · MMM d · custom "#,##0.00". Print → the browser's print / Save as PDF. // More element types:{ type: "chart", chart: "hbar", category: "region", value: "amount", sort: "-value", format: "C0", x: 0, y: 20, w: 90, h: 50 }{ type: "barcode", symbology: "code128" | "ean13" | "qr", value: "{no}", x: 96, y: 5, w: 52, h: 16 }{ type: "subreport", source: "lines", report: { bands: { detail: {} } }, x: 4, y: 31, w: 174, h: 20 }{ x: 130, y: 0, w: 26, h: 5, text: "{amount:N2}", conditions: [{ when: "amount >= 15000", style: { color: "#15803d", bold: true } }] }// parameters: [{ name: "minAmount", label: "Minimum amount", type: "number", default: 0 }]  → the ⚙ Parameters form