Python | ファイル・OS 操作:Excel 読み込み(openpyxl)

Python Python
スポンサーリンク
  1. 概要(openpyxlで「Excelを安全に読み取る」基本と勘所)
  2. 基本の使い方(ここが重要)
    1. インストールと基本読み込み
    2. シートの選択(名前・一覧・切り替え)
    3. セルの指定方法(A1表記・行列番号)
  3. 行・列・範囲の読み取り(反復とvalues_only)
    1. 行・列をループで読む(1行ずつ、1列ずつ)
    2. セルオブジェクトではなく「値だけ」を取る(values_only)
    3. 範囲指定でブロック読み(A1形式)
  4. 重要ポイントの深掘り(数式・日付・空セル・高速化)
    1. 数式を「式」か「結果」で読む(data_only)
    2. 日付・時刻の扱い(datetimeとして来る)
    3. 空セル・欠損の扱い(Noneで来る)
    4. 大きいファイルの高速化(read_only・data_only・values_only)
  5. 実務の読み取りパターン(ヘッダー行・辞書化・Pathlib・バリデーション)
    1. ヘッダー行を使って辞書化(列名でアクセス)
    2. Pathlibとの併用(存在確認・シート指定)
    3. 入力バリデーション(型・必須列の確認)
  6. よくある落とし穴の回避(結合セル・隠しシート・拡張子・計算値)
    1. 結合セル(merged cells)は「先頭セル」に値がある
    2. 非表示や保護シートの存在
    3. .xlsx以外は対象外(.xlsは不可)
    4. 数式結果がNoneになるケース(再計算未保存)
  7. 例題で身につける(定番から一歩先まで)
    1. 例題1:テーブル範囲の行を読み、合計を計算
    2. 例題2:ヘッダー辞書化して安全に参照
    3. 例題3:read_onlyで巨大シートをストリーム処理
    4. 例題4:結合セルの先頭値だけを拾う
  8. まとめ

概要(openpyxlで「Excelを安全に読み取る」基本と勘所)

openpyxlは.xlsx形式のExcelをPythonで読み書きできる定番ライブラリです。読み込みでは「どのシートを読むか」「セル値をどう取り出すか」「数式や日付をどう扱うか」が重要ポイントです。初心者は「load_workbookで開く→シートを選ぶ→値を読む」の流れを体に入れつつ、values_onlyやdata_only、read_onlyなどのオプションを理解すると、実務でも安全・高速に扱えるようになります。


基本の使い方(ここが重要)

インストールと基本読み込み

pip install openpyxl
from openpyxl import load_workbook

wb = load_workbook("sample.xlsx")  # 既存Excelを開く
ws = wb.active                     # アクティブなシート(先頭など)
print(ws["A1"].value)              # A1セルの値を取得
Python

「どのファイル・どのシート・どのセル」を明確に書くのが基本線です。Pathlibと併用すると安全です。

シートの選択(名前・一覧・切り替え)

from openpyxl import load_workbook

wb = load_workbook("book.xlsx")
print(wb.sheetnames)          # ['Summary', 'Data', 'Logs'] など
ws = wb["Data"]               # 名前で取得
Python

シート名が変わる可能性があるなら、一覧を確認して存在チェックを入れます。

セルの指定方法(A1表記・行列番号)

from openpyxl import load_workbook

ws = load_workbook("book.xlsx").active
print(ws["B2"].value)         # A1表記
print(ws.cell(row=2, column=2).value)  # 行列指定(2行2列=B2)
Python

A1表記は直感的、行列指定はループに適しています。場面で使い分けます。


行・列・範囲の読み取り(反復とvalues_only)

行・列をループで読む(1行ずつ、1列ずつ)

from openpyxl import load_workbook

ws = load_workbook("table.xlsx").active
for row in ws.iter_rows(min_row=2, max_col=3):   # ヘッダーを除外、3列まで
    vals = [cell.value for cell in row]
    print(vals)
Python

列単位ならiter_colsを使います。min_row/max_row/min_col/max_colを指定すると、範囲を限定できます。

セルオブジェクトではなく「値だけ」を取る(values_only)

from openpyxl import load_workbook

ws = load_workbook("table.xlsx").active
for row in ws.iter_rows(min_row=2, values_only=True):
    print(row)  # タプルで値だけ(セルではない)
Python

values_only=Trueは「シンプルな読み取り」に最適。セルの書式や座標は不要で、値だけ欲しい場面で使います。

範囲指定でブロック読み(A1形式)

from openpyxl import load_workbook

ws = load_workbook("table.xlsx").active
for row in ws["A2:C10"]:  # A2〜C10のブロック
    print([c.value for c in row])
Python

固定範囲の抜き出しはA1範囲指定が読みやすいです。


重要ポイントの深掘り(数式・日付・空セル・高速化)

数式を「式」か「結果」で読む(data_only)

  • 数式そのものが欲しいならデフォルトでOK(cell.valueに’=SUM(…)’が入る)。
  • 計算結果が欲しいならdata_only=Trueでブックを開く(式ではなく計算済み値を取得)。
from openpyxl import load_workbook

wb = load_workbook("calc.xlsx", data_only=True)
ws = wb.active
print(ws["B2"].value)  # 計算結果(注意:Excelで再計算された最新値が入っている前提)
Python

Excelで再計算して保存していないと、古い値やNoneになることがある点に注意します。

日付・時刻の扱い(datetimeとして来る)

from openpyxl import load_workbook
from datetime import datetime

ws = load_workbook("dates.xlsx").active
dt = ws["A2"].value        # datetime.datetime になることが多い
if isinstance(dt, datetime):
    print(dt.strftime("%Y-%m-%d"))
Python

Excelのシリアル日付はopenpyxlがdatetimeへ変換します(フォーマットは自分で整えるのが基本)。

空セル・欠損の扱い(Noneで来る)

from openpyxl import load_workbook

ws = load_workbook("missing.xlsx").active
val = ws["C5"].value
if val is None:
    print("空セル(欠損)")
Python

欠損はNoneで表現されます。集計前にガード(Noneチェック)を入れると安全です。

大きいファイルの高速化(read_only・data_only・values_only)

  • read_only=Trueでストリーミング読み(大規模シート向け、編集不可)。
  • data_only=Trueで数式結果を直接取得(式不要時)。
  • values_only=Trueで値だけに簡略化。
from openpyxl import load_workbook

wb = load_workbook("huge.xlsx", read_only=True, data_only=True)
ws = wb.active
for row in ws.iter_rows(values_only=True):
    ...
Python

大量データは「作らず流す」が基本。必要な範囲に絞るとメモリ・時間を節約できます。


実務の読み取りパターン(ヘッダー行・辞書化・Pathlib・バリデーション)

ヘッダー行を使って辞書化(列名でアクセス)

from openpyxl import load_workbook

ws = load_workbook("users.xlsx").active
header = [c.value for c in ws[1]]            # 1行目がヘッダー
rows = []
for r in ws.iter_rows(min_row=2, values_only=True):
    rows.append(dict(zip(header, r)))        # {'name': 'Alice', 'age': 30} など
Python

列順が変わってもヘッダーに依存すれば堅牢。CSVのDictReaderに近い書き味です。

Pathlibとの併用(存在確認・シート指定)

from pathlib import Path
from openpyxl import load_workbook

src = Path("data") / "sales.xlsx"
if not src.exists():
    raise FileNotFoundError(src)

wb = load_workbook(src, data_only=True)
ws = wb["Monthly"]  # シート名固定なら明示
Python

ファイル結合と存在チェックを一緒に書けます。失敗時のメッセージもわかりやすく。

入力バリデーション(型・必須列の確認)

from openpyxl import load_workbook

ws = load_workbook("sales.xlsx", data_only=True)["Data"]
header = [c.value for c in ws[1]]
required = {"date", "item", "amount"}
if not required.issubset(set(header)):
    raise ValueError("必須列が不足")

for row in ws.iter_rows(min_row=2, values_only=True):
    date, item, amount = row[:3]
    if date is None or item is None or not isinstance(amount, (int, float)):
        continue  # スキップやログ記録など
Python

壊れた行はスキップ、後で見返せるログを残すのが定石です。


よくある落とし穴の回避(結合セル・隠しシート・拡張子・計算値)

結合セル(merged cells)は「先頭セル」に値がある

from openpyxl import load_workbook

ws = load_workbook("merged.xlsx").active
for rng in ws.merged_cells.ranges:
    print("結合範囲:", rng)  # 例: A1:C1
# 結合の右側・下側セルはNone。先頭セルの値を使う設計にする。
Python

結合セルは見た目と内部構造が違います。結合の先頭セルだけ値があり、他はNoneになります。

非表示や保護シートの存在

非表示シートも読み取れますが、見落としの原因になります。sheetnamesを確認し、必要なシートだけ対象にします。保護されていても読み取りは可能な場合が多いですが、編集は制約されます。

.xlsx以外は対象外(.xlsは不可)

openpyxlは.xlsx(Excel 2007+)向けです。.xls(旧形式)は扱えません。必要なら別ライブラリや事前変換を検討します。

数式結果がNoneになるケース(再計算未保存)

data_only=Trueでも、Excelで再計算し保存していなければNoneや古い値の可能性があります。計算値が必要なら「Excel側で再計算→保存」か、Pythonで再計算ロジックを持つ必要があります。


例題で身につける(定番から一歩先まで)

例題1:テーブル範囲の行を読み、合計を計算

from openpyxl import load_workbook

ws = load_workbook("sales.xlsx", data_only=True)["Data"]
total = 0.0
for row in ws.iter_rows(min_row=2, max_col=3, values_only=True):  # A:日付 B:商品 C:金額
    amount = row[2]
    if isinstance(amount, (int, float)):
        total += amount
print("total:", total)
Python

例題2:ヘッダー辞書化して安全に参照

from openpyxl import load_workbook

ws = load_workbook("users.xlsx").active
header = [c.value for c in ws[1]]
for r in ws.iter_rows(min_row=2, values_only=True):
    row = dict(zip(header, r))
    name = (row.get("name") or "").strip()
    age = row.get("age")
    if name and isinstance(age, int) and age >= 20:
        print(name, age)
Python

例題3:read_onlyで巨大シートをストリーム処理

from openpyxl import load_workbook

wb = load_workbook("huge.xlsx", read_only=True, data_only=True)
ws = wb.active
count = 0
for row in ws.iter_rows(values_only=True):
    # その場で処理(DB投入・書き出しなど)
    count += 1
print("rows:", count)
Python

例題4:結合セルの先頭値だけを拾う

from openpyxl import load_workbook

ws = load_workbook("merged.xlsx").active
for rng in ws.merged_cells.ranges:
    top_left = ws[rng.coord.split(":")[0]].value  # 先頭セルの座標を取り出す
    print("merged head:", top_left)
Python

まとめ

openpyxlでExcelを読む要点は「load_workbook→シート選択→セル・範囲の反復」の流れと、values_only/data_only/read_onlyの適切な使い分けです。数式は式か結果かを決め、日付はdatetimeとして扱い、欠損はNoneでガードする。結合セルは先頭だけ値があること、.xlsxが対象であることも覚えておく。ヘッダー行を辞書化して列名でアクセスすれば堅牢性が上がり、Pathlibでファイル操作を安全に統合できる。大規模ファイルはread_onlyで“作らず流す”。この勘所を押さえれば、初心者でも短く、読みやすく、壊れないExcel読み取りが書けます。

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