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エンジニアには、ぜひ試してほしいアプローチです。