업무를 하다 보면 여러 시트로 구성된 엑셀 파일을 각각 마크다운 파일로 변환해야 할 때가 있습니다.
오늘은 Python을 사용해서 엑셀의 모든 시트를 개별 마크다운 파일로 자동 변환하는 방법을 단계별로 알아보겠습니다.
🎯 최종 결과물
이 가이드를 따라하면 다음과 같은 결과를 얻을 수 있습니다:📁 input_sheets/
├── 01_매출_현황.md
├── 02_재고_관리.md
├── 03_고객_정보.md
├── 04_예산_계획.md
└── 🔗 input_ALL_COMBINED.md (모든 시트 통합본)
📋 준비사항
1단계: Python 환경 확인
먼저 Python이 설치되어 있는지 확인합니다.
python --versionPython 3.7 이상이 필요합니다. 없다면 python.org에서 설치해주세요.
2단계: 필요한 라이브러리 설치
터미널(CMD)에서 다음 명령어를 실행합니다:
pip install aspose-cells-python참고: Windows에서는 .NET Framework 4.0 이상 또는 .NET 6.0이 필요합니다.
3단계: 작업 폴더 및 파일 준비
- 새 폴더를 만들고 그 안에 변환할 엑셀 파일을
input.xlsx이름으로 저장합니다. - 같은 폴더에 Python 스크립트 파일을 만들 예정입니다.
💻 완전한 변환 코드
다음 코드를 excel_to_markdown.py 파일로 저장하세요:
from aspose.cells import Workbook
import os
import re
try:
# 1. 파일 존재 여부 확인
if not os.path.exists("input.xlsx"):
print("ERROR: input.xlsx 파일이 없습니다.")
print("Python 파일과 같은 폴더에 input.xlsx 파일을 넣어주세요.")
exit()
print("📂 input.xlsx 파일을 처리 중...")
# 2. 엑셀 파일 열기
workbook = Workbook("input.xlsx")
# 3. 출력 폴더 생성
base_filename = os.path.splitext("input.xlsx")[0]
output_dir = f"{base_filename}_sheets"
if not os.path.exists(output_dir):
os.makedirs(output_dir)
print(f"📁 출력 폴더 '{output_dir}' 생성했습니다.")
# 4. 시트 개수 확인
sheet_count = len(workbook.worksheets)
print(f"📊 총 {sheet_count}개의 시트를 발견했습니다.")
# 5. 통합 파일을 위한 내용 저장소
combined_content = []
# 6. 각 시트를 개별 MD 파일로 변환
for i in range(sheet_count):
print(f"⏳ {i+1}번째 시트 처리 중...")
# 6-1. 새 워크북 생성 및 시트 복사
new_workbook = Workbook()
original_sheet = workbook.worksheets[i]
new_sheet = new_workbook.worksheets[0]
# 6-2. 원본 시트 이름 설정
new_sheet.name = original_sheet.name
sheet_name = original_sheet.name
# 6-3. 파일명으로 사용할 수 없는 문자 처리
safe_sheet_name = re.sub(r'[<>:"/\\|?*]', '_', sheet_name)
safe_sheet_name = safe_sheet_name.replace(' ', '_')
safe_sheet_name = safe_sheet_name.strip()
# 6-4. 데이터 복사
max_row = original_sheet.cells.max_data_row
max_col = original_sheet.cells.max_data_column
if max_row >= 0 and max_col >= 0:
for row in range(max_row + 1):
for col in range(max_col + 1):
source_cell = original_sheet.cells.get(row, col)
target_cell = new_sheet.cells.get(row, col)
target_cell.put_value(source_cell.value)
# 6-5. 개별 MD 파일 저장
output_filename = os.path.join(output_dir, f"{i+1:02d}_{safe_sheet_name}.md")
new_workbook.save(output_filename)
# 6-6. 파일 후처리 (불필요한 내용 제거)
try:
with open(output_filename, 'r', encoding='utf-8') as f:
content = f.read()
# "# Evaluation" 이후 모든 내용 제거
if "# Evaluation" in content:
content = content.split("# Evaluation")[0].rstrip()
# 마지막 빈 줄들 제거
content = content.rstrip('\n')
# 수정된 내용으로 파일 다시 저장
with open(output_filename, 'w', encoding='utf-8') as f:
f.write(content)
# 통합 파일용 내용 저장
combined_content.append(content)
except Exception as e:
print(f"⚠️ 파일 후처리 중 오류: {e}")
print(f"✅ {i+1}번째 시트 '{sheet_name}'를 '{output_filename}'로 저장했습니다.")
# 7. 모든 시트를 합친 통합 MD 파일 생성
print("📝 통합 파일 생성 중...")
combined_filename = os.path.join(output_dir, f"{base_filename}_ALL_COMBINED.md")
try:
with open(combined_filename, 'w', encoding='utf-8') as f:
# 7-1. 목차 생성
f.write("## 📋 목차\n\n")
for i in range(sheet_count):
sheet_name = workbook.worksheets[i].name
anchor_name = sheet_name.replace(' ', '-').lower()
f.write(f"{i+1}. [{sheet_name}](#{i+1:02d}-{anchor_name})\n")
f.write("\n---\n\n")
# 7-2. 각 시트 내용 추가
for i, content in enumerate(combined_content):
if content.strip():
sheet_name = workbook.worksheets[i].name
anchor_name = sheet_name.replace(' ', '-').lower()
f.write(f"<div id=\"{i+1:02d}-{anchor_name}\"></div>\n\n")
f.write(f"## {i+1:02d}. {sheet_name}\n\n")
f.write(content.replace(f"# {sheet_name}", ""))
f.write("\n\n---\n\n")
print(f"✅ 통합 파일 '{combined_filename}' 생성 완료!")
except Exception as e:
print(f"⚠️ 통합 파일 생성 중 오류: {e}")
# 8. 완료 메시지 및 결과 출력
print(f"\n🎉 모든 변환 작업이 완료되었습니다!")
print(f"📁 '{output_dir}' 폴더에 총 {sheet_count + 1}개의 MD 파일이 생성되었습니다.")
print(f"\n📋 생성된 파일 목록:")
for filename in sorted(os.listdir(output_dir)):
if filename.endswith('.md'):
if "ALL_COMBINED" in filename:
print(f" 🔗 {filename} (통합파일)")
else:
print(f" - {filename}")
except Exception as e:
print(f"❌ 오류 발생: {e}")
print("파일이 열려있다면 닫고 다시 시도해주세요.")🚀 실행 방법
1단계: 파일 준비
- 변환할 엑셀 파일을
input.xlsx이름으로 저장 excel_to_markdown.py파일과 같은 폴더에 배치
2단계: 스크립트 실행
터미널에서 다음 명령어 실행:
python excel_to_markdown.py3단계: 결과 확인
실행이 완료되면 다음과 같은 폴더 구조가 생성됩니다:📁 input_sheets/
├── 01_매출_현황.md (첫 번째 시트)
├── 02_재고_관리.md (두 번째 시트)
├── 03_고객_정보.md (세 번째 시트)
└── input_ALL_COMBINED.md (모든 시트 통합)
✨ 주요 기능 소개
🎯 스마트한 파일명 처리
- 시트 순서에 맞게
01_,02_번호 자동 부여 - 파일명에 사용할 수 없는 특수문자를 자동으로
_로 변경 - 띄어쓰기도
_로 자동 변환
📚 통합 파일 생성
- 모든 시트를 하나의 마크다운 파일로 통합
- 클릭 가능한 목차 자동 생성
- 각 시트별로 명확한 구분선 추가
🧹 자동 정리 기능
- 불필요한 “# Evaluation” 섹션 자동 제거
- 마지막 빈 줄들 자동 정리
- 깔끔한 마크다운 형식으로 변환
🔧 커스터마이징 옵션
다른 파일명 사용하기
input.xlsx 대신 다른 파일명을 사용하려면 코드에서 해당 부분을 수정하세요:
# 이 부분을 원하는 파일명으로 변경
if not os.path.exists("your_file.xlsx"):
print("ERROR: your_file.xlsx 파일이 없습니다.")
exit()
workbook = Workbook("your_file.xlsx")출력 폴더명 변경하기
출력 폴더명을 바꾸려면:
# 기본: input_sheets
output_dir = f"{base_filename}_sheets"
# 변경 예시: input_markdown
output_dir = f"{base_filename}_markdown"🆚 기존 도구들과의 비교
| 구분 | 이 스크립트 | 온라인 도구 | 수동 변환 |
|---|---|---|---|
| 시트별 분리 | ✅ 자동 | ❌ 불가능 | ⏰ 시간 소요 |
| 통합 파일 | ✅ 자동 생성 | ❌ 불가능 | ⏰ 수동 작업 |
| 파일명 정리 | ✅ 스마트 처리 | ❌ 제한적 | ⏰ 수동 편집 |
| 오프라인 사용 | ✅ 가능 | ❌ 인터넷 필요 | ✅ 가능 |
| 비용 | 🆓 무료 | 💰 일부 유료 | 🆓 무료 |
🐛 문제 해결
자주 발생하는 오류들
1. ModuleNotFoundError: No module named ‘aspose’
# 해결방법: 라이브러리 재설치
pip install aspose-cells-python2. 파일을 찾을 수 없습니다
input.xlsx파일이 Python 스크립트와 같은 폴더에 있는지 확인- 파일명이 정확한지 확인 (대소문자 구분)
3. 엑셀 파일이 열려있는 상태
- 엑셀 파일을 닫고 다시 실행
- 다른 프로그램에서 파일을 사용 중이지 않은지 확인
🎁 추가 활용 팁
배치 처리 스크립트
여러 엑셀 파일을 한 번에 처리하고 싶다면:
import glob
# 폴더 내 모든 .xlsx 파일 처리
for excel_file in glob.glob("*.xlsx"):
print(f"처리 중: {excel_file}")
# 위의 변환 코드 실행
자동화 스케줄링
Windows 작업 스케줄러나 Linux cron을 사용해서 정기적으로 자동 변환하도록 설정할 수 있습니다.
🎊 마무리
이제 복잡한 엑셀 파일도 몇 초 만에 깔끔한 마크다운 파일로 변환할 수 있습니다!
이 스크립트의 장점:
- ⚡ 빠른 처리: 수십 개 시트도 몇 초 내 변환
- 🎯 정확한 분리: 각 시트가 개별 파일로 깔끔하게 분리
- 📚 통합 관리: 전체 내용을 한 번에 볼 수 있는 통합 파일
- 🔧 커스터마이징: 필요에 따라 쉽게 수정 가능
업무 효율성을 크게 높여줄 이 도구를 활용해서 더 생산적인 작업 환경을 만들어보세요!
