데이터 처리 환경에서 CSV(Comma-Separated Values) 형식은 가볍고 호환성이 뛰어나 서로 다른 애플리케이션이나 데이터베이스 간에 정보를 교환할 때 가장 선호되는 포맷입니다. Python 개발자에게 리스트(List) 데이터를 CSV로 내보내는 작업은 데이터 분석 결과 저장, 보고서 생성 등 다양한 실무 시나리오에서 빈번하게 발생합니다.
Spire.XLS for Python 라이브러리를 사용하면 Microsoft Excel 설치 없이도 복잡한 데이터 구조를 간편하게 CSV 파일로 변환할 수 있습니다. 이 글에서는 1차원 리스트부터 중첩된 2차원 리스트, 그리고 키-값 쌍을 가진 딕셔너리 리스트를 CSV로 내보내는 구체적인 방법을 살펴보겠습니다.
라이브러리 설치 및 준비
Spire.XLS for Python은 데이터 형식 호환성이 뛰어나며, 쉼표 외에도 다양한 구분자를 지원하는 등 강력한 기능을 제공합니다. 먼저 터미널에서 다음 명령어를 실행하여 라이브러리를 설치합니다.
pip install Spire.XLS
1차원 리스트를 CSV로 내보내기
1차원 리스트는 단일 시퀀스 데이터입니다. 이를 CSV의 한 행 또는 한 열에 배치하는 방법입니다.
from spire.xls import *
from spire.xls.common import *
# 워크북 초기화
wb = Workbook()
wb.Worksheets.Clear()
sheet = wb.Worksheets.Add("1D_List_Export")
# 샘플 데이터: 음료 목록
beverages = ["커피", "녹차", "홍차", "우유", "주스"]
# 데이터를 첫 번째 행(가로)으로 입력
for idx, val in enumerate(beverages):
sheet.Range[1, idx + 1].Value = val
# CSV 파일로 저장
wb.SaveToFile("beverages_row.csv", FileFormat.CSV)
wb.Dispose()
데이터를 한 열(세로)로 저장하고 싶다면 sheet.Range[idx + 1, 1].Value = val 형식을 사용하면 됩니다.
2차원 리스트를 CSV로 변환하기
행과 열이 존재하는 표 형식의 데이터는 2차원 리스트(리스트의 리스트)로 표현됩니다. 이는 가장 일반적인 데이터 시트 형태입니다.
from spire.xls import *
from spire.xls.common import *
wb = Workbook()
wb.Worksheets.Clear()
sheet = wb.Worksheets.Add("InventoryData")
# 헤더를 포함한 2차원 데이터
inventory = [
["상품명", "가격", "카테고리", "재고량"],
["노트북", 1500000, "전자제품", 10],
["마우스", 50000, "주변기기", 45],
["키보드", 120000, "주변기기", 20],
["모니터", 350000, "전자제품", 15]
]
# 중첩 루프를 이용한 셀 데이터 쓰기
for r_idx, row_values in enumerate(inventory):
for c_idx, cell_value in enumerate(row_values):
# 모든 데이터 타입을 문자열로 변환하여 할당
sheet.Range[r_idx + 1, c_idx + 1].Value = str(cell_value)
wb.SaveToFile("product_inventory.csv", FileFormat.CSV)
wb.Dispose()
딕셔너리 리스트를 CSV로 내보내기
JSON 데이터나 데이터베이스 쿼리 결과는 주로 딕셔너리 리스트 형태입니다. 딕셔너리의 키(Key)를 CSV의 헤더로, 값(Value)을 데이터 행으로 활용합니다.
from spire.xls import *
from spire.xls.common import *
wb = Workbook()
wb.Worksheets.Clear()
sheet = wb.Worksheets.Add("StudentRecords")
# 학생 정보 딕셔너리 리스트
students = [
{"학번": "S001", "이름": "김철수", "전공": "컴퓨터공학"},
{"학번": "S002", "이름": "이영희", "전공": "전자공학"},
{"학번": "S003", "이름": "박지성", "전공": "경영학"}
]
if students:
# 1. 헤더(Key) 추출 및 쓰기
fields = list(students[0].keys())
for col, field in enumerate(fields):
sheet.Range[1, col + 1].Value = field
# 2. 데이터(Value) 쓰기
for row_idx, student in enumerate(students):
for col_idx, field in enumerate(fields):
# 키가 없을 경우를 대비해 get 메서드 사용
val = student.get(field, "")
sheet.Range[row_idx + 2, col_idx + 1].Value = str(val)
wb.SaveToFile("student_records.csv", FileFormat.CSV)
wb.Dispose()
구분자 및 인코딩 설정
특정 국가나 시스템에서는 쉼표(,) 대신 세미콜론(;)을 사용하거나 특정 인코딩(UTF-8)을 명시해야 할 때가 있습니다. SaveToFile 메서드를 확장하여 이를 제어할 수 있습니다.
# 세미콜론 구분자 및 UTF-8 인코딩 사용
sheet.SaveToFile("custom_format.csv", ";", Encoding.get_UTF8())
# 탭(Tab) 구분자 사용
sheet.SaveToFile("data_tab.csv", "\t", Encoding.get_UTF8())
핵심 팁 및 주의사항
- 자원 해제: 대량의 데이터를 처리한 후에는 반드시
wb.Dispose()를 호출하여 메모리 자원을 확보하십시오. - 데이터 정제: CSV 저장 전 None 값이나 특수 문자가 포함된 데이터는 미리 문자열로 치환하거나 정제하는 것이 좋습니다.
- 서식 지정: CSV 파일 자체는 서식을 저장하지 않지만, Spire.XLS 내에서 숫자 형식을 미리 지정(
NumberFormat)해두면 데이터 유실을 방지할 수 있습니다.