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")
'Python > PYTHON OpenPyXL (python and excel)' 카테고리의 다른 글
[openpyxl] 새로운 행, 열을 더하고 삭제하는 법 #2: (0) | 2020.08.10 |
---|---|
[openpyxl] sheet 이름 파악하기, 필요없는 sheet 지우기 (0) | 2020.06.22 |
[openpyxl] 새로운 행, 열을 더하고 삭제하는 법 #1:append (0) | 2020.06.08 |
[openpyxl] excel 파일 저장하기 전에 파이썬 콘솔에서 결과 미리 프린트해서 보는 법 (0) | 2020.06.05 |
[openpyxl] 각 엑셀 행과 열에 새로운 값을 입력할 경우 (0) | 2020.06.04 |