다른 명령
튜닝 보고서 파일들을 읽어서 엑셀로 정리하는 프로그램
import os
import re
import sys
from openpyxl import Workbook
from openpyxl.styles import Font, PatternFill, Alignment
def extract_report_data(file_path):
"""튜닝 보고서 파일에서 데이터 추출"""
try:
# 인코딩 자동 감지
encodings = ['utf-8-sig', 'utf-8', 'cp949', 'euc-kr']
content = None
for encoding in encodings:
try:
with open(file_path, 'r', encoding=encoding) as f:
content = f.read()
break
except UnicodeDecodeError:
continue
if content is None:
print(f"인코딩 오류: {file_path}")
return None
data = {
'DB': '',
'식별자': '',
'업무구분': '',
'수집유형': '',
'프로그램명': '',
'서비스': '',
'온라인/배치': '',
'수행빈도': '',
'Dynamic SQL여부': '',
'개발담당자': '',
'담당자연락처': '',
'Logical Reads(전)': '',
'Logical Reads(후)': '',
'Elapsed Time(전)': '',
'Elapsed Time(후)': '',
'파일명': os.path.basename(file_path)
}
# 각 항목 추출 (정규식 사용)
patterns = {
'DB': r'1\)\s*DB\s*[::]\s*(.+)',
'식별자': r'2\)\s*식별자\s*[::]\s*(.+)',
'업무구분': r'\(?\s*3\)?\s*업무\s*구분\s*[::]\s*(.+)',
'수집유형': r'4\)\s*수집\s*유형\s*[::]\s*(.+)',
'프로그램명': r'5\)\s*프로그램명\s*/\s*화면명\s*[::]\s*(.+)',
'서비스': r'6\)\s*서비스\s*[::]\s*(.+)',
'온라인/배치': r'7\)\s*온라인\s*/\s*배치\s*[::]\s*(.+)',
'수행빈도': r'8\)\s*수행\s*빈도.*[::]\s*(.+)',
'Dynamic SQL여부': r'9\)\s*Dynamic\s*S[OQ]L\s*여부.*[::]\s*(.+)',
'개발담당자': r'10\)\s*개발\s*담당자\s*[::]\s*(.+)',
'담당자연락처': r'11\)\s*담당자\s*연락처\s*[::]\s*(.+)',
}
for key, pattern in patterns.items():
match = re.search(pattern, content, re.IGNORECASE | re.MULTILINE)
if match:
data[key] = match.group(1).strip()
# Logical Reads 추출
logical_reads = re.search(r'Logical\s*Reads.*[::]\s*([0-9,]+)\s*/\s*([0-9,]+)', content, re.IGNORECASE)
if logical_reads:
data['Logical Reads(전)'] = logical_reads.group(1).strip().replace(',', '')
data['Logical Reads(후)'] = logical_reads.group(2).strip().replace(',', '')
# Elapsed Time 추출
elapsed_time = re.search(r'Elapsed\s*Time.*[::]\s*([0-9.]+)\s*/\s*([0-9.]+)', content, re.IGNORECASE)
if elapsed_time:
data['Elapsed Time(전)'] = elapsed_time.group(1).strip()
data['Elapsed Time(후)'] = elapsed_time.group(2).strip()
return data
except Exception as e:
print(f"파일 처리 오류 [{file_path}]: {str(e)}")
return None
def create_excel_report(folder_path, output_file='튜닝보고서_정리.xlsx'):
"""폴더의 모든 튜닝 보고서를 읽어 엑셀로 정리"""
# 워크북 생성
wb = Workbook()
ws = wb.active
ws.title = "튜닝보고서"
# 헤더 작성
headers = ['No', 'DB', '식별자', '업무구분', '수집유형', '프로그램명', '서비스',
'온라인/배치', '수행빈도', 'Dynamic SQL여부', '개발담당자', '담당자연락처',
'Logical Reads(전)', 'Logical Reads(후)', '개선율(%)',
'Elapsed Time(전)', 'Elapsed Time(후)', '개선율(%)', '파일명']
# 헤더 스타일
header_fill = PatternFill(start_color="366092", end_color="366092", fill_type="solid")
header_font = Font(bold=True, color="FFFFFF", size=11)
for col_idx, header in enumerate(headers, 1):
cell = ws.cell(row=1, column=col_idx, value=header)
cell.fill = header_fill
cell.font = header_font
cell.alignment = Alignment(horizontal='center', vertical='center')
# 파일 읽기
files = [f for f in os.listdir(folder_path) if f.endswith(('.txt', '.doc', '.docx', '.hwp'))]
if not files:
print(f"폴더에 파일이 없습니다: {folder_path}")
return
print(f"총 {len(files)}개 파일 처리 중...")
row_idx = 2
success_count = 0
for idx, filename in enumerate(files, 1):
file_path = os.path.join(folder_path, filename)
print(f"[{idx}/{len(files)}] 처리 중: {filename}")
data = extract_report_data(file_path)
if data:
# 개선율 계산
logical_improve = ''
elapsed_improve = ''
try:
if data['Logical Reads(전)'] and data['Logical Reads(후)']:
before = float(data['Logical Reads(전)'])
after = float(data['Logical Reads(후)'])
if before > 0:
logical_improve = round((before - after) / before * 100, 2)
except:
pass
try:
if data['Elapsed Time(전)'] and data['Elapsed Time(후)']:
before = float(data['Elapsed Time(전)'])
after = float(data['Elapsed Time(후)'])
if before > 0:
elapsed_improve = round((before - after) / before * 100, 2)
except:
pass
# 데이터 쓰기
ws.cell(row=row_idx, column=1, value=success_count + 1)
ws.cell(row=row_idx, column=2, value=data['DB'])
ws.cell(row=row_idx, column=3, value=data['식별자'])
ws.cell(row=row_idx, column=4, value=data['업무구분'])
ws.cell(row=row_idx, column=5, value=data['수집유형'])
ws.cell(row=row_idx, column=6, value=data['프로그램명'])
ws.cell(row=row_idx, column=7, value=data['서비스'])
ws.cell(row=row_idx, column=8, value=data['온라인/배치'])
ws.cell(row=row_idx, column=9, value=data['수행빈도'])
ws.cell(row=row_idx, column=10, value=data['Dynamic SQL여부'])
ws.cell(row=row_idx, column=11, value=data['개발담당자'])
ws.cell(row=row_idx, column=12, value=data['담당자연락처'])
ws.cell(row=row_idx, column=13, value=data['Logical Reads(전)'])
ws.cell(row=row_idx, column=14, value=data['Logical Reads(후)'])
ws.cell(row=row_idx, column=15, value=logical_improve)
ws.cell(row=row_idx, column=16, value=data['Elapsed Time(전)'])
ws.cell(row=row_idx, column=17, value=data['Elapsed Time(후)'])
ws.cell(row=row_idx, column=18, value=elapsed_improve)
ws.cell(row=row_idx, column=19, value=data['파일명'])
row_idx += 1
success_count += 1
# 컬럼 너비 자동 조정
for col in ws.columns:
max_length = 0
column = col[0].column_letter
for cell in col:
try:
if len(str(cell.value)) > max_length:
max_length = len(str(cell.value))
except:
pass
adjusted_width = min(max_length + 2, 50)
ws.column_dimensions[column].width = adjusted_width
# 엑셀 저장
output_path = os.path.join(folder_path, output_file)
wb.save(output_path)
print(f"\n완료! {success_count}개 파일 처리 완료")
print(f"저장 위치: {output_path}")
if __name__ == '__main__':
if len(sys.argv) != 2:
print("사용법: python parse_tuning_reports.py <폴더경로>")
print("예시: python parse_tuning_reports.py C:\\튜닝보고서")
sys.exit(1)
folder_path = sys.argv[1]
if not os.path.exists(folder_path):
print(f"폴더를 찾을 수 없습니다: {folder_path}")
sys.exit(1)
create_excel_report(folder_path)
```
사용 방법:
python parse_tuning_reports.py C:\튜닝보고서폴더
주요 기능:
1. ✅ 폴더 내 모든 튜닝 보고서 파일 자동 처리 2. ✅ UTF-8, CP949(ANSI) 자동 인식 3. ✅ 11개 항목 자동 추출 4. ✅ 성능 개선율 자동 계산 5. ✅ 엑셀 파일로 자동 정리 (헤더 스타일 포함)
혹시 파일 형식이 조금 다르면 샘플 파일을 보여주시면 패턴을 수정해드릴게요!