파이썬 openpyxl 엑셀 자동화 실전 가이드: 대량 데이터·셀 스타일·수식 입력
파이썬 openpyxl로 엑셀 파일을 만들고 대량 데이터를 입력하는 방법부터 셀 스타일, 수식, 기존 파일 수정, 대용량 처리와 실수 방지 요령까지 예제로 설명합니다.

파이썬에서 엑셀 보고서를 반복해서 만드는 업무라면 openpyxl로 시트 생성, 데이터 입력, 셀 서식, 수식 삽입과 파일 저장까지 자동화할 수 있습니다. 이 글에서는 빈 통합문서를 만든 뒤 실무형 매출 보고서를 완성하는 흐름을 하나의 예제로 설명합니다.
핵심 요약
Workbook으로 새 파일을 만들고load_workbook()으로 기존 파일을 엽니다.- 여러 행을 넣을 때는 셀을 하나씩 지정하기보다
append()를 활용하면 코드가 단순해집니다. Font,PatternFill,Border,Alignment를 조합해 제목 행과 데이터 영역을 꾸밀 수 있습니다.- openpyxl은 수식을 기록하지만 계산 엔진은 아닙니다. 계산 결과는 엑셀이나 호환 프로그램에서 파일을 열 때 갱신됩니다.
- 대용량 파일은
write_only=True또는read_only=True를 검토해야 메모리 사용량을 줄일 수 있습니다.
openpyxl 설치와 기본 구조
openpyxl은 파이썬에서 Excel 2010 이후의 .xlsx, .xlsm 등 Office Open XML 형식 파일을 읽고 쓰는 라이브러리입니다. 먼저 가상환경에서 pip install openpyxl로 설치합니다. 워크시트에 이미지를 넣을 계획이라면 Pillow도 함께 설치해야 합니다.
pip install openpyxl
pip install pillow
새 통합문서는 Workbook()으로 생성합니다. 통합문서를 만들면 최소 한 개의 워크시트가 자동으로 생기며, wb.active로 가져올 수 있습니다. 시트 이름은 title 속성으로 변경합니다.
from openpyxl import Workbook
wb = Workbook()
ws = wb.active
ws.title = "월별 매출"
wb.save("monthly_sales.xlsx")
save()는 같은 이름의 기존 파일을 별도 경고 없이 덮어쓸 수 있습니다. 실제 업무에서는 원본과 결과 파일의 경로를 분리하거나 저장 전에 파일 존재 여부를 확인하는 편이 안전합니다.
대량 데이터 시트 생성하기
데이터가 여러 행이라면 행마다 append()를 호출하는 방식이 읽기 쉽습니다. 아래 예제는 월, 상품명, 수량, 단가를 기록하고 마지막 열에 금액 수식을 넣을 준비를 합니다.
from openpyxl import Workbook
rows = [
["1월", "상품 A", 12, 15000],
["1월", "상품 B", 8, 22000],
["2월", "상품 A", 15, 15000],
]
wb = Workbook()
ws = wb.active
ws.title = "매출현황"
ws.append(["월", "상품", "수량", "단가", "금액"])
for row in rows:
ws.append(row)
wb.save("sales_report.xlsx")
특정 셀만 바꿀 때는 ws["A1"]처럼 주소로 접근하거나 ws.cell(row=1, column=1, value="월")을 사용합니다. 반대로 넓은 범위를 무조건 순회하면 값이 없는 셀까지 메모리에 만들어질 수 있으므로 필요한 범위만 지정해야 합니다.
| 작업 | 권장 방법 | 적합한 상황 |
|---|---|---|
| 한 셀 입력 | ws["A1"] = 값 |
제목·기준일처럼 위치가 고정된 값 |
| 여러 행 추가 | ws.append(행) |
목록·거래내역·집계 결과 |
| 범위 읽기 | iter_rows() |
기존 데이터 검사·변환 |
| 값만 읽기 | values_only=True |
셀 객체와 서식이 필요 없는 처리 |
제목 행과 셀 스타일링
openpyxl의 셀 스타일에는 글꼴, 채우기, 테두리, 정렬, 숫자 형식과 보호 설정이 포함됩니다. 반복 적용할 스타일 객체를 먼저 만든 뒤 대상 셀에 할당하면 코드 중복을 줄일 수 있습니다. 색상은 환경에 따라 달라질 수 있는 인덱스 색상보다 aRGB 형태의 8자리 값을 사용하는 것이 안정적입니다.
from openpyxl.styles import Font, PatternFill, Border, Side, Alignment
header_fill = PatternFill("solid", fgColor="FF1F4E78")
header_font = Font(color="FFFFFFFF", bold=True)
thin = Side(style="thin", color="FFD9E1F2")
cell_border = Border(left=thin, right=thin, top=thin, bottom=thin)
for cell in ws[1]:
cell.fill = header_fill
cell.font = header_font
cell.alignment = Alignment(horizontal="center", vertical="center")
cell.border = cell_border
for row in ws.iter_rows(min_row=2, min_col=3, max_col=5):
for cell in row:
cell.number_format = "#,##0"
cell.border = cell_border
ws.freeze_panes = "A2"
ws.column_dimensions["A"].width = 12
ws.column_dimensions["B"].width = 20
병합 셀은 왼쪽 위 셀이 값과 주요 서식을 담당합니다. 병합 범위 전체에 테두리를 표시해야 한다면 병합 후 결과를 실제 엑셀에서 확인해야 합니다. 또한 동일한 서식을 수천 개 셀에 적용할 때는 NamedStyle을 만들어 재사용하는 방법도 고려할 수 있습니다.
엑셀 수식 입력과 합계 행 만들기
수식은 엑셀에서 사용하는 표현을 문자열로 입력합니다. 예를 들어 각 행의 수량과 단가를 곱한 금액은 =C2*D2처럼 기록할 수 있습니다. 데이터 마지막 행을 계산해 합계 수식의 범위가 자동으로 바뀌게 만들면 행 수가 늘어도 코드를 다시 수정할 필요가 없습니다.
from openpyxl.utils import get_column_letter
for row_no in range(2, ws.max_row + 1):
ws.cell(row=row_no, column=5, value=f"=C{row_no}*D{row_no}")
total_row = ws.max_row + 1
ws.cell(row=total_row, column=4, value="합계")
ws.cell(row=total_row, column=5, value=f"=SUM(E2:E{total_row-1})")
ws.cell(row=total_row, column=5).number_format = "#,##0"
wb.save("sales_report.xlsx")
중요한 점은 openpyxl이 수식을 계산하지 않는다는 사실입니다. 라이브러리는 수식 문자열을 파일에 저장하며, 계산 결과는 Microsoft Excel이나 수식 계산을 지원하는 호환 프로그램이 파일을 열고 다시 계산할 때 갱신됩니다. 기존 파일을 data_only=True로 열면 수식 대신 마지막으로 저장된 계산 결과를 읽지만, 그 값이 최신이라고 단정할 수는 없습니다.
기존 엑셀 파일을 열어 수정하기
기존 파일은 load_workbook()으로 엽니다. 매크로가 포함된 .xlsm 파일을 유지해야 한다면 keep_vba=True를 사용하고 확장자도 그대로 보존해야 합니다. 다만 매크로를 보존할 수 있을 뿐 openpyxl로 VBA 코드를 편집하는 기능은 아닙니다.
from openpyxl import load_workbook
wb = load_workbook("template.xlsx")
ws = wb["매출현황"]
ws["G1"] = "작성일"
ws["H1"] = "2026-08-29"
wb.save("template_completed.xlsx")
기존 파일에는 도형, 외부 링크, 차트, 이미지처럼 단순 셀 데이터가 아닌 요소가 포함될 수 있습니다. 공식 문서에서도 지원되지 않는 일부 요소는 파일을 열고 다시 저장하는 과정에서 손실될 수 있다고 안내하므로, 중요한 서식 파일은 복사본으로 먼저 시험해야 합니다.
대용량 엑셀 파일 처리 방법
수십만 행을 일반 모드로 만들거나 읽으면 메모리 사용량이 크게 늘 수 있습니다. 새 파일을 순차적으로 작성하기만 한다면 Workbook(write_only=True), 큰 파일에서 값만 순차적으로 읽는다면 load_workbook(path, read_only=True, data_only=True)를 검토합니다.
| 모드 | 장점 | 주의사항 |
|---|---|---|
| 일반 모드 | 셀 수정과 서식 기능을 폭넓게 사용 | 대용량에서 메모리 부담 증가 |
| 읽기 전용 | 큰 파일을 적은 메모리로 순회 | 일부 기능과 열 단위 반복 제한 |
| 쓰기 전용 | 많은 행을 순차 생성할 때 효율적 | 이미 추가한 셀로 돌아가 수정하기 어려움 |
쓰기 전용 모드에서는 데이터가 결정되는 즉시 행을 추가하는 구조로 코드를 설계해야 합니다. 스타일이 필요한 경우에도 행을 추가하기 전에 WriteOnlyCell에 서식을 지정합니다. 데이터베이스나 CSV에서 데이터를 읽는다면 전체를 리스트로 만든 뒤 저장하기보다 일정 단위로 읽어 바로 기록하는 흐름이 유리합니다.
실수 방지 체크리스트
- 원본 파일과 결과 파일의 경로를 분리했는지 확인합니다.
- 시트 이름이 실제 파일의 이름과 정확히 일치하는지 확인합니다.
- 행 번호와 열 번호는 1부터 시작한다는 점을 기억합니다.
- 금액·날짜·백분율 셀에 알맞은
number_format을 지정합니다. - 수식 결과가 필요하면 엑셀에서 재계산한 뒤 저장했는지 확인합니다.
.xlsm파일은keep_vba=True와 올바른 확장자를 사용합니다.- 대용량 파일은 읽기·쓰기 전용 모드가 적합한지 검토합니다.
- 저장 후 다시 열어 핵심 셀 값과 시트 수를 자동 검증합니다.
자주 묻는 질문
1. openpyxl로 오래된 .xls 파일도 열 수 있나요?
기본 대상은 .xlsx와 같은 Office Open XML 형식입니다. 오래된 바이너리 .xls 파일은 먼저 변환하거나 다른 전용 라이브러리를 검토해야 합니다.
2. 엑셀이 설치되지 않은 PC에서도 사용할 수 있나요?
네. 파일을 만들고 읽는 작업 자체에는 Microsoft Excel 설치가 필요하지 않습니다. 다만 수식 계산 결과의 갱신은 별도의 계산 프로그램이 필요할 수 있습니다.
3. 수식을 입력했는데 결과가 None으로 보이는 이유는 무엇인가요?
openpyxl은 수식을 계산하지 않습니다. 엑셀에서 파일을 열어 계산하고 저장한 이력이 없으면 data_only=True로 읽을 계산 결과가 없을 수 있습니다.
4. 셀 색상이 예상과 다르게 나오는 이유는 무엇인가요?
테마색이나 인덱스 색상은 파일과 프로그램 환경의 영향을 받을 수 있습니다. 일관된 결과가 중요하면 aRGB 값을 명시하는 것이 좋습니다.
5. 여러 셀에 같은 스타일을 빠르게 적용하려면 어떻게 하나요?
스타일 객체를 재사용하거나 NamedStyle을 등록해 적용할 수 있습니다. 스타일 객체를 셀마다 불필요하게 새로 만들지 않는 것이 좋습니다.
6. 열 너비를 내용에 맞게 완전히 자동 조정할 수 있나요?
엑셀의 자동 맞춤과 완전히 같은 결과를 보장하는 단일 기능은 없습니다. 문자열 길이를 계산해 column_dimensions의 너비를 정하는 방식을 주로 사용합니다.
7. CSV 파일도 openpyxl로 읽나요?
CSV는 엑셀 통합문서 형식이 아닙니다. 파이썬의 csv 모듈이나 pandas로 읽은 뒤, 결과를 openpyxl 워크시트에 기록하는 방식이 적합합니다.
8. 이미지를 셀 안에 넣을 수 있나요?
Pillow를 설치한 뒤 openpyxl.drawing.image.Image를 이용할 수 있습니다. 이미지는 셀 값이 아니라 워크시트 위에 배치되는 개체로 취급됩니다.
9. 비밀번호로 암호화된 엑셀 파일도 바로 열 수 있나요?
암호화된 파일을 openpyxl만으로 직접 해제하는 용도로 사용하면 안 됩니다. 적절한 권한과 별도 복호화 절차가 필요합니다.
10. 작업이 끝난 파일을 어떻게 검증하면 좋나요?
저장한 파일을 load_workbook()으로 다시 열어 시트 이름, 마지막 행, 핵심 셀 값과 수식 문자열을 검사합니다. 중요한 보고서는 실제 엑셀 화면에서도 최종 확인하는 것이 안전합니다.
공식 출처
공식 문서 확인일: 2026년 8월 29일