콘텐츠로 건너뛰기

엑셀 생성 라이브러리 비교: Apache POI vs xlsxwriter vs openpyxl

  • 테크

서버에서 엑셀 보고서를 자동 생성해야 하는 요구사항은 마케팅, 재무, 운영 등 다양한 도메인에서 흔히 발생합니다. 특히 광고 성과 보고서처럼 대용량 데이터를 복잡한 포맷으로 출력해야 할 때, 어떤 라이브러리를 선택하느냐에 따라 성능과 개발 생산성이 크게 달라집니다. 이 글에서는 Java 진영의 Apache POI와 Python 진영의 openpyxl, xlsxwriter를 중심으로, 서버 환경에서 엑셀 파일을 생성·처리할 때 활용할 수 있는 주요 라이브러리들의 특성을 살펴봅니다.


1. 라이브러리 개요

Apache POI

Apache POI는 Java 생태계에서 가장 널리 사용되는 Microsoft Office 문서 처리 라이브러리입니다. Excel 외에도 Word, PowerPoint 등 다양한 포맷을 지원하며, HSSF(.xls)와 XSSF(.xlsx) 두 가지 Excel 포맷을 모두 처리할 수 있습니다.
주의할 점으로 XSSF는 내부적으로 DOM 기반 구조를 사용하기 때문에, 모든 셀 데이터를 메모리에 적재한 상태에서 작업이 이루어져 대용량 데이터 처리 시 메모리 부담이 크다는 특징이 있습니다. 이 문제를 해결하기 위해 Apache POI는 SXSSF(Streaming Usermodel API)를 별도로 제공합니다.

// Apache POI 기본 예제
Workbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet("Report");
Row row = sheet.createRow(0);
Cell cell = row.createCell(0);
cell.setCellValue("Hello, Excel!");

try (FileOutputStream fos = new FileOutputStream("report.xlsx")) {
    workbook.write(fos);
}
workbook.close();

이처럼 API 구조가 Excel의 개념(Workbook, Sheet, Row, Cell)과 1:1로 대응되기 때문에, Excel 구조를 이해하고 있다면 비교적 직관적으로 사용할 수 있다는 장점이 있습니다.

openpyxl

openpyxl은 Python에서 Excel 2010+ 파일(.xlsx)을 읽고 쓸 수 있는 라이브러리입니다. 읽기와 쓰기 모두 지원하는 것이 특징이며, 기존 Excel 파일을 수정하는 작업에 강점을 가집니다. 스타일, 병합 셀, 수식, 조건부 서식 등 Excel 요소를 비교적 충실하게 유지하면서 조작할 수 있어, 템플릿 기반 리포트 자동화에 적합합니다.

from openpyxl import Workbook

wb = Workbook()
ws = wb.active
ws['A1'] = 'Hello, Excel!'
wb.save('report.xlsx')

xlsxwriter

xlsxwriter는 Excel 파일 생성에 특화된 Python 라이브러리입니다. 읽기는 지원하지 않지만, 쓰기 성능과 Excel 기능 지원 면에서 강점을 가집니다. 조건부 서식, 차트, 데이터 유효성 검사 등 보고서 시각화에 필요한 기능을 풍부하게 지원하며, 내부 구현 역시 스트리밍 친화적으로 설계되어 있습니다.

import xlsxwriter

workbook = xlsxwriter.Workbook('report.xlsx')
worksheet = workbook.add_worksheet()
worksheet.write('A1', 'Hello, Excel!')
workbook.close()

2. 기능비교

기능Apache POIopenpyxlxlsxwriter
.xlsx 읽기
.xlsx 쓰기
.xls 지원
피벗 테이블 생성✅ (제한적)
슬라이서/타임라인
차트
조건부 서식
데이터 유효성
이미지 삽입
스트리밍 쓰기✅ (SXSSF)✅ (write_only)✅ (constant_memory)
VBA 매크로
Pandas 통합

3. 메모리 관리 및 대용량 처리

서버 환경에서 Excel 자동화의 가장 큰 리스크는 OOM(Out Of Memory) 입니다. 특히 컨테이너 환경이나 배치 서버에서는 단 한 번의 리포트 생성 실패가 전체 작업 실패로 이어질 수 있기 때문에, 스트리밍 방식 지원 여부는 라이브러리 선택의 핵심 기준이 됩니다.

Apache POI – SXSSF (Streaming Usermodel API)

SXSSF는 Apache POI가 공식적으로 제공하는 스트리밍 API로, 내부적으로 디스크 기반 임시 파일을 사용해 메모리 사용량을 제한합니다.

// 메모리에 100행만 유지하는 스트리밍 워크북
SXSSFWorkbook workbook = new SXSSFWorkbook(100);
Sheet sheet = workbook.createSheet("Data");

for (int rownum = 0; rownum < 100000; rownum++) {
    Row row = sheet.createRow(rownum);
    row.createCell(0).setCellValue("Row " + rownum);
}

// 임시 파일 정리 필수
workbook.dispose();

공식 문서 발췌:

“Streaming version of XSSFWorkbook implementing the ‘BigGridDemo’ strategy. This allows to write very large files without running out of memory as only a configurable portion of the rows are kept in memory at any one time.” — Apache POI SXSSFWorkbook API

SXSSF 주의사항:

  • 임시 파일이 생성되며, setCompressTempFiles(true) 옵션으로 디스크 공간 절약 가능
  • dispose() 메서드로 임시 파일 반드시 정리
  • 이미 플러시된 행에는 접근 불가

openpyxl – write_only 모드

openpyxl의 write_only 모드는 내부적으로 XML 스트림을 바로 디스크에 기록하는 방식으로 동작합니다.

from openpyxl import Workbook

# write_only 모드로 워크북 생성
wb = Workbook(write_only=True)
ws = wb.create_sheet()

# 행 단위로 순차 작성
for row_data in data:
    ws.append(row_data)

wb.save('large_file.xlsx')

공식 문서 발췌:

“Sometimes, you will need to open or write extremely large XLSX files, and the common routines in openpyxl won’t be able to handle that load. Fortunately, there are two modes that enable you to read and write unlimited amounts of data with (near) constant memory consumption.” — openpyxl Optimised Modes

write_only 모드 제한사항:

  • 워크북은 한 번만 저장 가능
  • append() 메서드로만 행 추가 가능
  • lxml 설치 시 성능 향상

xlsxwriter – constant_memory 모드

xlsxwriter의 constant_memory 모드는 설계 단계부터 대용량 파일 생성을 염두에 둔 기능입니다. 다만 공식 문서에 명시된 것처럼, 이 모드에서는 일부 고급 API(add_table 등)가 제한되며 데이터는 반드시 순차적으로 기록해야 합니다.

import xlsxwriter

workbook = xlsxwriter.Workbook('huge_file.xlsx', {'constant_memory': True})
worksheet = workbook.add_worksheet()

for row_num, row_data in enumerate(data):
    for col_num, value in enumerate(row_data):
        worksheet.write(row_num, col_num, value)

workbook.close()

공식 문서 발췌:

“The trade-off when using ‘constant_memory’ mode is that you won’t be able to take advantage of any new features that manipulate cell data after it is written. Currently the add_table() method doesn’t work in this mode and merge_range() and set_row() only work for the current row.” — XlsxWriter Working with Memory and Performance

constant_memory 모드 제한사항:

  • 데이터는 순차적인 행 순서로 작성해야 함
  • add_table() 메서드 사용 불가
  • merge_range()set_row()는 현재 행에서만 동작


지금까지 서버 환경에서 활용할 수 있는 대표적인 엑셀 라이브러리들을 살펴보았습니다.
Java 환경에서는 사실상 Apache POI가 표준에 가깝고, 대용량 데이터를 다루는 경우라면 초기 설계 단계부터 SXSSF 기반 처리를 고려하는 것이 필수적입니다. Python 환경에서는 기존 엑셀 파일을 유지·수정해야 할 경우 openpyxl이, 대규모 신규 파일을 빠르게 생성하는 목적이라면 xlsxwriter가 각각 합리적인 선택지가 됩니다.

이처럼 단순히 “엑셀을 만든다”는 수준을 넘어서, 데이터 규모·사용 목적·운영 환경에 맞는 도구와 구조를 선택하고 최적화하는 과정 자체가 리포트 품질을 좌우한다고 보고 있습니다.
저희 개발 팀은 마케터분들이 방대한 광고 데이터를 더 빠르고 정확하게 확인할 수 있도록, 엑셀 리포팅 자동화를 하나의 핵심 제품 영역으로 다루며 지속적으로 개선해 오고 있습니다.

앞으로도 엑셀이라는 익숙한 도구 안에서 더 안정적이고 신뢰할 수 있는 리포트 경험을 제공하기 위해, 기술적인 선택과 구현에 대한 고민을 계속 이어갈 예정입니다.


참고자료

공식 문서
주요 API 문서


최신 마케팅/고객 데이터 활용 사례를 받아보실 수 있습니다.

비즈스프링 뉴스레터 구독하기 →

AI 대화창에서 당신의 브랜드는 추천되고 있나요?

 

X