기술

엑셀 다운로드 패턴을 만들었는데, 진짜 완성은 운영하면서 드러났습니다

2026.06.037분 읽기

어떤 B2B SaaS의 한 화면에 엑셀 다운로드 기능을 붙이면서, 이걸 한 번 쓰고 버릴 코드가 아니라 재사용 가능한 패턴으로 정립하기로 했습니다. 그런데 그 패턴이 자리잡는 과정이 흥미로웠습니다. 정립하고, 운영하면서 빈틈을 찾고, 다른 프로젝트로 옮겨가는 일이 하루 안에 다 일어났습니다.

정리하면 패턴은 세 단계로 자리잡습니다. 정립, 운영 발견, 전파입니다. 그리고 첫 단계와 마지막 단계 사이에서 운영 중에 발견되는 미세한 개선이, 패턴의 진짜 완성도를 결정합니다.

1.jpeg


1단계: 한 화면에서 패턴을 정립했습니다

먼저 라이브러리를 골랐습니다. FastExcel은 대용량 시트에서 Apache POI(비스트리밍)보다 힙 메모리를 훨씬 적게 쓰고, 데이터를 출력 스트림으로 흘려보내는 스트리밍 방식의 라이브러리입니다. 공식 벤치마크에서는 10만 행 기준 비스트리밍 POI가 힙을 십수 배 더 쓴다고 나옵니다. POI도 스트리밍 API를 쓰면 격차가 줄지만, 현재 쓰는 위치보다 위쪽 셀에 접근하지 못하는 제약이 붙습니다.

그 위에 공통 유틸 세 가지를 만들었습니다. 컬럼 정의(헤더 + 값 추출)를 담는 타입, 5만 행씩 페이징으로 가져와 시트당 100만 행을 넘으면 자동 분할해주는 익스포터, 그리고 한글 파일명을 RFC 5987로 인코딩해 응답 헤더를 만들어주는 헬퍼입니다.

조회 쿼리는 새로 만들지 않고 기존 조건 검색을 재사용했습니다. 마지막으로 이 패턴을 어떻게 쓰는지 체크리스트가 포함된 문서로 정리했습니다. 이 문서가 나중에 전파 단계에서 결정적인 역할을 합니다.


2단계: 운영하니 네 가지가 드러났습니다

패턴을 정립했다고 끝이 아니었습니다. 실제로 화면에서 다운로드를 눌러보니 네 가지가 보였습니다.

가장 까다로운 건 첫 번째였습니다. 백엔드에서 한글 파일명을 분명히 보냈는데, 다운로드된 파일 이름이 전부 'download'로 떨어졌습니다. 원인은 CORS 설정의 exposedHeaders에 Content-Disposition이 빠진 것이었습니다. 백엔드가 헤더를 보내도, 브라우저가 그 헤더를 프런트엔드 코드에 노출해주지 않으면 axios가 파일명을 읽지 못합니다.

이건 코드를 짤 때는 거의 안 보이고, 운영에서 실제로 눌러봐야 드러나는 함정입니다. 비슷하게 운영에 들어가서야 보이는 미세 이슈를 인증서에서 겪은 적도 있습니다.

나머지 세 가지는 사용성 개선이었습니다. 파일명 포맷을 날짜만 찍던 걸 시·분까지 포함한 10자리로 바꿨고, 거래 유형을 코드값 대신 한글 라벨로 셀에 출력했고, 다운로드 버튼을 밋밋한 아웃라인에서 엑셀을 연상시키는 초록과 아이콘으로 바꿨습니다.

2.jpeg


3단계: 다른 프로젝트가 같은 패턴을 가져갔습니다

같은 날, 전혀 다른 도메인의 SaaS에서 엑셀 업로드·다운로드 기능이 필요했습니다. 평가 데이터를 엑셀로 올리고, 양식 샘플을 내려받는 기능이었습니다.

여기서 앞서 정립한 패턴이 거의 그대로 들어갔습니다. 샘플 다운로드는 같은 FastExcel로 백엔드에서 동적으로 만들되 현재 등록된 값을 미리 채웠고, 업로드는 데이터 성격에 따라 전체 교체와 부분 갱신을 나눠 처리했습니다. 프런트엔드에서는 다운로드 응답 처리, 샘플 스타일, 업로드 버튼, blob 다운로드 유틸을 공통 컴포넌트로 묶었습니다.

다만 차용은 복붙과 다릅니다. 공통 패턴은 그대로 가져가되, 도메인에 특화된 부분은 따로 손봐야 합니다. 이 프로젝트에서도 분석 화면의 비율 지표 명칭과 산출 로직을 도메인에 맞게 별도로 수정했습니다.

3.jpeg


정립과 운영 발견 사이의 갭이 진짜 완성도입니다

이 하루를 돌아보면, 패턴이 자리잡는 과정에서 가장 중요한 건 가운데 단계였습니다. 정립만 하고 운영해보지 않으면, CORS exposedHeaders 누락 같은 미세 이슈가 그대로 남습니다. 코드 리뷰에서는 잘 안 보이고, 실제로 눌러봐야 드러나기 때문입니다.

전파가 빨랐던 이유도 분명합니다. 한 작업자가 여러 프로젝트를 동시에 진행하면 컨텍스트가 자동으로 공유돼서, 정립한 패턴이 곧바로 다른 프로젝트로 흘러갑니다. 그리고 그 흐름을 가속한 건 체크리스트 형식의 패턴 문서였습니다. "이것만은 빠뜨리지 마라"가 적혀 있으면, 차용하는 쪽이 같은 함정을 다시 밟지 않습니다.

물론 한계도 있습니다. 1인개발이라 하루 안에 세 단계가 다 돌았습니다. 팀이 단계를 나눠 맡으면 사이사이 지연이 생기고, 도메인이 너무 다르면 차용 자체가 부담이 됩니다. 패턴이 전파되려면 충분히 일반적이어야 합니다.


점검 체크리스트

엑셀 다운로드 같은 공통 패턴을 정립하고 전파할 때 다음을 점검하면 좋습니다.

대용량을 고려해 스트리밍 방식 라이브러리와 페이징·시트 분할을 잡았는가

한글 파일명은 RFC 5987로 인코딩했는가

CORS exposedHeaders에 Content-Disposition을 노출했는가 (운영에서야 드러나는 함정)

코드값이 아니라 사용자가 읽을 라벨로 출력하는가

패턴 문서를 "빠뜨리면 안 되는 것" 체크리스트 형식으로 남겼는가

차용 시 도메인 특화 부분을 복붙하지 않고 따로 손봤는가


패턴은 눌러봐야 완성됩니다

정립한 코드가 곧 완성된 패턴은 아니었습니다. 실제로 화면에서 다운로드를 눌러보고서야 파일명이 깨지는 함정이 드러났고, 그 빈틈을 메운 다음에야 다른 프로젝트가 안심하고 가져갈 수 있는 패턴이 됐습니다. 정립과 전파 사이에 운영 발견 단계를 끼워 넣는 것, 그게 패턴의 완성도를 올리는 방법이었습니다.

#엑셀다운로드#FastExcel#RFC5987#CORS#패턴정립#코드재사용#운영의기술