Profile picture

[Python] 파이썬으로 엑셀 파일 하나로 합치기

JaehyoJJAng2023년 05월 10일

Openpyxl

파이썬에서 엑셀을 다루는 것을 쉽게 해주는 도구


a. 라이브러리 설치

$ pip install openpyxl

데이터 생성

엑셀 파일을 병합하기 이전에 샘플 .xlsx 파일을 생성해보도록 하자

from typing import Dict,List
import time
import pyexcel as px
import random
import os

class MakeAccount:
    def __init__(self) -> None:
        self.NUM_SAMPLES: int = 1000
        self.first_name_samples : str = "김이박최정강조윤장임"
        self.middle_name_samples : str = "민서예지도하주윤채현지"
        self.last_name_samples : str = "준윤우원호후서연아은진"
        self.alphabet_samples : str = 'abcdefghizklmnopqrstuvwxyz1234567890'
        self.dir_name: str = 'personal_info'
    
    @staticmethod
    def start_job() -> None:
        print('Process Start')
    
    @staticmethod
    def end_job() -> None:
        print("Process Done")
        
    def random_string(self,length: int) -> str:
        result : str = ''
        for i in range(length):
            result += random.choice(self.alphabet_samples)
        return result
    
    def random_name(self) -> str:
        result : str = ''
        result += random.choice(self.first_name_samples)
        result += random.choice(self.middle_name_samples)
        result += random.choice(self.last_name_samples)
        return result
    
    def make_text(self) -> List[Dict[str,str]]:
        dict_data : List[Dict[str,str]] = list()
        for i in range(1,self.NUM_SAMPLES + 1):
            dic : Dict[str,str] = dict()
            
            # 사람이름 생성
            dic['name'] = f'{self.random_name()}, '
            
            # 나이 생성
            dic['age'] = f'{str(time.time())[-2:]}, '
            
            # 이메일 생성
            dic['e-mail'] = f'{self.random_string(length=8)}@leejaehyo.com, '
            
            # 부서명 생성
            dic['division'] = f'{self.random_string(length=3)}, '
            
            # 핸드폰 번호 생성
            dic['telephone'] = f'{str(time.time())[-4:]} - {str(time.time())[-6:-2]},'
            
            # 성별 생성
            dic['sex'] = f"{random.choice(['male','female'])}"
            dict_data.append(dic)            
        return dict_data
    
    def create_text_file(self,dict_data: List[Dict[str,str]]) -> None:
        # 헤더 정의
        HEADER : List[str] = ['name','age','e-mail','division','telephone','sex']
        
        # 디렉토리 생성
        if not os.path.exists(self.dir_name):
            os.mkdir(self.dir_name)

        for i,data in enumerate(dict_data,1):
            contents : List[str] = []
            
            file_name : str = f'{os.path.join(self.dir_name,f"{i}.xlsx")}'
            
            contents.append(data['name'])
            contents.append(data['age'])
            contents.append(data['e-mail'])
            contents.append(data['division'])
            contents.append(data['telephone'])
            contents.append(data['sex'])            
            
            # 헤더와 데이터를 합쳐 저장될 데이터 완성
            RESULT : List[List[str]] = [HEADER,contents]
            
            # 완성된 엑셀파일 저장
            px.save_as(array=RESULT,dest_file_name=file_name)
            
def main() -> None:
    # 작업 시간 계산
    start_time : float = time.time()
    
    # MakeAccount 객체 생성
    account : MakeAccount = MakeAccount()
    
    # 작업 시작
    account.start_job()
    
    # 개인정보 데이터 추출
    dict_data : List[Dict[str,str]] = account.make_text()
    
    # 파일로 만들기
    account.create_text_file(dict_data=dict_data)
    
    # 작업 종료
    account.end_job()
    
    # 끝난 시간 계산
    end_time : float = time.time()
    print(f'The job Took : {end_time - start_time} seconds')
        
main()

위 코드를 실행하여 1000개의 샘플 .xlsx 파일을 생성하도록 하자

$ python3 main.py
$ ls -lh personal_info | grep -v "^total" | wc -l
1000

정상적으로 샘플 파일이 생성되었다


엑셀 파일 병합

이제 각각의 엑셀 파일들을 병합하는 코드를 작성해보자

from typing import List
from openpyxl import load_workbook, Workbook
import time
import os
import sys

def merged_xlsx(target_directory: str, outfile_name: str, input_files: List[str]) -> None:
    # 데이터 저장할 리스트
    CONTENTS : List[str] = []
    
    # 첫 번째 파일 처리
    FILE_PROCESSED : bool = False
    
    # 새로운 엑셀 파일 생성
    merged_workbook : Workbook = Workbook()
    merged_sheet = merged_workbook.active
    
    for filename in input_files:
        if '.xlsx' not in filename:
            continue
            
        # 엑셀 파일 읽어오기
        load_book = load_workbook(filename=os.path.join(target_directory,filename))
        sheet = load_book.active
        
        # 첫 번째 파일 헤더 처리
        if not FILE_PROCESSED:
            for row in sheet.iter_rows(values_only=True):
                merged_sheet.append(row)
            FILE_PROCESSED = True
        else:
            # 헤더를 제외한 나머지 데이터 처리
            for row in sheet.iter_rows(min_row=2,values_only=True):
                merged_sheet.append(row)
                
    # 결과 파일 저장
    merged_workbook.save(outfile_name)
# 작업 시작
print('Process Start')

# 시작 시각
start_time : float = time.time()

# 파일들이 저장될 폴더명
target_directory : str = 'personal_info'

# 결과물 파일 이름
outfile_name : str = 'merged_ID.xlsx'

# 폴더 내용물 열람해 목록 생성
input_files : List[str] = os.listdir(target_directory)

# xlsx 병합
merged_xlsx(target_directory=target_directory,outfile_name=outfile_name,input_files=input_files)

Loading script...