Initial commit: Excel Data Merger RPA
- 여러 엑셀 파일을 하나로 자동 통합 - 원본 파일명 추적 기능 - 에러 처리 및 진행 상황 표시 - 샘플 데이터 생성 스크립트 포함 Features: - Support .xlsx, .xls, .xlsm files - Automatic timestamp in output filename - Error handling for corrupted files - Real-time progress display
This commit is contained in:
33
.gitignore
vendored
Normal file
33
.gitignore
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
# Python
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
*.so
|
||||
.Python
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
.venv
|
||||
|
||||
# 데이터 파일
|
||||
input/*.xlsx
|
||||
input/*.xls
|
||||
input/*.xlsm
|
||||
output/*.xlsx
|
||||
output/*.xls
|
||||
output/*.xlsm
|
||||
|
||||
# 폴더는 유지하되 내용물 제외
|
||||
!input/.gitkeep
|
||||
!output/.gitkeep
|
||||
|
||||
# IDE
|
||||
.vscode/
|
||||
.idea/
|
||||
*.swp
|
||||
*.swo
|
||||
*~
|
||||
|
||||
# OS
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
222
README.md
Normal file
222
README.md
Normal file
@@ -0,0 +1,222 @@
|
||||
# 📊 엑셀 데이터 통합 자동화 (Excel Data Merger RPA)
|
||||
|
||||
여러 개의 엑셀 파일을 클릭 한 번으로 자동 통합하는 RPA 프로그램입니다.
|
||||
|
||||
## 🎯 프로젝트 개요
|
||||
|
||||
### 해결하는 문제
|
||||
- 매월/매주 여러 부서에서 받는 엑셀 파일을 하나로 합쳐야 할 때
|
||||
- 수작업 복사/붙여넣기로 인한 시간 낭비 (5시간 → 10초)
|
||||
- 데이터 입력 오류 제거
|
||||
- 반복 작업 자동화
|
||||
|
||||
### 주요 기능
|
||||
✅ 여러 엑셀 파일 자동 통합 (.xlsx, .xls, .xlsm)
|
||||
✅ 원본 파일명 추적 (어느 파일에서 왔는지)
|
||||
✅ 자동 타임스탬프 (통합_날짜_시간.xlsx)
|
||||
✅ 에러 처리 (일부 파일 실패해도 계속 진행)
|
||||
✅ 진행 상황 실시간 표시
|
||||
✅ 통합 전 미리보기
|
||||
|
||||
## 🚀 빠른 시작
|
||||
|
||||
### 1. 설치
|
||||
|
||||
```bash
|
||||
# 저장소 클론
|
||||
git clone https://github.com/gahusb/excel-merger-rpa.git
|
||||
cd excel-merger-rpa
|
||||
|
||||
# 의존성 설치
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
### 2. 사용법
|
||||
|
||||
#### 기본 사용
|
||||
```bash
|
||||
# 1. input 폴더에 엑셀 파일들을 넣기
|
||||
# 2. 프로그램 실행
|
||||
python excel_merger.py
|
||||
```
|
||||
|
||||
#### 예제
|
||||
```
|
||||
excel-merger-rpa/
|
||||
├── input/ # 여기에 엑셀 파일 넣기
|
||||
│ ├── 1월_매출.xlsx
|
||||
│ ├── 2월_매출.xlsx
|
||||
│ └── 3월_매출.xlsx
|
||||
├── output/ # 통합 파일이 여기에 생성됨
|
||||
│ └── 통합데이터_20250210_143022.xlsx
|
||||
└── excel_merger.py # 실행 파일
|
||||
```
|
||||
|
||||
### 3. 실행 화면
|
||||
|
||||
```
|
||||
==================================================
|
||||
📊 엑셀 데이터 통합 자동화 프로그램
|
||||
Excel Data Merger RPA
|
||||
==================================================
|
||||
|
||||
📋 파일 목록:
|
||||
--------------------------------------------------
|
||||
1. 1월_매출.xlsx
|
||||
- 150행 × 5열
|
||||
2. 2월_매출.xlsx
|
||||
- 180행 × 5열
|
||||
3. 3월_매출.xlsx
|
||||
- 170행 × 5열
|
||||
--------------------------------------------------
|
||||
총 3개 파일, 예상 통합 행 수: 500행
|
||||
|
||||
계속하시겠습니까? (y/n): y
|
||||
|
||||
📂 발견된 파일 수: 3개
|
||||
--------------------------------------------------
|
||||
1. 1월_매출.xlsx 읽는 중...
|
||||
✓ 150행 읽기 완료
|
||||
2. 2월_매출.xlsx 읽는 중...
|
||||
✓ 180행 읽기 완료
|
||||
3. 3월_매출.xlsx 읽는 중...
|
||||
✓ 170행 읽기 완료
|
||||
|
||||
🔄 데이터 통합 중...
|
||||
💾 파일 저장 중: output/통합데이터_20250210_143022.xlsx
|
||||
|
||||
==================================================
|
||||
✅ 통합 완료!
|
||||
📊 총 500행 통합됨
|
||||
📁 저장 위치: output/통합데이터_20250210_143022.xlsx
|
||||
==================================================
|
||||
```
|
||||
|
||||
## 📋 요구사항
|
||||
|
||||
- Python 3.8 이상
|
||||
- pandas
|
||||
- openpyxl (xlsx 파일)
|
||||
- xlrd (xls 파일)
|
||||
|
||||
## 🎨 사용 사례
|
||||
|
||||
### 1. 월별 매출 데이터 통합
|
||||
```
|
||||
각 지점에서 제출한 월별 매출 보고서를 본사에서 통합
|
||||
→ 5시간 작업이 10초로 단축
|
||||
```
|
||||
|
||||
### 2. 부서별 인원 현황 통합
|
||||
```
|
||||
각 부서 인사담당자가 작성한 인원 현황을 인사팀에서 통합
|
||||
→ 실수 없이 정확한 데이터
|
||||
```
|
||||
|
||||
### 3. 재고 현황 통합
|
||||
```
|
||||
여러 창고의 재고 데이터를 하나로 합쳐서 분석
|
||||
→ 재고 관리 효율 증가
|
||||
```
|
||||
|
||||
## 🛠 커스터마이징
|
||||
|
||||
### 코드에서 사용하기
|
||||
|
||||
```python
|
||||
from excel_merger import ExcelMerger
|
||||
|
||||
# ExcelMerger 객체 생성
|
||||
merger = ExcelMerger(
|
||||
input_folder="my_data", # 입력 폴더
|
||||
output_folder="merged_data" # 출력 폴더
|
||||
)
|
||||
|
||||
# 통합 실행
|
||||
df, output_path = merger.merge_excel_files(
|
||||
output_filename="최종통합.xlsx" # 사용자 지정 파일명
|
||||
)
|
||||
|
||||
# 결과 확인
|
||||
print(f"총 {len(df)}행 통합됨")
|
||||
print(f"파일 위치: {output_path}")
|
||||
```
|
||||
|
||||
### 원본 파일명 컬럼 제거하기
|
||||
|
||||
`excel_merger.py` 67번째 줄:
|
||||
```python
|
||||
# 이 줄을 주석 처리하면 원본 파일명 컬럼이 추가되지 않음
|
||||
# df['원본파일'] = filename
|
||||
```
|
||||
|
||||
### 특정 시트만 읽기
|
||||
|
||||
```python
|
||||
df = pd.read_excel(file, sheet_name="Sheet1") # 특정 시트
|
||||
```
|
||||
|
||||
## 🎯 실제 효과
|
||||
|
||||
| 항목 | 수작업 | 자동화 | 절감 |
|
||||
|------|--------|--------|------|
|
||||
| **시간** | 5시간 | 10초 | 99.9% |
|
||||
| **정확도** | 95% | 100% | +5% |
|
||||
| **비용** | 시급 1만원 × 5시간 | 무료 | 5만원 |
|
||||
|
||||
**월 20회 작업 시:**
|
||||
- 시간 절감: 100시간/월
|
||||
- 비용 절감: 100만원/월
|
||||
|
||||
## 📂 프로젝트 구조
|
||||
|
||||
```
|
||||
excel-merger-rpa/
|
||||
├── excel_merger.py # 메인 프로그램
|
||||
├── requirements.txt # 의존성 목록
|
||||
├── README.md # 이 파일
|
||||
├── .gitignore # Git 제외 파일
|
||||
├── input/ # 입력 폴더 (엑셀 파일 넣기)
|
||||
└── output/ # 출력 폴더 (통합 파일 생성)
|
||||
```
|
||||
|
||||
## 🐛 트러블슈팅
|
||||
|
||||
### "ModuleNotFoundError: No module named 'pandas'"
|
||||
```bash
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
### "Permission denied" 에러
|
||||
- 출력 파일이 엑셀에서 열려있는지 확인
|
||||
- 파일을 닫고 다시 실행
|
||||
|
||||
### 한글 깨짐
|
||||
```python
|
||||
# excel_merger.py에서 encoding 추가
|
||||
df.to_excel(output_path, index=False, encoding='utf-8-sig')
|
||||
```
|
||||
|
||||
## 💡 추가 기능 아이디어
|
||||
|
||||
- [ ] GUI 버전 (tkinter)
|
||||
- [ ] 특정 시트만 선택해서 통합
|
||||
- [ ] CSV 파일도 지원
|
||||
- [ ] 중복 데이터 자동 제거
|
||||
- [ ] 데이터 정제 (공백 제거, 날짜 형식 통일)
|
||||
- [ ] 스케줄러 (매일 자동 실행)
|
||||
|
||||
## 📞 문의
|
||||
|
||||
프로젝트 관련 문의 또는 커스터마이징 요청:
|
||||
- **이메일**: bgg8988@gmail.com
|
||||
- **포트폴리오**: https://jaengseung-made.com
|
||||
- **전화**: 010-3907-1392
|
||||
|
||||
## 📄 라이선스
|
||||
|
||||
MIT License - 자유롭게 사용, 수정, 배포 가능합니다.
|
||||
|
||||
---
|
||||
|
||||
**Made by 쟁승메이드** | [더 많은 RPA 프로젝트 보기](https://jaengseung-made.com)
|
||||
40
create_sample_data.py
Normal file
40
create_sample_data.py
Normal file
@@ -0,0 +1,40 @@
|
||||
"""
|
||||
샘플 엑셀 데이터 생성 스크립트
|
||||
테스트용 엑셀 파일들을 자동으로 생성합니다.
|
||||
"""
|
||||
|
||||
import pandas as pd
|
||||
import random
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
def create_sample_sales_data():
|
||||
"""샘플 매출 데이터 생성"""
|
||||
|
||||
months = ['1월', '2월', '3월']
|
||||
|
||||
for month in months:
|
||||
# 랜덤 데이터 생성
|
||||
data = {
|
||||
'날짜': [datetime(2025, months.index(month)+1, day)
|
||||
for day in range(1, random.randint(25, 31))],
|
||||
'제품명': [f'제품{random.randint(1,10)}'
|
||||
for _ in range(random.randint(25, 30))],
|
||||
'수량': [random.randint(1, 100)
|
||||
for _ in range(random.randint(25, 30))],
|
||||
'단가': [random.randint(1000, 50000)
|
||||
for _ in range(random.randint(25, 30))],
|
||||
}
|
||||
|
||||
# 매출액 계산
|
||||
df = pd.DataFrame(data)
|
||||
df['매출액'] = df['수량'] * df['단가']
|
||||
|
||||
# 파일 저장
|
||||
filename = f'input/{month}_매출.xlsx'
|
||||
df.to_excel(filename, index=False)
|
||||
print(f'✓ {filename} 생성 완료 ({len(df)}행)')
|
||||
|
||||
if __name__ == '__main__':
|
||||
print('📊 샘플 데이터 생성 중...\n')
|
||||
create_sample_sales_data()
|
||||
print('\n✅ 완료! input 폴더를 확인하세요.')
|
||||
171
excel_merger.py
Normal file
171
excel_merger.py
Normal file
@@ -0,0 +1,171 @@
|
||||
"""
|
||||
엑셀 데이터 통합 자동화 프로그램
|
||||
Excel Data Merger RPA
|
||||
|
||||
여러 엑셀 파일을 하나로 자동 통합하는 RPA 프로그램입니다.
|
||||
"""
|
||||
|
||||
import pandas as pd
|
||||
import glob
|
||||
import os
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
class ExcelMerger:
|
||||
"""엑셀 파일 통합 클래스"""
|
||||
|
||||
def __init__(self, input_folder="input", output_folder="output"):
|
||||
"""
|
||||
초기화
|
||||
|
||||
Args:
|
||||
input_folder: 입력 엑셀 파일들이 있는 폴더
|
||||
output_folder: 통합 파일을 저장할 폴더
|
||||
"""
|
||||
self.input_folder = input_folder
|
||||
self.output_folder = output_folder
|
||||
|
||||
# 폴더 생성
|
||||
Path(input_folder).mkdir(exist_ok=True)
|
||||
Path(output_folder).mkdir(exist_ok=True)
|
||||
|
||||
def get_excel_files(self):
|
||||
"""입력 폴더에서 모든 엑셀 파일 찾기"""
|
||||
patterns = [
|
||||
f"{self.input_folder}/*.xlsx",
|
||||
f"{self.input_folder}/*.xls",
|
||||
f"{self.input_folder}/*.xlsm"
|
||||
]
|
||||
|
||||
files = []
|
||||
for pattern in patterns:
|
||||
files.extend(glob.glob(pattern))
|
||||
|
||||
return files
|
||||
|
||||
def merge_excel_files(self, output_filename=None):
|
||||
"""
|
||||
엑셀 파일들을 하나로 통합
|
||||
|
||||
Args:
|
||||
output_filename: 출력 파일명 (기본값: 현재 시간)
|
||||
|
||||
Returns:
|
||||
통합된 DataFrame과 출력 파일 경로
|
||||
"""
|
||||
excel_files = self.get_excel_files()
|
||||
|
||||
if not excel_files:
|
||||
print(f"⚠️ '{self.input_folder}' 폴더에 엑셀 파일이 없습니다.")
|
||||
return None, None
|
||||
|
||||
print(f"📂 발견된 파일 수: {len(excel_files)}개")
|
||||
print("-" * 50)
|
||||
|
||||
# 모든 데이터를 담을 리스트
|
||||
all_data = []
|
||||
|
||||
# 각 파일 읽기
|
||||
for i, file in enumerate(excel_files, 1):
|
||||
try:
|
||||
filename = os.path.basename(file)
|
||||
print(f"{i}. {filename} 읽는 중...")
|
||||
|
||||
# 엑셀 파일 읽기
|
||||
df = pd.read_excel(file)
|
||||
|
||||
# 원본 파일명 컬럼 추가 (선택사항)
|
||||
df['원본파일'] = filename
|
||||
|
||||
all_data.append(df)
|
||||
print(f" ✓ {len(df)}행 읽기 완료")
|
||||
|
||||
except Exception as e:
|
||||
print(f" ✗ 에러 발생: {e}")
|
||||
continue
|
||||
|
||||
if not all_data:
|
||||
print("❌ 읽을 수 있는 파일이 없습니다.")
|
||||
return None, None
|
||||
|
||||
# 데이터 통합
|
||||
print("\n🔄 데이터 통합 중...")
|
||||
merged_df = pd.concat(all_data, ignore_index=True)
|
||||
|
||||
# 출력 파일명 생성
|
||||
if output_filename is None:
|
||||
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||
output_filename = f"통합데이터_{timestamp}.xlsx"
|
||||
|
||||
output_path = os.path.join(self.output_folder, output_filename)
|
||||
|
||||
# 파일 저장
|
||||
print(f"💾 파일 저장 중: {output_path}")
|
||||
merged_df.to_excel(output_path, index=False)
|
||||
|
||||
print("\n" + "=" * 50)
|
||||
print("✅ 통합 완료!")
|
||||
print(f"📊 총 {len(merged_df)}행 통합됨")
|
||||
print(f"📁 저장 위치: {output_path}")
|
||||
print("=" * 50)
|
||||
|
||||
return merged_df, output_path
|
||||
|
||||
def get_summary(self):
|
||||
"""입력 폴더의 파일 정보 요약"""
|
||||
files = self.get_excel_files()
|
||||
|
||||
if not files:
|
||||
print("입력 폴더에 엑셀 파일이 없습니다.")
|
||||
return
|
||||
|
||||
print("\n📋 파일 목록:")
|
||||
print("-" * 50)
|
||||
|
||||
total_rows = 0
|
||||
for i, file in enumerate(files, 1):
|
||||
try:
|
||||
filename = os.path.basename(file)
|
||||
df = pd.read_excel(file)
|
||||
rows = len(df)
|
||||
cols = len(df.columns)
|
||||
total_rows += rows
|
||||
|
||||
print(f"{i}. {filename}")
|
||||
print(f" - {rows}행 × {cols}열")
|
||||
|
||||
except Exception as e:
|
||||
print(f"{i}. {os.path.basename(file)}")
|
||||
print(f" - 에러: {e}")
|
||||
|
||||
print("-" * 50)
|
||||
print(f"총 {len(files)}개 파일, 예상 통합 행 수: {total_rows}행")
|
||||
|
||||
|
||||
def main():
|
||||
"""메인 실행 함수"""
|
||||
print("=" * 50)
|
||||
print("📊 엑셀 데이터 통합 자동화 프로그램")
|
||||
print(" Excel Data Merger RPA")
|
||||
print("=" * 50)
|
||||
print()
|
||||
|
||||
# ExcelMerger 객체 생성
|
||||
merger = ExcelMerger(input_folder="input", output_folder="output")
|
||||
|
||||
# 파일 요약 출력
|
||||
merger.get_summary()
|
||||
|
||||
print("\n계속하시겠습니까? (y/n): ", end="")
|
||||
response = input().strip().lower()
|
||||
|
||||
if response == 'y':
|
||||
# 통합 실행
|
||||
merger.merge_excel_files()
|
||||
else:
|
||||
print("취소되었습니다.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
0
input/.gitkeep
Normal file
0
input/.gitkeep
Normal file
0
output/.gitkeep
Normal file
0
output/.gitkeep
Normal file
3
requirements.txt
Normal file
3
requirements.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
pandas==2.2.0
|
||||
openpyxl==3.1.2
|
||||
xlrd==2.0.1
|
||||
Reference in New Issue
Block a user