PythonでExcel業務を自動化したら月20時間削減できた話

Excelの手作業から解放されたきっかけ

前職で、毎月末に各部門から送られてくる数十枚のExcelレポートを1つに集計して経営陣に提出する業務がありました。データのコピペ、書式の統一、グラフの更新——これだけで月に20時間以上かかっていました。

「これは絶対に自動化できる」と思い、Pythonのopenpyxlで取り組んだのが本記事の内容です。結果として集計作業は15分に短縮され、ミスもほぼゼロになりました。

openpyxlとは

openpyxlはPythonからExcel(.xlsx形式)ファイルを読み書きできるライブラリです。セルへの値の書き込み、書式設定、グラフ生成まで幅広く対応しています。

pip install openpyxl

基本操作:ファイルの読み書き

既存ファイルを読み込む

from openpyxl import load_workbook

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

# セルの値を取得
value = ws["B2"].value
print(value)

# 行ごとに処理
for row in ws.iter_rows(min_row=2, values_only=True):
    print(row)

新規ファイルを作成する

from openpyxl import Workbook

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

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

# データを書き込む
data = [
    ("2026-01-01", "商品A", 50000),
    ("2026-01-02", "商品B", 30000),
]
for row_idx, (date, name, sales) in enumerate(data, start=2):
    ws.cell(row=row_idx, column=1, value=date)
    ws.cell(row=row_idx, column=2, value=name)
    ws.cell(row=row_idx, column=3, value=sales)

wb.save("output.xlsx")

実践:複数ファイルの集計

前職で実装したのは「各部門のExcelファイルを一括で読み込み、集計シートを生成する」スクリプトです。

from pathlib import Path
from openpyxl import Workbook, load_workbook
from openpyxl.styles import Font, PatternFill, Alignment
from openpyxl.utils import get_column_letter


def collect_reports(report_dir: str, output_path: str) -> None:
    """指定ディレクトリのExcelレポートを集計する"""
    report_files = list(Path(report_dir).glob("*.xlsx"))

    wb_out = Workbook()
    ws_summary = wb_out.active
    ws_summary.title = "集計"

    # ヘッダー設定
    headers = ["部門", "売上合計", "件数", "平均単価"]
    for col, header in enumerate(headers, start=1):
        cell = ws_summary.cell(row=1, column=col, value=header)
        cell.font = Font(bold=True, color="FFFFFF")
        cell.fill = PatternFill(fill_type="solid", fgColor="2F5496")
        cell.alignment = Alignment(horizontal="center")

    # 各レポートを読み込んで集計
    for row_idx, filepath in enumerate(sorted(report_files), start=2):
        wb_in = load_workbook(filepath, read_only=True)
        ws_in = wb_in.active

        dept_name = filepath.stem
        total_sales = 0
        count = 0

        for row in ws_in.iter_rows(min_row=2, values_only=True):
            if row[2]:  # 売上列がある場合
                total_sales += row[2]
                count += 1

        avg_price = total_sales // count if count > 0 else 0

        ws_summary.cell(row=row_idx, column=1, value=dept_name)
        ws_summary.cell(row=row_idx, column=2, value=total_sales)
        ws_summary.cell(row=row_idx, column=3, value=count)
        ws_summary.cell(row=row_idx, column=4, value=avg_price)

        wb_in.close()

    # 列幅を自動調整
    for col in range(1, len(headers) + 1):
        ws_summary.column_dimensions[get_column_letter(col)].width = 18

    wb_out.save(output_path)
    print(f"集計完了: {output_path}")


if __name__ == "__main__":
    collect_reports("./reports", "./集計レポート.xlsx")

書式設定のポイント

見やすいレポートを作るためによく使う書式設定です。

from openpyxl.styles import Font, PatternFill, Border, Side, numbers

# 数値フォーマット(カンマ区切り)
ws["C2"].number_format = "#,##0"

# 日付フォーマット
ws["A2"].number_format = "YYYY/MM/DD"

# 罫線
thin = Side(style="thin")
ws["B2"].border = Border(left=thin, right=thin, top=thin, bottom=thin)

実行結果と効果

| 項目 | 自動化前 | 自動化後 |

|——|———-|———-|

| 集計にかかる時間 | 月20時間 | 月15分 |

| 手作業ミスの件数 | 月2〜3件 | ほぼゼロ |

| 提出までのリードタイム | 3営業日 | 当日 |

導入した当初は「Pythonが動かない」「ファイルが開けない」など現場からの質問もありましたが、バッチファイルにラップして「ダブルクリックするだけ」にしたことでスムーズに定着しました。

まとめ

openpyxlを使ったExcel自動化の要点は以下の通りです。

  • `load_workbook`で既存ファイルを読み込み、`Workbook`で新規作成
  • `iter_rows(values_only=True)`でデータを高速に読み込む
  • `Font`・`PatternFill`・`Border`で書式を設定する
  • 複数ファイルの処理は`pathlib.Path.glob`と組み合わせると効率的
  • 月20時間の繰り返し作業を自動化したことで、より本質的な業務に集中できるようになりました。ExcelをよくさわるPythonエンジニアには、ぜひ試してほしいアプローチです。