메뉴 여닫기
개인 메뉴 토글
로그인하지 않음
만약 지금 편집한다면 당신의 IP 주소가 공개될 수 있습니다.

텍스트파일을 읽어서 엑셀로 정리하기 (튜닝보고서를 엑셀로 정리)

데브카페

튜닝 보고서 파일들을 읽어서 엑셀로 정리하는 프로그램

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. ✅ 엑셀 파일로 자동 정리 (헤더 스타일 포함)

혹시 파일 형식이 조금 다르면 샘플 파일을 보여주시면 패턴을 수정해드릴게요!

Comments