【Python】Excelファイルをopenpyxlで自動操作する

Python

こんにちは、かつコーチです。

毎月手作業でExcelに数字を入力し直す作業、正直うんざりしませんか。

「集計はいつも同じ手順なのに、なぜ毎回手で入力しているんだろう」

そんな定型作業は、openpyxl(PythonからExcelファイルを読み書きするためのライブラリ)で自動化できます。

この記事では、openpyxlのインストールから、セルの読み書き、複数シートの操作までを解説します。

読み終える頃には、Excel集計作業をPythonスクリプトに任せられるようになります。

基本の書き方・実装手順

openpyxlのインストール

pip install openpyxl

手順1:新規Excelファイルを作成してセルに書き込む

Workbookクラスで新しいExcelファイル(ブック)を作成します。

from openpyxl import Workbook

wb = Workbook()
ws = wb.active
ws.title = "売上"

ws["A1"] = "商品名"
ws["B1"] = "売上"

ws["A2"] = "りんご"
ws["B2"] = 1200

ws["A3"] = "みかん"
ws["B3"] = 800

wb.save("sales.xlsx")
print("sales.xlsxを作成しました。")

wb.activeは、デフォルトで用意されている最初のシート(ワークシート)を取得します。

ws["A1"] = "商品名"のように、Excelと同じセル番地でそのまま値を代入できます。

手順2:既存のExcelファイルを読み込む

作成したファイルを読み込んで、中身を確認してみます。

from openpyxl import load_workbook

wb = load_workbook("sales.xlsx")
ws = wb["売上"]

for row in ws.iter_rows(min_row=2, values_only=True):
    name, amount = row
    print(f"{name}: {amount}円")

実行結果は次の通りです。

りんご: 1200円
みかん: 800円

load_workbook()で既存ファイルを開き、wb["売上"]でシート名を指定して取得します。

iter_rows(min_row=2, values_only=True)は、2行目以降のセルの値だけをタプルで取得するオプションです。

手順3:複数シートを操作する

create_sheet()で新しいシートを追加し、シートを切り替えながら操作します。

from openpyxl import Workbook

wb = Workbook()

ws_sales = wb.active
ws_sales.title = "売上"
ws_sales["A1"] = "商品名"
ws_sales["B1"] = "売上"
ws_sales["A2"] = "りんご"
ws_sales["B2"] = 1200

ws_stock = wb.create_sheet("在庫")
ws_stock["A1"] = "商品名"
ws_stock["B1"] = "在庫数"
ws_stock["A2"] = "りんご"
ws_stock["B2"] = 30

print(wb.sheetnames)

wb.save("sales_and_stock.xlsx")

実行すると、['売上', '在庫']という2つのシート名が出力され、両方のシートを含むファイルが保存されます。

つまずきやすい設定・注意点

ws["A1"]のようなセル指定は、Excelの列がアルファベット(A、B、C…)である点に注意してください。

数値のインデックスで指定したい場合は、ws.cell(row=1, column=1)という書き方も使えます。

セル同士の関係や大量データを扱う場合は、行番号・列番号どちらでも操作できることを覚えておくと便利です。

よくあるつまずきポイント・エラー対処

数式のセルを読み込むと計算結果ではなく数式文字列が返ってくる

これは筆者が実際に、他の人が作ったExcelファイルを集計しようとしたときに遭遇したつまずきです。

SUM関数が入ったセルを読み込んだところ、期待した合計値ではなく=SUM(B2:B3)という文字列が返ってきました。

❌ Before(数式をそのまま読み込んでしまう書き方)

from openpyxl import load_workbook

wb = load_workbook("sales_with_formula.xlsx")
ws = wb.active

total = ws["B4"].value
print(total)

実行結果は次のようになり、数値として使えませんでした。

=SUM(B2:B3)

原因は、load_workbook()のデフォルトの挙動が「数式そのもの」を読み込む設定になっているためです。

Excel上で表示されている計算結果と、openpyxlが読み込む値は別物だと知らず、しばらく原因が分かりませんでした。

✅ After(data_only=Trueで計算結果を読み込む書き方)

from openpyxl import load_workbook

wb = load_workbook("sales_with_formula.xlsx", data_only=True)
ws = wb.active

total = ws["B4"].value
print(total)

data_only=Trueを指定すると、数式ではなく最後にExcelで計算された結果の値を読み込めます。

2000

ただし注意点として、data_only=Trueは「そのファイルを最後に開いたときに保存された計算結果」を読み込む仕組みです。

Python側でセルの値を書き換えただけでは数式は再計算されないため、Excelアプリで一度開いて保存し直す必要がある場合があります。

数式付きのExcelファイルを扱うときは、この挙動の違いを覚えておきましょう。

まとめ

この記事のポイント

  • Workbook()で新規ファイル作成、load_workbook()で既存ファイルの読み込みができる
  • セルへのアクセスはws["A1"]のような番地指定とws.cell(row, column)の両方が使える
  • create_sheet()でシートを追加し、複数シートを扱える
  • iter_rows(values_only=True)で複数行のデータをまとめて取得できる
  • 数式入りのセルを扱う場合はdata_only=Trueで計算結果を読み込む

次に読むべき記事

  • CSVファイルを一括処理する自動化スクリプトを書く
  • csvモジュールでCSVファイルを読み書きする
  • pathlibでファイルパスをモダンに扱う

タグ: Python, 中級者向け, 自動化

タイトルとURLをコピーしました