Python/PYTHON OpenPyXL (python and excel)

[openpyxl] 여러 엑셀 파일을 하나의 파일 안에 정리해서 넣기

시키테이 2020. 6. 18. 12:12
반응형

openpyxl을 사용하는 가장 큰 이유 중 하나가 수십, 수백, 수천 개의 엑셀 파일을 하나의 엑셀 파일로 정리해서 놓기 위함일 겁니다. 물론 아주 완벽한 형태로는 못할지라고 하더라도 말이죠. 오늘은 그간 배운 명령 몇 개를 갖고 간단하게 정리하는 법을 해볼까 합니다. 

 

좋은 예가 선관위 자료인 것 같아요. 2020년 총선 자료를 보면 각 지역구(예를 들어 강남구 갑)마다 여당과 야당이 얼마나 많은 득표를 했냐는 건 알 수 있는데 문제는 선관위가 개별적인 엑셀 파일을 만들어서 전체 지역 (예를 들어 서울)을 보기 어려움이 있다는 데 있습니다. 그래서 이 자료들을 한 폴더에 넣고 그 파일의 핵심 내용만을 추출해서 엑셀 파일 하나로 만들어보는 작업을 해보겠습니다. 

 

일단 라이브러리 데려오고 아래처럼 루프를 만들어서 새로운 파일에 층층이 쌓아줍니다. 

import openpyxl
import os

저는 이 폴더안에다가 선관위 (서울) 자료를 다 넣었어요. 

os.getcwd()
os.chdir("/Users/xxx/Downloads/제21대 국회의원선거(재보궐 포함) 투표구별 개표결과/지역구/1서울")

그 다음에 각 "파일명"으로 구성된 리스트를 만듭니다. 모든 게 다 loop를 위한 거죠. ^^

files=["개표상황(투표구별)_강남구갑.xlsx", 
"개표상황(투표구별)_강남구병.xlsx",
"개표상황(투표구별)_강남구을.xlsx",
"개표상황(투표구별)_강동구갑.xlsx",
"개표상황(투표구별)_강동구을.xlsx",
"개표상황(투표구별)_강북구갑.xlsx",
"개표상황(투표구별)_강북구을.xlsx",
"개표상황(투표구별)_강서구갑.xlsx",
"개표상황(투표구별)_강서구병.xlsx",
"개표상황(투표구별)_강서구을.xlsx",
"개표상황(투표구별)_관악구갑.xlsx",
"개표상황(투표구별)_관악구을.xlsx",
"개표상황(투표구별)_광진구갑.xlsx",
"개표상황(투표구별)_광진구을.xlsx",
"개표상황(투표구별)_구로구갑.xlsx",
"개표상황(투표구별)_구로구을.xlsx",
"개표상황(투표구별)_금천구.xlsx",
"개표상황(투표구별)_노원구갑.xlsx",
"개표상황(투표구별)_노원구병.xlsx",
"개표상황(투표구별)_노원구을.xlsx",
"개표상황(투표구별)_도봉구갑.xlsx",
"개표상황(투표구별)_도봉구을.xlsx",
"개표상황(투표구별)_동대문구갑.xlsx",
"개표상황(투표구별)_동대문구을.xlsx",
"개표상황(투표구별)_동작구갑.xlsx",
"개표상황(투표구별)_동작구을.xlsx",
"개표상황(투표구별)_마포구갑.xlsx",
"개표상황(투표구별)_마포구을.xlsx",
"개표상황(투표구별)_서대문구갑.xlsx",
"개표상황(투표구별)_서대문구을.xlsx",
"개표상황(투표구별)_서초구갑.xlsx",
"개표상황(투표구별)_서초구을.xlsx",
"개표상황(투표구별)_성북구갑.xlsx",
"개표상황(투표구별)_성북구을.xlsx",
"개표상황(투표구별)_송파구갑.xlsx",
"개표상황(투표구별)_송파구병.xlsx",
"개표상황(투표구별)_송파구을.xlsx",
"개표상황(투표구별)_양천구갑.xlsx",
"개표상황(투표구별)_양천구을.xlsx",
"개표상황(투표구별)_영등포구갑.xlsx",
"개표상황(투표구별)_영등포구을.xlsx",
"개표상황(투표구별)_용산구.xlsx",
"개표상황(투표구별)_은평구갑.xlsx",
"개표상황(투표구별)_은평구을.xlsx",
"개표상황(투표구별)_종로구.xlsx",
"개표상황(투표구별)_중구성동구갑_성동구.xlsx",
"개표상황(투표구별)_중구성동구을_중구.xlsx",
"개표상황(투표구별)_중랑구갑.xlsx",
"개표상황(투표구별)_중랑구을.xlsx"]

위처럼 수동으로 할 수도 있지만, 아래처럼 해도 됩니다. 그 폴더 안에 있는 모든 파일을 다 리스트라는 변수로 만들어 버럽니다. 참고로 파일이 몇 개인가 알아보면 50개로 나오네요. 

list = os.listdir("/Users/xxx/Downloads/제21대 국회의원선거(재보궐 포함) 투표구별 개표결과/지역구/1서울") # dir is your directory path
number_files = len(list)
print(number_files)

 

이제 새 파일을 한 번 만들어봅니다. 

wb_new=openpyxl.Workbook()
ws1=wb_new.create_sheet("number")

자료를 저는 투표수, 후보자이름, 그리고 지역구를 뽑아야 해서 기본적으로 새 파일의 3줄씩 썼고 그래서 루프는 한 줄 더 추가하도록 (i+=4)로 했습니다. 

i=0

for file_path in files:
    i+=4
    wb_old=openpyxl.load_workbook(file_path)
    ws=wb_old.worksheets[0]
    for j in range(0, ws.max_column):
        ws1.cell(row=i, column=j+1).value=ws.cell(row=3, column=j+1).value
        ws1.cell(row=i+1, column=j+1).value=ws.cell(row=5, column=j+1).value
        ws1.cell(row=i+2, column=j+1).value=ws.cell(row=7, column=j+1).value

wb_new.save("election.xlsx")

 

그러면 다음과 같은 자료가 한 파일에 쭉 뽑힙니다. 아 좋습니다. ㅎㅎ

 

 

만약에 각 정보들 (투표수, 후보자 이름, 선거구)을 각각의 sheet에 따로 만들어서 저장하려고 하면 아래와 같이 각 sheet를 만들어서 

wb_new=openpyxl.Workbook()
ws1=wb_new.create_sheet("number")
ws2=wb_new.create_sheet("candiates")
ws3=wb_new.create_sheet("precinct")

아래와 같이 해줘도 됩니다. 

 

i=0

for file_path in files:
    i+=1
    wb_old=openpyxl.load_workbook(file_path)
    ws=wb_old.worksheets[0]
    for j in range(0, ws.max_column):
        ws1.cell(row=i, column=j+1).value=ws.cell(row=7, column=j+1).value
        ws2.cell(row=i, column=j+1).value=ws.cell(row=5, column=j+1).value
        ws3.cell(row=i, column=j+1).value=ws.cell(row=3, column=j+1).value

wb_new.save("election_again.xlsx")

    
반응형