openpyxl:Excelファイルからデータを取り出して、別のExcelファイルに書き出してみよう

※社外のコラムニストによる記事です。Python関連の情報をお伝えします。
「シゴトがはかどるPython自動処理の教科書(著:クジラ飛行机様/マイナビ出版)」を利用して、Pythonを使った自動化について学んでいきます。
今回は2つのExcelブックを行き来して、データをコピー&ペースト(コピペ)するというプログラムについて学びます。
条件に合うデータを取り出して、新しいExcelにデータを書き出そう
事務処理をしていると、2つのExcelを行き来して、データを持ってきて、何かしらの単純な処理をすることがあります。例えばデータをコピペしたり、参照したり…。簡単だし必要なのだけど、地味に面倒な作業です。自動化出来たら助かりますね。
今回はそうした2つのブックを行き来して、何度もコペペを繰り返すという処理をするプログラムです。
ここでは顧客情報の一覧データが保存されているExcelファイルから、指定条件「横浜」と「名古屋」にあう見込み客だけを別のファイルにコピペするという処理を例に学習します。以下はサンプルコードです。
import openpyxl as excel
# 顧客一覧のブックを開く --- (*1)
book = excel.load_workbook("all-customer.xlsx")
# 名簿のシートを選択 --- (*2)
sheet = book["名簿"]
# 抜き出す顧客を記録する変数 --- (*3)
customers = [["名前","住所","購入プラン"]]
# 顧客一覧を抽出 --- (*4)
for row in sheet.iter_rows(min_row=3):
values = [v.value for v in row]
if values[0] is None: break
# 横浜と名古屋ならコピー --- (*5)
area = values[1]
if area == "横浜市" or area == "名古屋市":
customers.append(values)
print(values)
# 新規ブックを作成 --- (*6)
new_book = excel.Workbook()
new_sheet = new_book.active
new_sheet["A1"] = "横浜と名古屋の顧客名簿"
# 抽出したデータを繰り返しシートに書き込み --- (*7)
for row, row_val in enumerate(customers):
for col, val in enumerate(row_val):
c = new_sheet.cell(2+row, 1+col)
c.value = val
# ファイルに書き込む --- (*8)
new_book.save("yokohama_nagoya.xlsx")
これを実行すると、以下のExcelファイル(右/all-customer.xlsx)が生成されます。(左側は取り出し元の顧客名簿all-customer.xlsxです。)

ではここで、プログラムについて確認していきます。(1と2は割愛) 3は取り出したデータを保存する先のファイルのヘッダの設定です。
# 抜き出す顧客を記録する変数 --- (*3)
customers = [["名前","住所","購入プラン"]]
4はiter_rowsメソッドを利用して、Excelシートの行を順番に繰り返し処理してデータを取り出します。顧客名簿のExcelでは3行目以降に取得するべきデータが保存されているので、min_row=3となっています。最大行(max_row)は指定されていないので、データが入っている行まで取得されます。 ただ途中で空行があった場合、プログラムは停止してしまいます(プログラムでは先頭列が空欄だと処理が終了)。空行があっても進めたいときにはcontinueを使うこともできますが、continueにすると最後の空行の判定ができないので、Excelの終わり(104万行目)まで処理が続いてしまうことになります。なので、空行がないデータを用意するか、どうしても空行がある場合には行全体が空かどうかを判定するような条件を追加して終了判定をしてあげる必要があります。
# 顧客一覧を抽出 --- (*4)
for row in sheet.iter_rows(min_row=3):
values = [v.value for v in row]
if values[0] is None: break
5は横浜市か名古屋市という条件に当てはまる行かどうかを判定するのに利用されています。 Excelのインデックスは1からですが、Pythonのインデックスは0からスタートしますので、名前→0、住所→1、購入プラン→2というインデックス番号が振られます。そのため、住所を取り出すには values[1] を使い、それを area という変数に入れています。その後、変数名customersに対象となるデータを保存する役割を持つのが、[customers.append(values)]の部分で、後々新しいExcelに書き出すための準備が行われています。
# 横浜と名古屋ならコピー --- (*5)
area = values[1]
if area == "横浜市" or area == "名古屋市":
customers.append(values)
print(values)
6以降は新しいブックに対する処理で、7の部分で5で取り出した変数customersの値を書き込んでいく作業を行っています。
# 新規ブックを作成 --- (*6)
new_book = excel.Workbook()
new_sheet = new_book.active
new_sheet["A1"] = "横浜と名古屋の顧客名簿"
# 抽出したデータを繰り返しシートに書き込み --- (*7)
for row, row_val in enumerate(customers):
for col, val in enumerate(row_val):
c = new_sheet.cell(2+row, 1+col)
c.value = val
# ファイルに書き込む --- (*8)
new_book.save("yokohama_nagoya.xlsx")
それではきりが良いのでこちらで終了です。次回はこのデータから、さらにプランごとに異なるシートに分けて保存する方法について学びます。
今回もお付き合いいただき、ありがとうございました。
Pythonの自動化で業務の効率化を図りたい方は、グローバルウェイに依頼してみてはいかがでしょうか?興味がある方は以下をご覧の上、是非お問い合わせください。


