100,000 rows
A list of 100,000 rows laid out into thousands of pages; pages are drawn as they scroll into view.
Report definition (JSON)
{
"name": "거래 내역 (대용량)",
"page": {
"size": "A4",
"margins": [
12,
12,
12,
12
]
},
"font": {
"family": "Nanum Gothic",
"size": 8
},
"bands": {
"pageHeader": {
"height": 9,
"elements": [
{
"type": "text",
"x": 0,
"y": 0,
"w": 120,
"h": 6,
"text": "거래 내역 · 2026년 3분기",
"style": {
"bold": true,
"fontSize": 10
}
},
{
"type": "text",
"x": 120,
"y": 0,
"w": 66,
"h": 6,
"text": "{page} / {pages}",
"style": {
"align": "right",
"color": "#4a5568"
}
}
]
},
"columnHeader": {
"height": 6.5,
"elements": [
{
"type": "text",
"x": 0,
"y": 0,
"w": 18,
"h": 6.5,
"text": "번호",
"style": {
"bold": true,
"align": "center",
"background": "#eef1f6",
"border": "0.2 solid #8a94a6"
}
},
{
"type": "text",
"x": 18,
"y": 0,
"w": 22,
"h": 6.5,
"text": "일자",
"style": {
"bold": true,
"align": "center",
"background": "#eef1f6",
"border": "0.2 solid #8a94a6"
}
},
{
"type": "text",
"x": 40,
"y": 0,
"w": 14,
"h": 6.5,
"text": "지역",
"style": {
"bold": true,
"align": "center",
"background": "#eef1f6",
"border": "0.2 solid #8a94a6"
}
},
{
"type": "text",
"x": 54,
"y": 0,
"w": 32,
"h": 6.5,
"text": "거래처",
"style": {
"bold": true,
"align": "center",
"background": "#eef1f6",
"border": "0.2 solid #8a94a6"
}
},
{
"type": "text",
"x": 86,
"y": 0,
"w": 40,
"h": 6.5,
"text": "품목",
"style": {
"bold": true,
"align": "center",
"background": "#eef1f6",
"border": "0.2 solid #8a94a6"
}
},
{
"type": "text",
"x": 126,
"y": 0,
"w": 14,
"h": 6.5,
"text": "수량",
"style": {
"bold": true,
"align": "center",
"background": "#eef1f6",
"border": "0.2 solid #8a94a6"
}
},
{
"type": "text",
"x": 140,
"y": 0,
"w": 46,
"h": 6.5,
"text": "금액",
"style": {
"bold": true,
"align": "center",
"background": "#eef1f6",
"border": "0.2 solid #8a94a6"
}
}
]
},
"detail": {
"height": 5.5,
"canGrow": false,
"altBackground": "#fafbfd",
"elements": [
{
"type": "field",
"x": 0,
"y": 0,
"w": 18,
"h": 5.5,
"expr": "no",
"format": "#,##0",
"style": {
"border": "0.15 solid #c9d0da",
"wrap": false,
"align": "right",
"color": "#6b7280"
}
},
{
"type": "field",
"x": 18,
"y": 0,
"w": 22,
"h": 5.5,
"expr": "date",
"style": {
"border": "0.15 solid #c9d0da",
"wrap": false,
"align": "center"
}
},
{
"type": "field",
"x": 40,
"y": 0,
"w": 14,
"h": 5.5,
"expr": "region",
"style": {
"border": "0.15 solid #c9d0da",
"wrap": false,
"align": "center"
}
},
{
"type": "field",
"x": 54,
"y": 0,
"w": 32,
"h": 5.5,
"expr": "customer",
"style": {
"border": "0.15 solid #c9d0da",
"wrap": false
}
},
{
"type": "field",
"x": 86,
"y": 0,
"w": 40,
"h": 5.5,
"expr": "product",
"style": {
"border": "0.15 solid #c9d0da",
"wrap": false
}
},
{
"type": "field",
"x": 126,
"y": 0,
"w": 14,
"h": 5.5,
"expr": "qty",
"format": "#,##0",
"style": {
"border": "0.15 solid #c9d0da",
"wrap": false,
"align": "right"
}
},
{
"type": "field",
"x": 140,
"y": 0,
"w": 46,
"h": 5.5,
"expr": "amount",
"format": "#,##0",
"style": {
"border": "0.15 solid #c9d0da",
"wrap": false,
"align": "right"
}
}
]
},
"summary": {
"height": 8,
"elements": [
{
"type": "text",
"x": 0,
"y": 1,
"w": 126,
"h": 7,
"text": "총 합계 ({count(no):#,##0}건)",
"style": {
"bold": true,
"align": "center",
"background": "#eef1f6",
"border": "0.2 solid #8a94a6"
}
},
{
"type": "field",
"x": 126,
"y": 1,
"w": 14,
"h": 7,
"expr": "sum(qty)",
"format": "#,##0",
"style": {
"bold": true,
"align": "right",
"background": "#eef1f6",
"border": "0.2 solid #8a94a6"
}
},
{
"type": "field",
"x": 140,
"y": 1,
"w": 46,
"h": 7,
"expr": "sum(amount)",
"format": "#,##0",
"style": {
"bold": true,
"align": "right",
"background": "#eef1f6",
"border": "0.2 solid #8a94a6"
}
}
]
},
"pageFooter": {
"height": 7,
"elements": [
{
"type": "text",
"x": 0,
"y": 1.5,
"w": 120,
"h": 5,
"text": "이 페이지 {count(no, \"page\")}건 · 소계 {sum(amount, \"page\"):#,##0}원",
"style": {
"fontSize": 7.5,
"color": "#4a5568"
}
}
]
}
}
}Data
Long lists show their first three items.
{
"rows": [
{
"no": 1,
"date": "2026-09-28",
"region": "대구",
"customer": "다온상사",
"manager": "정하준",
"product": "노트북 15형",
"category": "전자",
"qty": 1,
"price": 1290000,
"amount": 1290000
},
{
"no": 2,
"date": "2026-07-21",
"region": "서울",
"customer": "새봄디자인",
"manager": "강서윤",
"product": "무선 키보드",
"category": "주변기기",
"qty": 7,
"price": 59000,
"amount": 413000
},
{
"no": 3,
"date": "2026-08-09",
"region": "경기",
"customer": "온누리건설",
"manager": "박도윤",
"product": "27형 모니터",
"category": "전자",
"qty": 5,
"price": 349000,
"amount": 1745000
}
]
}Code for this demo
import type { ReportDefinition, Style } from '@freereportjs/core';
import { makeSales } from '../../samples/data';
import { mountViewer, select, tr, type DemoContext } from '../ui';
/**
* A plain transaction list: column header on every page, page subtotals, a grand total, page x / y.
* Page bands only aggregate over the page ("page" scope), so each page costs the same however long the list is.
*/
const th: Style = { bold: true, align: 'center', background: '#eef1f6', border: '0.2 solid #8a94a6' };
const td: Style = { border: '0.15 solid #c9d0da', wrap: false };
const num: Style = { ...td, align: 'right' };
export const definition: ReportDefinition = {
name: '거래 내역 (대용량)',
page: { size: 'A4', margins: [12, 12, 12, 12] },
font: { family: 'Nanum Gothic', size: 8 },
bands: {
pageHeader: {
height: 9,
elements: [
{ type: 'text', x: 0, y: 0, w: 120, h: 6, text: '거래 내역 · 2026년 3분기', style: { bold: true, fontSize: 10 } },
{ type: 'text', x: 120, y: 0, w: 66, h: 6, text: '{page} / {pages}', style: { align: 'right', color: '#4a5568' } },
],
},
columnHeader: {
height: 6.5,
elements: [
{ type: 'text', x: 0, y: 0, w: 18, h: 6.5, text: '번호', style: th },
{ type: 'text', x: 18, y: 0, w: 22, h: 6.5, text: '일자', style: th },
{ type: 'text', x: 40, y: 0, w: 14, h: 6.5, text: '지역', style: th },
{ type: 'text', x: 54, y: 0, w: 32, h: 6.5, text: '거래처', style: th },
{ type: 'text', x: 86, y: 0, w: 40, h: 6.5, text: '품목', style: th },
{ type: 'text', x: 126, y: 0, w: 14, h: 6.5, text: '수량', style: th },
{ type: 'text', x: 140, y: 0, w: 46, h: 6.5, text: '금액', style: th },
],
},
detail: {
height: 5.5,
canGrow: false,
altBackground: '#fafbfd',
elements: [
{ type: 'field', x: 0, y: 0, w: 18, h: 5.5, expr: 'no', format: '#,##0', style: { ...num, color: '#6b7280' } },
{ type: 'field', x: 18, y: 0, w: 22, h: 5.5, expr: 'date', style: { ...td, align: 'center' } },
{ type: 'field', x: 40, y: 0, w: 14, h: 5.5, expr: 'region', style: { ...td, align: 'center' } },
{ type: 'field', x: 54, y: 0, w: 32, h: 5.5, expr: 'customer', style: td },
{ type: 'field', x: 86, y: 0, w: 40, h: 5.5, expr: 'product', style: td },
{ type: 'field', x: 126, y: 0, w: 14, h: 5.5, expr: 'qty', format: '#,##0', style: num },
{ type: 'field', x: 140, y: 0, w: 46, h: 5.5, expr: 'amount', format: '#,##0', style: num },
],
},
summary: {
height: 8,
elements: [
{ type: 'text', x: 0, y: 1, w: 126, h: 7, text: '총 합계 ({count(no):#,##0}건)', style: th },
{ type: 'field', x: 126, y: 1, w: 14, h: 7, expr: 'sum(qty)', format: '#,##0', style: { ...th, align: 'right' } },
{ type: 'field', x: 140, y: 1, w: 46, h: 7, expr: 'sum(amount)', format: '#,##0', style: { ...th, align: 'right' } },
],
},
pageFooter: {
height: 7,
elements: [
{ type: 'text', x: 0, y: 1.5, w: 120, h: 5, text: '이 페이지 {count(no, "page")}건 · 소계 {sum(amount, "page"):#,##0}원', style: { fontSize: 7.5, color: '#4a5568' } },
],
},
},
};
export const sampleData = { rows: makeSales(3) };
export default function mount(ctx: DemoContext) {
const open = (n: number) => {
const t0 = performance.now();
const rows = makeSales(n);
ctx.log(tr(ctx.lang, { en: `${n.toLocaleString('en')} rows generated in ${Math.round(performance.now() - t0)} ms; laying out pages…`, ko: `${n.toLocaleString('ko')}건 생성 ${Math.round(performance.now() - t0)}ms · 페이지를 나누는 중…` }));
return rows;
};
const viewer = mountViewer(ctx, { definition, data: { rows: open(100_000) }, fileName: '거래 내역' });
select(ctx, tr(ctx.lang, { en: 'Rows', ko: '건수' }), [['10000', '10,000'], ['50000', '50,000'], ['100000', '100,000']], '100000', n => {
void viewer.setData({ rows: open(Number(n)) });
});
}