엑셀 매크로(VBA) 보안 경고 끝! 파이썬으로 똑같은 작업 대체하기
"출장 영수증 20장을 일일이 보면서 금액을 엑셀에 입력해야 한다", "매달 카드 명세서를 사진으로 찍어두긴 했는데 정리를 안 했다", "사업자 지출 내역을 영수증 사진만 보고 회계 프로그램에 옮겨야 한다"…
영수증을 눈으로 보고 손으로 타이핑하는 작업은 시간도 오래 걸리고 숫자를 잘못 입력하는 실수도 생깁니다. 파이썬과 무료 OCR(광학 문자 인식) 라이브러리를 활용하면 영수증이나 명세서 사진에서 텍스트를 자동으로 추출하고, 날짜와 금액을 인식해 엑셀로 정리할 수 있습니다.
파이썬이 설치되어 있어야 합니다. 없다면 python.org에서 최신 버전을 받아 설치하세요. 설치 시 반드시 "Add Python to PATH"에 체크해야 합니다.
OCR 처리에 필요한 라이브러리를 설치합니다. 터미널(윈도우: CMD 또는 파워셸)을 열고 아래 명령어를 실행하세요:
pip install easyocr pandas openpyxl
easyocr은 한글과 영어를 모두 지원하는 무료 OCR 라이브러리입니다. 별도 API 키나 회원가입 없이 바로 사용할 수 있습니다. 처음 실행 시 인식 모델(약 100MB)을 자동으로 내려받으므로 시간이 조금 걸립니다. pandas와 openpyxl은 인식 결과를 엑셀로 저장하는 데 사용합니다.
💡 이 코드로 할 수 있는 것: 영수증·명세서 이미지에서 전체 텍스트를 인식하고, 정규식을 활용해 날짜와 금액 패턴을 자동으로 찾아냅니다. 여러 영수증 이미지를 한꺼번에 처리해 하나의 엑셀로 정리합니다.
아래 코드를 그대로 복사해서 메모장에 붙여넣고, receipt_ocr.py로 저장하세요. 저장 시 파일 형식은 "모든 파일", 인코딩은 UTF-8로 설정합니다.
import easyocr
import pandas as pd
import re
from pathlib import Path
# ① 설정
FOLDER_PATH = r"C:\Users\내이름\Desktop\영수증사진" # ← 영수증 이미지가 있는 폴더
OUTPUT_PATH = r"C:\Users\내이름\Desktop\영수증_정리.xlsx" # ← 저장 경로
SUPPORTED = {".jpg", ".jpeg", ".png"} # ← 지원 이미지 확장자
# ② OCR 리더 초기화 (한글+영어 인식, 최초 실행 시 모델 다운로드)
print(" OCR 모델 로드 중... (최초 실행 시 시간이 걸립니다)")
reader = easyocr.Reader(["ko", "en"], gpu=False)
print(" ✔ OCR 모델 로드 완료")
# ③ 금액·날짜 패턴 추출 함수
def extract_amount(text_list):
"""텍스트 목록에서 가장 큰 금액(보통 합계)을 찾는 함수"""
amounts = []
for text in text_list:
# 숫자+쉼표 패턴 찾기 (예: 12,500 / 8500)
matches = re.findall(r"[\d,]{4,}", text.replace(" ", ""))
for m in matches:
num = int(m.replace(",", ""))
if 100 <= num <= 10_000_000: # 비정상적으로 크거나 작은 값 제외
amounts.append(num)
return max(amounts) if amounts else None
def extract_date(text_list):
"""텍스트 목록에서 날짜 패턴을 찾는 함수"""
for text in text_list:
# YYYY-MM-DD, YYYY.MM.DD, YYYY/MM/DD 패턴
match = re.search(r"(20\d{2})[-./](\d{1,2})[-./](\d{1,2})", text)
if match:
y, m, d = match.groups()
return f"{y}-{int(m):02d}-{int(d):02d}"
return None
# ④ 폴더 안의 영수증 이미지 처리
folder = Path(FOLDER_PATH)
images = sorted([f for f in folder.iterdir()
if f.is_file() and f.suffix.lower() in SUPPORTED])
print(f"\n 📂 처리할 영수증: {len(images)}개\n")
results = []
for img_path in images:
try:
ocr_result = reader.readtext(str(img_path))
text_list = [item[1] for item in ocr_result] # 인식된 텍스트만 추출
amount = extract_amount(text_list)
date = extract_date(text_list)
full_text = " / ".join(text_list[:5]) # 미리보기용 (앞 5개 텍스트)
results.append({
"파일명": img_path.name,
"인식날짜": date or "인식안됨",
"인식금액": amount or "인식안됨",
"전체텍스트": " ".join(text_list),
})
print(f" ✔ {img_path.name} → 날짜: {date or '?'} / 금액: {amount or '?'}")
except Exception as e:
print(f" ✘ {img_path.name} 처리 실패: {e}")
results.append({
"파일명": img_path.name, "인식날짜": "오류",
"인식금액": "오류", "전체텍스트": str(e),
})
# ⑤ 엑셀로 저장
df = pd.DataFrame(results)
df.to_excel(OUTPUT_PATH, index=False)
success_count = sum(1 for r in results if r["인식금액"] != "인식안됨" and r["인식금액"] != "오류")
print(f"\n✅ 완료! 금액 인식 성공: {success_count}/{len(images)}건 → {OUTPUT_PATH}")
FOLDER_PATH에 그 폴더 경로를 입력합니다.python receipt_ocr.py
정상 실행 시 터미널에 이렇게 출력됩니다:
OCR 모델 로드 중... (최초 실행 시 시간이 걸립니다) ✔ OCR 모델 로드 완료 📂 처리할 영수증: 5개 ✔ 영수증_1.jpg → 날짜: 2026-06-15 / 금액: 24500 ✔ 영수증_2.jpg → 날짜: 2026-06-16 / 금액: 8900 ✔ 영수증_3.jpg → 날짜: 2026-06-18 / 금액: 53200 ✅ 완료! 금액 인식 성공: 5/5건 → C:\Users\내이름\Desktop\영수증_정리.xlsx
엑셀 파일에는 파일명, 인식된 날짜, 인식된 금액, 전체 인식 텍스트가 정리됩니다. 전체텍스트 열을 참고하면 자동 인식이 정확한지 직접 검증할 수 있습니다.
오류 1: 금액이 "인식안됨"으로 나오거나 잘못된 숫자가 인식됨
영수증 사진이 흐릿하거나 기울어진 경우 OCR 정확도가 떨어집니다. 사진을 정면에서, 밝은 조명 아래에서 다시 촬영하세요. 또한 코드의 extract_amount() 함수는 "가장 큰 숫자"를 합계로 추정하는 방식이므로, 영수증에 전화번호나 사업자번호가 더 크게 인식되면 오류가 날 수 있습니다. 전체텍스트 열로 직접 확인 후 보정하세요.
오류 2: 처음 실행 시 매우 오래 걸림
EasyOCR이 최초 실행 시 한글·영어 인식 모델을 자동으로 다운로드합니다. 인터넷 속도에 따라 1~5분 정도 소요될 수 있습니다. 한 번 다운로드되면 이후 실행부터는 빠릅니다.
오류 3: ModuleNotFoundError: No module named 'easyocr'
설치가 제대로 되지 않은 경우입니다. 아래 명령어로 다시 시도하세요.
python -m pip install easyocr
영수증 상단에 보통 상호명이 가장 먼저 인식됩니다. 인식된 텍스트의 첫 줄을 상호명으로 추정하는 방법입니다.
def extract_store_name(text_list):
"""영수증 상단의 첫 텍스트를 상호명으로 추정"""
for text in text_list[:3]: # 상위 3개 중에서 찾기
# 숫자만 있는 줄(전화번호 등)은 제외
if not re.match(r"^[\d\-\s]+$", text) and len(text) >= 2:
return text
return "인식안됨"
# 결과 딕셔너리에 추가
results[-1]["상호명"] = extract_store_name(text_list)
💡 이전 게시글과 결합하면: 엑셀 자동 정렬·필터링 편으로 인식된 지출 데이터를 월별로 정리하거나, 차트 자동 저장 편과 결합해 지출 현황을 시각화하는 것도 가능합니다.
이 코드를 응용하면 인식된 데이터를 카테고리별로 자동 분류하거나, 매달 지출 합계를 자동 계산하는 것도 가능합니다.