PythonでExcelを読み書きする(openpyxl入門)

PythonでExcelファイルを操作するには「openpyxl」というライブラリを使います。VBAなしでExcelを読み込み・編集・保存する基本的な操作を、実際に動くコードで解説します。

openpyxlとは

openpyxlはPythonからExcel(.xlsx)ファイルを操作するためのライブラリです。Excelがインストールされていないサーバー上でも動作するため、スケジュール実行との相性がいいです。

インストールはコマンドプロンプトで以下を実行します。

pip install openpyxl

openpyxlでできること

  • セルの読み書き・書式設定
  • シートの追加・削除・コピー
  • 新規Excelファイルの作成
  • 既存ファイルの読み込みと編集

openpyxlでできないこと

  • VBAマクロの実行
  • グラフの細かい編集(基本的なグラフ作成は可能)
  • .xls(旧形式)の読み書き(xlrdライブラリが別途必要)

基本:Excelファイルを開いてセルを読む

import openpyxl

# Excelファイルを開く
wb = openpyxl.load_workbook("data.xlsx")

# シートを選ぶ(シート名で指定)
ws = wb["Sheet1"]

# セルの値を読む
print(ws["A1"].value)           # A1セルの値
print(ws.cell(row=2, column=3).value)  # 2行3列(C2)の値

# 全シート名を確認する
print(wb.sheetnames)

wb.close()

セルに値を書き込んで保存する

import openpyxl

# 既存ファイルを開く
wb = openpyxl.load_workbook("report.xlsx")
ws = wb["集計"]

# セルに値を書き込む
ws["A1"].value = "月次レポート"
ws["B1"].value = "2025年1月"
ws.cell(row=2, column=1).value = 12500  # 数値

# 書式を設定する
from openpyxl.styles import Font, PatternFill, Alignment

ws["A1"].font = Font(bold=True, size=14)
ws["A1"].fill = PatternFill(fill_type="solid", fgColor="DDDDDD")
ws["B1"].alignment = Alignment(horizontal="center")

# 同じファイルに上書き保存
wb.save("report.xlsx")

# 別名で保存する場合
wb.save("report_updated.xlsx")

wb.close()

新規Excelファイルを作成する

import openpyxl

# 新しいワークブックを作成(Sheet1が自動で作られる)
wb = openpyxl.Workbook()
ws = wb.active
ws.title = "売上データ"

# ヘッダー行を書き込む
headers = ["日付", "商品名", "数量", "単価", "合計"]
for col, header in enumerate(headers, start=1):
    ws.cell(row=1, column=col).value = header

# データ行を書き込む
data = [
    ["2025-01-06", "商品A", 3, 1200, 3600],
    ["2025-01-07", "商品B", 1, 5000, 5000],
    ["2025-01-08", "商品A", 2, 1200, 2400],
]
for row_idx, row_data in enumerate(data, start=2):
    for col_idx, value in enumerate(row_data, start=1):
        ws.cell(row=row_idx, column=col_idx).value = value

wb.save("売上データ.xlsx")
wb.close()
print("ファイルを作成しました。")

全行を繰り返して処理する

import openpyxl

wb = openpyxl.load_workbook("売上データ.xlsx")
ws = wb["売上データ"]

total = 0

# 2行目から最終行まで繰り返す
for row in ws.iter_rows(min_row=2, values_only=True):
    # row は (日付, 商品名, 数量, 単価, 合計) のタプル
    if row[0] is None:  # 空行に達したら終了
        break
    print(f"{row[0]} - {row[1]}: {row[4]}円")
    total += row[4]

print(f"合計: {total}円")
wb.close()

values_only=True をつけると、セルオブジェクトではなく値だけが返されます。読み込み専用の処理に便利です。

openpyxlとpandasの使い分け

Excelを読み書きするライブラリとしては pandas もよく使われます。用途によって使い分けます。

用途 向いているライブラリ
データの集計・分析・フィルタリング pandas
書式・セル結合・複数シートの細かい制御 openpyxl
大量データの高速処理 pandas
既存Excelの書式を保ちながら編集 openpyxl
CSVとExcelを行き来する処理 pandas

pandasでExcelを読む場合は pandas.read_excel() を使いますが、内部でopenpyxlを使っているため、両方インストールされている必要があります。

import pandas as pd

# pandasでExcelを読む(シンプルな集計に便利)
df = pd.read_excel("売上データ.xlsx", sheet_name="売上データ")
print(df.groupby("商品名")["合計"].sum())

# pandasでExcelに書き出す
df.to_excel("集計結果.xlsx", index=False)

実務でよく使うパターン

列の最終行を取得する

openpyxlにはVBAの End(xlUp) に相当する直接的な機能がないため、以下のようにして最終行を取得します。

# A列のデータが入っている最終行を取得
max_row = ws.max_row  # シートの最終行(空行も含む)

# 実際にデータが入っている最終行を確認する
last_data_row = 0
for row in range(1, ws.max_row + 1):
    if ws.cell(row=row, column=1).value is not None:
        last_data_row = row

列幅を自動調整する

from openpyxl.utils import get_column_letter

for col in ws.columns:
    max_length = 0
    col_letter = get_column_letter(col[0].column)
    for cell in col:
        if cell.value:
            max_length = max(max_length, len(str(cell.value)))
    ws.column_dimensions[col_letter].width = max_length + 2

まとめ

openpyxlを使えば、PythonからExcelファイルの読み書き・書式設定・新規作成ができます。VBAと違い、Excelが起動していない環境でも動作するため、サーバーでのスケジュール実行との組み合わせで特に力を発揮します。集計・フィルタリングなどのデータ処理が中心であれば pandasのほうが簡単に書けるので、処理の内容によって使い分けてください。