🇺🇸 English version

Excel 보고서 생성, 아직도 POI로 한 땀 한 땀 작성하시나요?

JVM 환경에서 Excel 보고서를 만들어 본 개발자라면 Apache POI의 고통을 잘 알고 있을 것입니다.

// Apache POI로 직접 작성하면...
val workbook = XSSFWorkbook()
val sheet = workbook.createSheet("직원 현황")
val headerRow = sheet.createRow(0)
headerRow.createCell(0).setCellValue("이름")
headerRow.createCell(1).setCellValue("직급")
headerRow.createCell(2).setCellValue("연봉")

employees.forEachIndexed { index, emp ->
    val row = sheet.createRow(index + 1)
    row.createCell(0).setCellValue(emp.name)
    row.createCell(1).setCellValue(emp.position)
    row.createCell(2).setCellValue(emp.salary.toDouble())
}

// 열 폭 조정, 스타일 적용, 수식 추가, 차트... 끝이 없음

헤더 하나 만들고, 셀 하나 채우고, 스타일 적용하고... 보고서 하나에 수백 줄의 코드가 필요합니다.
거기에 차트, 조건부 서식, 수식, 이미지까지 추가하면? 코드는 걷잡을 수 없이 불어납니다.

TBEG (Template Based Excel Generator) 은 이 문제를 근본적으로 해결합니다.


TBEG이란?

Excel 템플릿에 데이터를 바인딩하여 보고서를 생성하는 JVM 라이브러리입니다.

핵심 아이디어는 간단합니다:
1. 디자이너(또는 본인)가 Excel에서 직접 보고서 양식을 디자인합니다
2. 데이터가 들어갈 자리에 ${변수명} 마커를 넣습니다
3. 코드에서는 데이터만 전달합니다
4. TBEG이 템플릿 + 데이터를 결합하여 최종 보고서를 생성합니다

// TBEG 사용 - 이게 전부입니다
val data = mapOf(
    "title" to "직원 현황",
    "employees" to employeeList
)

ExcelGenerator().use { generator ->
    val bytes = generator.generate(template, data)
    File("output.xlsx").writeBytes(bytes)
}

서식, 차트, 수식, 조건부 서식은 모두 템플릿에서 관리합니다. 코드는 데이터 바인딩에만 집중합니다.


설계 철학

Excel이 이미 잘하는 기능은 재구현하지 않고 그대로 살립니다.

  • 집계는 엑셀의 수식=SUM()으로, 평균은 =AVERAGE()
  • 조건부 강조는 조건부 서식으로
  • 시각화는 차트로

익숙한 Excel 기능을 그대로 활용하세요.
TBEG은 여기에 동적 데이터 바인딩을 더하고, 데이터가 확장되어도 이 기능들이 의도대로 동작하도록 자동 조정합니다.


한 눈에 보기

템플릿

템플릿

코드

val data = simpleDataProvider {
    value("reportTitle", "Q1 2026 매출 실적 보고서")
    value("period", "2026년 1월 ~ 3월")
    value("author", "황용호")
    value("reportDate", LocalDate.now().toString())
    image("logo", logoBytes)
    imageUrl("ci", "https://example.com/ci.png")  // URL도 가능
    items("depts") { deptList.iterator() }
    items("products") { productList.iterator() }
    items("employees") { employeeList.iterator() }
}

ExcelGenerator().use { generator ->
    generator.generateToFile(template, data, outputDir, "quarterly_report")
}

결과

결과

변수 치환, 이미지 삽입, 반복 데이터 확장, 자동 셀 병합, 수식 범위 조정, 조건부 서식 자동 적용, 차트 데이터 반영까지 TBEG이 자동으로 처리합니다.


주요 기능

기능설명
템플릿 기반 생성Excel 템플릿에 데이터를 바인딩하여 보고서 생성
반복 데이터 처리${repeat(...)} 문법으로 리스트 데이터를 행/열로 확장
변수 치환셀, 차트, 도형, 머리글/바닥글, 수식 인자 등에 값 바인딩
이미지 삽입바이트 배열 또는 URL로 동적 이미지 삽입
자동 셀 병합반복 데이터에서 연속된 같은 값의 셀을 자동 병합
요소 묶음여러 요소를 하나의 단위로 묶어 일체로 이동
선택적 필드 노출상황에 따라 특정 필드의 노출을 제한. 삭제(DELETE) 또는 비활성화(DIM) 모드 선택 가능
수식 자동 조정데이터 확장 시 =SUM(범위), =AVERAGE(범위) 등 수식 범위를 자동 갱신
조건부 서식 자동 적용반복되는 셀에 원본의 조건부 서식을 자동 적용
차트/피벗 테이블 자동 반영확장된 데이터 범위를 차트에 자동 반영. 피벗 테이블 소스 범위 자동 조정
파일 암호화생성된 Excel 파일에 열기 암호 설정
문서 메타데이터제목, 작성자, 키워드 등 문서 속성 설정
대용량 처리100만 행 이상의 데이터를 낮은 CPU 사용률로 안정적으로 처리
비동기 처리대용량 데이터를 백그라운드에서 처리
지연 로딩DataProvider를 통한 메모리 효율적 데이터 처리
Spring Boot 지원Auto-configuration으로 간편한 연동

템플릿 문법 미리보기

문법설명예시
${변수명}변수 치환${title}
${객체.필드}반복 항목 필드${emp.name}
${repeat(컬렉션, 범위, 객체)}반복 처리${repeat(items, A2:C2, item)}
${image(이름)}이미지 삽입${image(logo)}
${merge(객체.필드)}자동 셀 병합${merge(emp.dept)}
${bundle(범위)}요소 묶음${bundle(A5:H12)}
${hideable(객체.필드, 범위, 모드)}선택적 필드 노출${hideable(emp.salary, C1:C3, DIM)}

성능

TBEG은 내부적으로 스트리밍 방식으로 데이터를 생성하기 때문에, 100만 행을 약 9초에 생성하면서도 시스템 CPU의 9% 미만만 사용합니다. 렌더링과 후처리 모두 스트리밍 방식으로 동작하여 데이터 크기에 관계없이 일정한 메모리 버퍼만 사용합니다.

데이터 크기소요 시간CPU 사용률
1,000행20ms23.5%
10,000행109ms14.7%
30,000행315ms12.5%
100,000행993ms10.8%
1,000,000행8,952ms8.8%

타 라이브러리 비교 (30,000행)

라이브러리소요 시간
TBEG0.3초
JXLS5.2초

가장 흔한 사용 시나리오: 엑셀 다운로드 API

실무에서 TBEG이 가장 많이 쓰이는 곳은 웹 애플리케이션의 엑셀 다운로드 기능입니다.

@GetMapping("/api/reports/download")
fun downloadReport(response: HttpServletResponse) {
    val data = reportService.getReportData()
    val template = resourceLoader.getResource("classpath:templates/report.xlsx")
    
    response.contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
    response.setHeader("Content-Disposition", "attachment; filename=report.xlsx")
    
    excelGenerator.generate(template.inputStream, data)
        .let { response.outputStream.write(it) }
}

관리자 페이지의 목록 내보내기, 정산 보고서 다운로드, 월간 리포트 생성 등...
템플릿 하나 만들어 두면 코드는 이게 전부입니다.


이럴 때 TBEG을 사용하세요

✅ 정형화된 보고서/명세서 생성
✅ 디자이너가 제공한 Excel 양식에 데이터 채우기
✅ 복잡한 서식(조건부 서식, 차트)이 필요한 보고서
✅ 수만~수십만 행의 대용량 데이터 처리
✅ 행/열 구조가 동적으로 변하는 표 만들기
✅ Spring Boot 환경에서의 Excel 다운로드 API 구현
❌ Excel 파일 읽기/파싱 (TBEG은 생성 전용)


시작하기

의존성 추가

// build.gradle.kts
dependencies {
    implementation("io.github.jogakdal:tbeg:1.2.3")
}
// Gradle (Groovy DSL)
dependencies {
    implementation 'io.github.jogakdal:tbeg:1.2.3'
}
<!-- Maven -->
<dependency>
    <groupId>io.github.jogakdal</groupId>
    <artifactId>tbeg</artifactId>
    <version>1.2.3</version>
</dependency>

위 버전은 이 글의 작성 시점 기준입니다. 최신 버전은 Maven Central에서 확인하세요.

빠른 시작 (Kotlin)

import io.github.jogakdal.tbeg.ExcelGenerator
import java.io.File

data class Employee(val name: String, val position: String, val salary: Int)

fun main() {
    val data = mapOf(
        "title" to "직원 현황",
        "employees" to listOf(
            Employee("황용호", "부장", 8000),
            Employee("한용호", "과장", 6500)
        )
    )

    ExcelGenerator().use { generator ->
        val template = File("template.xlsx").inputStream()
        val bytes = generator.generate(template, data)
        File("output.xlsx").writeBytes(bytes)
    }
}

빠른 시작 (Java)

import io.github.jogakdal.tbeg.ExcelGenerator;
import java.io.*;
import java.nio.file.*;
import java.util.*;

public class Example {
    public static void main(String[] args) throws Exception {
        var data = Map.<String, Object>of(
            "title", "직원 현황",
            "employees", List.of(
                Map.of("name", "황용호", "position", "부장", "salary", 8000),
                Map.of("name", "한용호", "position", "과장", "salary", 6500)
            )
        );

        try (var generator = new ExcelGenerator()) {
            byte[] bytes = generator.generate(
                new FileInputStream("template.xlsx"), data);
            Files.write(Path.of("output.xlsx"), bytes);
        }
    }
}

더 알아보기

이 글은 TBEG 시리즈의 첫 번째 편입니다. 다음 편에서는 실제 템플릿을 만들고 데이터를 바인딩하는 과정을 단계별로 다룹니다.

GitHub: jogakdal/data-processors-with-excel
Maven Central: tbeg

📖 상세 문서

0개의 댓글