@tipp/pdf-builder
v1.0.8
Published
pdfmake 기반 PDF 생성 라이브러리 - metaJson + data를 받아 PDF Buffer 생성
Downloads
1,516
Readme
@tipp/pdf-builder
pdfmake 기반 PDF 생성 라이브러리입니다. metaJson과 data를 받아 PDF Buffer를 생성합니다.
특징
- 메타 기반 PDF 생성: JSON 형태의 메타 정보로 PDF 문서를 정의
- 데이터 바인딩:
{{path}}템플릿과$path바인딩 지원 - 컴포넌트 아키텍처: 재사용 가능한 컴포넌트 시스템
- 페이지 분할: 멀티 페이지 및 페이지 구분 지원
- 커스텀 프리셋: 문서 스타일 프리셋 및 푸터 프리셋
설치
pnpm add @tipp/pdf-builder빠른 시작
import { buildPdf, registerDefaultComponents } from '@tipp/pdf-builder';
import type { PdfMeta } from '@tipp/pdf-builder';
// 기본 컴포넌트 등록
registerDefaultComponents();
// PDF 메타 정의
const meta: PdfMeta = {
pages: [
{
sections: [
{
type: 'sectionHeading',
config: { text: 'Hello World', level: 1 },
},
{
type: 'paragraph',
config: { text: '{{greeting}}' },
},
],
},
],
};
// 데이터
const data = {
greeting: 'Welcome to PDF Builder!',
};
// PDF 생성
const buffer = await buildPdf(meta, data);
// 파일로 저장
fs.writeFileSync('output.pdf', buffer);핵심 개념
PdfMeta 구조
type PdfMeta = {
docPreset?: string; // 문서 프리셋 ('default' 등)
defaultStyle?: Style; // 기본 스타일
styles?: StyleDictionary; // 커스텀 스타일
pages: PageConfig[]; // 페이지 목록
};
type PageConfig = {
layout?: PageLayout; // 페이지 레이아웃
pageBreak?: 'after' | 'before' | 'none';
sections: SectionConfig[]; // 섹션 목록
};
type SectionConfig = {
type: string; // 컴포넌트 타입
config: Record<string, unknown>; // 컴포넌트 설정
};참고:
SectionConfig는 커스텀 컴포넌트도 허용하기 때문에 최종적으로는type: string형태를 유지합니다.
다만 기본(built-in) 컴포넌트(table,sectionTitle,tableOfContents등)는type에 따라config타입이 자동완성되도록 구현되어 있습니다.
pageBreak를 생략하면 기본값은'after'로 동작합니다. (단, 마지막 페이지에는 자동으로'after'가 적용되지 않습니다.)
데이터 바인딩
- 템플릿 치환:
{{path.to.value}}형식으로 데이터 값을 문자열에 삽입 - 직접 바인딩:
$path.to.value형식으로 설정 값을 데이터에서 가져옴 - 배열 인덱스:
items.0.name형식으로 배열 요소 접근
// 데이터
const data = {
user: { name: 'John' },
items: ['First', 'Second'],
};
// 템플릿 치환
{ text: 'Hello, {{user.name}}!' } // => 'Hello, John!'
// 직접 바인딩
{ items: '$items' } // => ['First', 'Second']기본 컴포넌트
헤더
commonHeader- 문서 헤더 (제목, 부제목, 로고)sectionTitle- 섹션 타이틀 (번호 + 제목)
{
type: 'commonHeader',
config: {
title: '성과평가 피드백 분석 리포트',
subtitle: '성과평가 피드백 대화 모델 O-FEAR-S 기반',
},
}텍스트
text- 기본 텍스트paragraph- 단락sectionHeading- 섹션 헤딩 (레벨 1-4)
{ type: 'sectionHeading', config: { text: '요약', level: 2 } }
{ type: 'paragraph', config: { text: '{{report.summary}}' } }테이블
table- 통합 테이블 (DSL +layoutPreset)
기본 사용 예시
{
type: 'table',
config: {
widths: [60, '*'],
rows: [
[{ kind: 'label', text: '설명' }, { kind: 'value', text: '{{reportData.summary.comment}}' }],
[{ kind: 'label', text: '대화 예시' }, { kind: 'value', text: '{{reportData.skills.0.example1}}' }],
],
layoutPreset: 'gridThin',
margin: [0, 0, 0, 24],
},
}셀 DSL(rows) 요약
- 리터럴:
string | number | null(null은 rowSpan/colSpan placeholder 용도) - 객체:
{ kind, text, overrides }- kind:
label | value - overrides:
colSpan/rowSpan/alignment/fillColor/color/weight/fontSize/lineHeight/style/margin/decoration/borderOff등 최소 오버라이드
- kind:
layoutPreset
gridThin(기본): 얇은 gridnoBorders: border 제거
borderOff
- 기본은 grid이며, 특정 셀의 border를 끄려면
overrides.borderOff를 사용합니다. - 값은
['left' | 'top' | 'right' | 'bottom']배열입니다.
예제
examples/ 디렉토리에서 다양한 예제를 확인할 수 있습니다:
basic/- 기본 사용 예제coaching-report/- 코칭 리포트 형식 예제complex-layout/- 복잡한 레이아웃 예제ai-training-ofears-report/- AI Training O-FEAR-S 리포트 예제 (backend 리포트 구성 참고)ai-training-openfans-report/- AI Training OPEN FANS 리포트 예제 (backend 리포트 구성 참고)
# 예제 실행
npx tsx examples/basic/index.ts
# 코칭 리포트 예제 실행 (생성 파일: examples/coaching-report/output/coaching-report.pdf)
npx tsx examples/coaching-report/index.ts
# 복잡 레이아웃 예제 실행
npx tsx examples/complex-layout/index.ts
# AI Training O-FEAR-S 리포트 예제 실행
npx tsx examples/ai-training-ofears-report/index.ts
# AI Training OPEN FANS 리포트 예제 실행
npx tsx examples/ai-training-openfans-report/index.tsAPI 문서
자세한 API 문서는 docs/API.md를 참조하세요.
라이선스
MIT
