매출 보고서
조회 조건, 지역별 그룹과 소계, 페이지 소계, 차트, 출력자·출력 일시 워터마크.
보고서 정의 (JSON)
{
"name": "지역별 매출 보고서",
"page": {
"size": "A4",
"margins": [
14,
15,
14,
15
]
},
"font": {
"family": "Nanum Gothic",
"size": 8.5
},
"params": {
"title": {
"label": "보고서 제목",
"type": "string",
"default": "2026년 3분기 지역별 매출 보고서"
},
"minAmount": {
"label": "최소 금액",
"type": "number",
"default": 0
},
"printedBy": {
"label": "출력자",
"type": "string",
"default": "홍길동"
}
},
"filter": "amount >= (params.minAmount ?? 0)",
"sort": [
"date"
],
"watermark": {
"text": "{params.printedBy} · {format(now(), \"yyyy-MM-dd HH:mm\")} 출력",
"repeat": true,
"opacity": 0.06,
"fontSize": 11,
"gap": 55
},
"bands": {
"title": {
"height": 30,
"elements": [
{
"type": "text",
"x": 0,
"y": 0,
"w": 180,
"h": 12,
"text": "{params.title}",
"style": {
"fontSize": 17,
"bold": true,
"align": "center"
}
},
{
"type": "text",
"x": 0,
"y": 13,
"w": 180,
"h": 6,
"text": "기간 2026-07-01 ~ 2026-09-30 · 대상 {count()}건 · 합계 {sum(amount):#,##0}원",
"style": {
"align": "center",
"color": "#4a5568"
}
}
]
},
"pageHeader": {
"height": 8,
"elements": [
{
"type": "text",
"x": 0,
"y": 0,
"w": 120,
"h": 6,
"text": "(주)세컨드코리아 · 영업관리팀",
"style": {
"color": "#6b7280",
"fontSize": 7.5
}
},
{
"type": "text",
"x": 120,
"y": 0,
"w": 60,
"h": 6,
"text": "{params.title}",
"style": {
"color": "#6b7280",
"fontSize": 7.5,
"align": "right"
}
},
{
"type": "line",
"x": 0,
"y": 6.5,
"w": 180,
"h": 0,
"color": "#c9d0da",
"width": 0.2
}
]
},
"columnHeader": {
"height": 7,
"elements": [
{
"x": 0,
"y": 0,
"w": 12,
"h": 7,
"type": "text",
"text": "번호",
"style": {
"bold": true,
"align": "center",
"background": "#eef1f6",
"border": "0.2 solid #8a94a6"
}
},
{
"x": 12,
"y": 0,
"w": 22,
"h": 7,
"type": "text",
"text": "일자",
"style": {
"bold": true,
"align": "center",
"background": "#eef1f6",
"border": "0.2 solid #8a94a6"
}
},
{
"x": 34,
"y": 0,
"w": 34,
"h": 7,
"type": "text",
"text": "거래처",
"style": {
"bold": true,
"align": "center",
"background": "#eef1f6",
"border": "0.2 solid #8a94a6"
}
},
{
"x": 68,
"y": 0,
"w": 42,
"h": 7,
"type": "text",
"text": "품목",
"style": {
"bold": true,
"align": "center",
"background": "#eef1f6",
"border": "0.2 solid #8a94a6"
}
},
{
"x": 110,
"y": 0,
"w": 14,
"h": 7,
"type": "text",
"text": "수량",
"style": {
"bold": true,
"align": "center",
"background": "#eef1f6",
"border": "0.2 solid #8a94a6"
}
},
{
"x": 124,
"y": 0,
"w": 24,
"h": 7,
"type": "text",
"text": "단가",
"style": {
"bold": true,
"align": "center",
"background": "#eef1f6",
"border": "0.2 solid #8a94a6"
}
},
{
"x": 148,
"y": 0,
"w": 32,
"h": 7,
"type": "text",
"text": "금액",
"style": {
"bold": true,
"align": "center",
"background": "#eef1f6",
"border": "0.2 solid #8a94a6"
}
}
]
},
"groups": [
{
"by": "region",
"sort": "asc",
"repeatHeader": true,
"keepWithRows": 2,
"header": {
"height": 7,
"elements": [
{
"type": "text",
"x": 0,
"y": 0,
"w": 180,
"h": 7,
"text": "■ {region} ({count()}건)",
"style": {
"bold": true,
"color": "#1a2fc0",
"border": {
"bottom": "0.3 solid #1a2fc0"
}
}
}
]
},
"footer": {
"height": 7.5,
"elements": [
{
"type": "text",
"x": 0,
"y": 0,
"w": 110,
"h": 7,
"text": "{region} 소계",
"style": {
"border": "0.15 solid #b9c1cd",
"bold": true,
"align": "center",
"background": "#f7f8fb"
}
},
{
"type": "field",
"x": 110,
"y": 0,
"w": 14,
"h": 7,
"expr": "sum(qty)",
"format": "#,##0",
"style": {
"border": "0.15 solid #b9c1cd",
"align": "right",
"bold": true,
"background": "#f7f8fb"
}
},
{
"type": "text",
"x": 124,
"y": 0,
"w": 24,
"h": 7,
"text": "",
"style": {
"border": "0.15 solid #b9c1cd",
"background": "#f7f8fb"
}
},
{
"type": "field",
"x": 148,
"y": 0,
"w": 32,
"h": 7,
"expr": "sum(amount)",
"format": "#,##0",
"style": {
"border": "0.15 solid #b9c1cd",
"align": "right",
"bold": true,
"background": "#f7f8fb"
}
}
]
}
}
],
"detail": {
"height": 6,
"altBackground": "#fafbfd",
"elements": [
{
"x": 0,
"y": 0,
"w": 12,
"h": 6,
"type": "field",
"expr": "rowNum",
"style": {
"border": "0.15 solid #b9c1cd",
"align": "center",
"color": "#6b7280"
}
},
{
"x": 12,
"y": 0,
"w": 22,
"h": 6,
"type": "field",
"expr": "date",
"format": "yyyy-MM-dd",
"style": {
"border": "0.15 solid #b9c1cd",
"align": "center"
}
},
{
"x": 34,
"y": 0,
"w": 34,
"h": 6,
"type": "field",
"expr": "customer",
"style": {
"border": "0.15 solid #b9c1cd"
}
},
{
"x": 68,
"y": 0,
"w": 42,
"h": 6,
"type": "field",
"expr": "product",
"style": {
"border": "0.15 solid #b9c1cd"
}
},
{
"x": 110,
"y": 0,
"w": 14,
"h": 6,
"type": "field",
"expr": "qty",
"format": "#,##0",
"style": {
"border": "0.15 solid #b9c1cd",
"align": "right"
}
},
{
"x": 124,
"y": 0,
"w": 24,
"h": 6,
"type": "field",
"expr": "price",
"format": "#,##0",
"style": {
"border": "0.15 solid #b9c1cd",
"align": "right"
}
},
{
"x": 148,
"y": 0,
"w": 32,
"h": 6,
"type": "field",
"expr": "amount",
"format": "#,##0",
"style": {
"border": "0.15 solid #b9c1cd",
"align": "right",
"bold": true
}
}
]
},
"summary": {
"height": 78,
"elements": [
{
"type": "text",
"x": 0,
"y": 2,
"w": 110,
"h": 8,
"text": "총 합계",
"style": {
"bold": true,
"align": "center",
"background": "#eef1f6",
"border": "0.2 solid #8a94a6",
"fontSize": 10
}
},
{
"type": "field",
"x": 110,
"y": 2,
"w": 14,
"h": 8,
"expr": "sum(qty)",
"format": "#,##0",
"style": {
"bold": true,
"align": "right",
"background": "#eef1f6",
"border": "0.2 solid #8a94a6"
}
},
{
"type": "text",
"x": 124,
"y": 2,
"w": 24,
"h": 8,
"text": "",
"style": {
"bold": true,
"align": "center",
"background": "#eef1f6",
"border": "0.2 solid #8a94a6"
}
},
{
"type": "field",
"x": 148,
"y": 2,
"w": 32,
"h": 8,
"expr": "sum(amount)",
"format": "#,##0",
"style": {
"bold": true,
"align": "right",
"background": "#eef1f6",
"border": "0.2 solid #8a94a6",
"fontSize": 10
}
},
{
"type": "chart",
"x": 0,
"y": 16,
"w": 112,
"h": 60,
"chartType": "bar",
"title": "지역별 매출",
"source": "groupSum(rows, \"region\", \"amount\")",
"category": "region",
"series": [
{
"expr": "amount",
"label": "매출"
}
],
"format": "#,##0,\"천\"",
"showValues": false
},
{
"type": "chart",
"x": 116,
"y": 16,
"w": 64,
"h": 60,
"chartType": "doughnut",
"title": "품목군 비중",
"source": "groupSum(rows, \"category\", \"amount\")",
"category": "category",
"series": [
{
"expr": "amount"
}
]
}
]
},
"pageFooter": {
"height": 9,
"elements": [
{
"type": "line",
"x": 0,
"y": 1,
"w": 180,
"h": 0,
"color": "#c9d0da",
"width": 0.2
},
{
"type": "text",
"x": 0,
"y": 2,
"w": 90,
"h": 6,
"text": "이 페이지 소계 {sum(amount, \"page\"):#,##0}원",
"style": {
"fontSize": 7.5,
"color": "#4a5568"
}
},
{
"type": "text",
"x": 90,
"y": 2,
"w": 90,
"h": 6,
"text": "{page} / {pages}",
"style": {
"fontSize": 7.5,
"align": "right",
"color": "#4a5568"
}
}
]
}
}
}데이터
긴 목록은 처음 3건만 보여 줍니다.
{
"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
},
"… 180 items"
]
}이 데모의 코드
import { makeSales } from '../../samples/data';
import { salesReport } from '../../samples/reports';
import { mountViewer, select, tr, type DemoContext } from '../ui';
/** 매출 보고서: parameters, region groups with subtotals, page subtotals, charts and a security watermark. */
export const definition = salesReport;
export const sampleData = { rows: makeSales(180) };
export default function mount(ctx: DemoContext) {
const viewer = mountViewer(ctx, { definition, data: sampleData, paramsOpen: true, fileName: '매출 보고서', toolbar: { csv: true } });
select(ctx, tr(ctx.lang, { en: 'Rows', ko: '건수' }), [['60', '60'], ['180', '180'], ['1000', '1,000']], '180', n => {
void viewer.setData({ rows: makeSales(Number(n)) });
});
}