MENU

PythonでExcel作業を自動化する方法【openpyxl実践ガイド】

「毎日同じExcel作業を繰り返していて、もう限界…」そんな声を、IT担当者やビジネスパーソンの方からよく耳にします。コピペ・集計・フォーマット整形——これらの作業、実はPythonを使えば劇的に効率化できるんです。今回は、ExcelをPythonで操作するためのライブラリ「openpyxl(オープンパイエックスエル)」を使った自動化の方法を、実務で使えるサンプルコード付きで丁寧に解説します。Pythonが初めての方でも大丈夫。ハナと一緒にステップを踏んでいきましょう!


目次

フェーズ1:なぜExcel手作業は限界なのか?課題の整理

繰り返し作業がもたらす時間コストと人的ミスのリスク

まず、現状の課題を正直に見つめてみましょう。毎月末の売上集計、毎週のレポート作成、複数部署から届くデータのコピペ統合——こうした作業は「慣れればすぐ終わる」と思いがちですが、積み重なると驚くほどの時間を消費しています。

たとえば、1日30分のExcel手作業が週5日続くと、1か月で約10時間。年間に換算すると120時間以上もの時間が「単純作業」に費やされていることになります。さらに深刻なのが人的ミスのリスクです。コピペのずれ、集計式の参照先間違い、フォーマットの崩れ——これらは「うっかりミス」では済まされない業務上の損失につながります。ハナが見てきた現場でも、月次レポートの数値ミスが発覚して再集計に半日かかった、というケースは珍しくありません。

手作業の課題を整理すると、主に以下の3点に集約されます。

  • 時間コスト:定型作業に高スキル人材の時間が奪われる
  • 品質リスク:人間が手を動かす限り、ミスはゼロにならない
  • スケーラビリティの欠如:データ量が増えると処理時間が比例して増大する

VBAとPythonの比較——なぜPythonを選ぶのか?

Excel自動化といえば、VBA(Visual Basic for Applications:ExcelなどのOffice製品に組み込まれたマクロ言語)を思い浮かべる方も多いでしょう。VBAは確かに強力ですが、Pythonと比較すると以下のような違いがあります。

観点 VBA Python(openpyxl)
可読性 やや難解・独自構文 シンプルで読みやすい
外部ライブラリ連携 限定的 pandas・matplotlib等と自由に連携
保守性 Excelファイルに依存・共有困難 独立したスクリプトとして管理可能
実行環境 Excel必須 Excelなし(サーバー上)でも実行可能
学習リソース VBA専用 豊富なコミュニティ・書籍・Web情報

特に注目したいのが「Excelなしで実行できる」という点です。サーバー上でスケジューラと組み合わせれば、誰も操作しなくても毎日自動でレポートが生成される——そんな仕組みが作れます。VBAではなかなか実現できない世界です。


フェーズ2:自動化の設計図を描く――openpyxlでできること

openpyxlの主要機能と業務課題へのマッピング

openpyxlは、PythonでExcelファイル(.xlsx形式)を読み書きするためのライブラリです。主な機能と、それが解決できる業務課題を整理してみましょう。

openpyxlの機能 対応できる業務課題
セルの読み書き データ入力・転記・集計
シート操作(作成・削除・コピー) 月次シートの自動生成・整理
スタイル設定(色・フォント・罫線) レポートの自動フォーマット整形
グラフ生成 売上推移グラフの自動作成
数式の埋め込み 集計式の自動設定
複数ファイルの一括処理 部署別ファイルの統合・集約

自動化対象業務の選定基準と処理フロー設計

「何でも自動化すればいい」というわけではありません。自動化の効果を最大化するには、対象業務を正しく選ぶことが重要です。ハナがおすすめする選定基準は以下の3つです。

  • 頻度が高い:毎日・毎週・毎月など定期的に発生する作業
  • 工数が大きい:1回あたり15分以上かかる作業
  • ミス発生率が高い:手作業でのコピペや計算が多い作業

選定が終わったら、実装前に処理フローを設計しましょう。以下のステップで進めると整理しやすいです。

  1. インプットの定義:どのファイル・シート・セル範囲を読み込むか
  2. 処理ロジックの整理:集計・変換・判定などの処理内容
  3. アウトプットの定義:どのファイル・シートに何を書き出すか
  4. エラーケースの想定:ファイルが存在しない場合・データが空の場合など

この設計ステップを省略すると、「動くけど使いにくいスクリプト」になりがちです。実装前の5分間の設計が、後の保守コストを大きく左右します。


フェーズ3:実装手順――環境構築からサンプルコードまで

環境構築:PythonとopenpyxLのインストール

まずはPython本体をインストールします。Python公式サイトから最新版(3.10以上推奨)をダウンロードしてください。インストール時に「Add Python to PATH」にチェックを入れることを忘れずに。

Pythonがインストールできたら、コマンドプロンプト(Windowsの場合)またはターミナル(Mac/Linuxの場合)を開き、以下のコマンドを実行します。

# openpyxlのインストール
pip install openpyxl

# インストール確認
python -c "import openpyxl; print(openpyxl.__version__)"

バージョン番号(例:3.1.2)が表示されれば、インストール成功です!次に、動作確認として簡単なExcelファイルを作成してみましょう。

import openpyxl

# 新しいワークブックを作成
wb = openpyxl.Workbook()
ws = wb.active
ws.title = "テスト"

# セルにデータを書き込む
ws["A1"] = "Hello"
ws["B1"] = "openpyxl"
ws["A2"] = 2024

# ファイルを保存
wb.save("test.xlsx")
print("test.xlsx を作成しました!")

このスクリプトを実行して「test.xlsx」が生成されれば、環境構築は完了です。それでは、実務直結の3つのサンプルコードを見ていきましょう。

ステップ1:既存Excelファイルの読み込みと集計・別シート書き出し

既存のExcelファイルを開き、特定列(ここでは「売上」列)のデータを集計して、同一ファイルの新しいシートに結果を書き出すスクリプトです。openpyxlload_workbookでファイルを読み込み、行をループして集計処理を行います。

import openpyxl
from collections import defaultdict

SOURCE_FILE = "sales_data.xlsx"
SOURCE_SHEET = "Sheet1"
OUTPUT_SHEET = "集計結果"

wb = openpyxl.load_workbook(SOURCE_FILE)
ws = wb[SOURCE_SHEET]

# ヘッダー行を取得(1行目)
headers = [cell.value for cell in ws[1]]
category_col = headers.index("カテゴリ")  # 0始まり
sales_col = headers.index("売上")

# カテゴリ別に売上を集計
aggregated = defaultdict(float)
for row in ws.iter_rows(min_row=2, values_only=True):
    category = row[category_col]
    sales = row[sales_col]
    if category and sales:
        aggregated[category] += float(sales)

# 集計結果シートを作成(既存なら削除して再作成)
if OUTPUT_SHEET in wb.sheetnames:
    del wb[OUTPUT_SHEET]
ws_out = wb.create_sheet(OUTPUT_SHEET)

# ヘッダー書き込み
ws_out.append(["カテゴリ", "売上合計"])

# 集計データ書き込み
for category, total in sorted(aggregated.items()):
    ws_out.append([category, total])

# 合計行
ws_out.append(["総合計", sum(aggregated.values())])

wb.save(SOURCE_FILE)
print(f"集計完了:{OUTPUT_SHEET} シートに書き出しました")

このスクリプトのポイントは、iter_rows(values_only=True)を使うことでセルオブジェクトではなく値だけを取得し、処理を高速化している点です。また、集計結果シートが既存の場合は削除して再作成するため、何度実行しても同じ結果が得られます(冪等性:べきとうせい)。

ステップ2:複数Excelファイルのループ処理とテンプレートへの一括転記

指定フォルダ内の複数Excelファイルを自動的に読み込み、定型テンプレートに転記して別フォルダに保存するスクリプトです。globでファイルを一括取得し、copy_workbookの代わりにテンプレートをコピーして使い回します。

import openpyxl
import shutil
from pathlib import Path

INPUT_DIR = Path("./input")
OUTPUT_DIR = Path("./output")
TEMPLATE_FILE = "template.xlsx"

OUTPUT_DIR.mkdir(exist_ok=True)

# 転記マッピング:{転記先セル: 転記元(シート名, 行, 列)}
CELL_MAP = {
    "B2": ("データ", 2, 1),   # 会社名
    "B3": ("データ", 2, 2),   # 担当者
    "B4": ("データ", 2, 3),   # 金額
    "B5": ("データ", 2, 4),   # 日付
}

for src_path in INPUT_DIR.glob("*.xlsx"):
    # テンプレートをコピーして出力先を作成
    out_path = OUTPUT_DIR / f"report_{src_path.name}"
    shutil.copy2(TEMPLATE_FILE, out_path)

    # 転記元データを読み込む
    wb_src = openpyxl.load_workbook(src_path)

    # テンプレートコピーを開く
    wb_out = openpyxl.load_workbook(out_path)
    ws_out = wb_out.active

    # セルマッピングに従って転記
    for dest_cell, (sheet_name, row, col) in CELL_MAP.items():
        if sheet_name in wb_src.sheetnames:
            value = wb_src[sheet_name].cell(row=row, column=col).value
            ws_out[dest_cell] = value

    # ファイル名をB1セルに記録
    ws_out["B1"] = src_path.stem

    wb_out.save(out_path)
    wb_src.close()
    print(f"転記完了:{out_path.name}")

print(f"\n全{len(list(OUTPUT_DIR.glob('*.xlsx')))}件の処理が完了しました")

CELL_MAPという辞書(ディクショナリ)で転記ルールを一元管理しているのが、このスクリプトの工夫ポイントです。転記先・転記元の対応関係をコードの冒頭で宣言しているため、業務ルールが変わったときも1か所を修正するだけで対応できます。

ステップ3:条件に応じたセルスタイル(背景色・フォント・罫線)の自動適用

数値の大小や文字列の内容に応じて、セルの背景色・フォントスタイル・罫線を自動で設定するサンプルです。PatternFillFontBorderSideを組み合わせて実用的なスタイリングを行います。

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

FILE = "styled_report.xlsx"

# 新規作成
wb = openpyxl.Workbook()
ws = wb.active
ws.title = "スタイル適用レポート"

# サンプルデータ
data = [
    ["商品名", "売上", "ステータス"],
    ["商品A", 150000, "達成"],
    ["商品B", 80000, "未達"],
    ["商品C", 200000, "達成"],
    ["商品D", 45000, "未達"],
]

# スタイル定義
header_fill = PatternFill(start_color="4472C4", end_color="4472C4", fill_type="solid")
header_font = Font(color="FFFFFF", bold=True, size=11)
achieved_fill = PatternFill(start_color="C6EFCE", end_color="C6EFCE", fill_type="solid")
failed_fill = PatternFill(start_color="FFC7CE", end_color="FFC7CE", fill_type="solid")
achieved_font = Font(color="276221", bold=False)
failed_font = Font(color="9C0006", bold=False)

thin_side = Side(style="thin", color="BFBFBF")
thin_border = Border(left=thin_side, right=thin_side, top=thin_side, bottom=thin_side)

# データ書き込みとスタイル適用
for row_idx, row_data in enumerate(data, start=1):
    for col_idx, value in enumerate(row_data, start=1):
        cell = ws.cell(row=row_idx, column=col_idx, value=value)
        cell.border = thin_border
        cell.alignment = Alignment(horizontal="center", vertical="center")

        if row_idx == 1:
            # ヘッダー行
            cell.fill = header_fill
            cell.font = header_font
        else:
            # データ行:ステータスに応じて色分け
            status = row_data[2]
            if status == "達成":
                cell.fill = achieved_fill
                cell.font = achieved_font
            else:
                cell.fill = failed_fill
                cell.font = failed_font

# 列幅の自動調整
ws.column_dimensions["A"].width = 15
ws.column_dimensions["B"].width = 12
ws.column_dimensions["C"].width = 10

# 行の高さ設定
ws.row_dimensions[1].height = 20

wb.save(FILE)
print(f"スタイル適用完了:{FILE}")

このサンプルでは「達成」「未達」のステータスに応じてセルの色を自動で塗り分けています。手作業で条件付き書式を設定する手間が一切不要になり、毎回同じ品質のレポートが出力されます。


フェーズ4:動作確認・トラブル対処と応用展開

よくあるエラーと対処法

openpyxlを使い始めると、いくつかのエラーに遭遇することがあります。代表的なものと対処法をまとめました。

① ファイルロックエラー(PermissionError)

症状PermissionError: [Errno 13] Permission denied: 'file.xlsx'

原因:Excelで対象ファイルを開いたまま、Pythonスクリプトを実行しようとしている

対処法:Excelでファイルを閉じてからスクリプトを実行する。または、スクリプト内で読み込み専用モード(read_only=True)を使用する

# 読み込み専用で開く(書き込みは不可)
wb = openpyxl.load_workbook("file.xlsx", read_only=True)

② 文字コードエラー

症状:日本語のファイル名やシート名で文字化けが発生する

原因:Pythonスクリプトファイルの文字コードがUTF-8以外になっている

対処法:スクリプトの先頭に文字コード宣言を追加する

# -*- coding: utf-8 -*-

③ セル型不一致エラー(TypeError)

症状:数値として扱いたいセルが文字列型になっており、計算でエラーが出る

原因:Excelで文字列として入力された数値(例:「’1000」)を、そのままfloat()に渡している

対処法:型チェックと変換処理を追加する

def safe_float(value):
    """セル値を安全にfloatに変換する"""
    if value is None:
        return 0.0
    try:
        return float(str(value).replace(",", "").strip())
    except (ValueError, TypeError):
        return 0.0

動作確認チェックリスト

スクリプトを本番運用に移す前に、以下のチェックリストで確認しましょう。

  • ☐ テスト用ファイル(本番データのコピー)で動作確認済み
  • ☐ ファイルが存在しない場合のエラーハンドリングが実装されている
  • ☐ データが空(0件)の場合でも正常終了する
  • ☐ 出力ファイルが正しいシート・セルに書き込まれている
  • ☐ 日本語のシート名・セル値が正しく処理されている
  • ☐ スクリプト実行後、元ファイルが破損していない
  • ☐ 複数回実行しても同じ結果が得られる(冪等性の確認)

応用展開①:スケジューラとの組み合わせで完全自動実行

スクリプトが完成したら、次のステップは「人が実行しなくても動く」仕組みを作ることです。

Windowsタスクスケジューラの設定手順(概要)

  1. 「タスクスケジューラ」を起動(スタートメニューで検索)
  2. 「基本タスクの作成」をクリック
  3. 実行タイミングを設定(例:毎日9:00)
  4. 「プログラムの開始」でPythonのパスとスクリプトパスを指定
# タスクスケジューラに設定するコマンドの例
# プログラム:C:\Python311\python.exe
# 引数:C:\scripts\excel_automation.py
# 開始場所:C:\scripts

Linux/MacのCron(クーロン:Unix系OSの定期実行スケジューラ)設定例

# crontabを編集
crontab -e

# 毎日午前9時に実行する例
0 9 * * * /usr/bin/python3 /home/user/scripts/excel_automation.py >> /home/user/logs/automation.log 2>&1

応用展開②:pandasとの併用で大量データを高速処理

pandas(パンダス:Pythonのデータ分析ライブラリ)と組み合わせると、数万行・数十万行のデータも高速に処理できます。openpyxlはセル単位の操作が得意ですが、大量データの集計・フィルタリングはpandasが圧倒的に速いです。

import pandas as pd
import openpyxl
from openpyxl.styles import PatternFill, Font

# pandasで大量データを高速集計
df = pd.read_excel("large_data.xlsx", sheet_name="Sheet1")

# 集計処理(pandasの強み)
summary = df.groupby("カテゴリ")["売上"].agg(["sum", "mean", "count"]).reset_index()
summary.columns = ["カテゴリ", "売上合計", "平均売上", "件数"]

# pandasで集計結果をExcelに書き出し
summary.to_excel("summary_output.xlsx", index=False, sheet_name="集計結果")

# openpyxlでスタイルを後付け
wb = openpyxl.load_workbook("summary_output.xlsx")
ws = wb["集計結果"]

header_fill = PatternFill(start_color="4472C4", end_color="4472C4", fill_type="solid")
header_font = Font(color="FFFFFF", bold=True)

for cell in ws[1]:
    cell.fill = header_fill
    cell.font = header_font

wb.save("summary_styled.xlsx")
print("集計+スタイル適用完了!")

「pandasで集計 → openpyxlでスタイル適用」という役割分担が、実務では非常に効果的です。それぞれのライブラリの得意分野を活かした組み合わせをぜひ試してみてください。


ハナの所見

今回openpyxlを使ったExcel自動化を一通り解説してきましたが、ハナが最も伝えたいことは「完璧なスクリプトを最初から作ろうとしなくていい」ということです。

自動化のスタートは、「一番時間がかかっている作業を1つ選んで、まずそれだけ自動化する」で十分です。フェーズ3で紹介した3つのサンプルコードは、そのままコピペして動かせるように設計しています。まずは自分のデータに合わせてファイル名やシート名を書き換えるところから始めてみてください。

実際の現場でopenpyxlを導入した企業では、月次レポート作成が「3時間→15分」に短縮されたケースや、集計ミスがゼロになったという声もよく聞きます。最初の一歩は小さくていい。でも、その一歩が積み重なると、働き方そのものが変わっていきます。

VBAからPythonへの移行を迷っている方へ。両方を使い分けるのも全然ありです。ただ、Pythonを覚えておくと、Excel以外の業務(メール送信・Web API連携・データベース操作など)にも応用が効くので、長期的なスキル投資として非常にコスパが高いと感じています。

ハナはこれからも、ビジネスの現場で使えるIT活用情報を発信し続けます。「試してみたけどうまくいかない」「もっと複雑なことをやりたい」という方は、ぜひコメントや問い合わせで教えてください。一緒に解決策を考えましょう!


まとめ

今回の記事では、Pythonのopenpyxlライブラリを使ったExcel自動化について、課題の整理から実装・応用展開まで幅広く解説しました。手作業によるExcel業務の非効率さを見直し、Pythonによる自動化を取り入れることで、業務の質とスピードを同時に高めることができます。まずは小さな一歩から始めて、自動化の効果を実感してみてください。

  • openpyxlで解決できる課題:セルの読み書き・シート操作・スタイル設定・グラフ生成など、日常的なExcel手作業のほぼすべてをPythonで自動化できます
  • 実装開始の具体的なステップpip install openpyxlでインストール後、本記事のサンプルコードをベースにファイル名・シート名を自分の環境に合わせて書き換えるだけで、すぐに動かせます
  • VBAとの使い分け:既存のVBAマクロはそのまま活用しつつ、新規開発や他システムとの連携が必要な処理はPythonで実装するハイブリッド運用が現実的です
  • pandasとの組み合わせ:大量データの集計・フィルタリングはpandasに任せ、仕上げのスタイル適用はopenpyxlで行う役割分担により、処理速度と出力品質を両立できます
  • 自動化による効果:定型作業の工数削減・人的ミスのゼロ化・スケジューラとの連携による完全無人実行が実現し、担当者はより付加価値の高い業務に集中できるようになります

この記事はハナ編集部が執筆しました。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

はじめまして、「白米元気」と申します。

ノースキルで副業をスタートし、2ヶ月で月10万円を達成。
その後も毎日ChatGPTとにらめっこしながら、
「どうやったら仕組みで稼げるのか?」を考え続けてきました。

そんな中出会ったのが「LLM無職」です。
AIと仕組みを作り、AIに仕事をさせる。
副業や働き方そのものを実験していく——そんな挑戦をしています。

このブログでは、わたしのLLM無職への道のりの途中で
AIを活用した具体的な方法や工夫、日々の実践内容を紹介。
ときどき家族の話もまじえながら、
読んでくれた方が「なんかおもしろそう!」と思えるような、
リアルで実験的な情報をお届けしていきます。

コメント

コメント一覧 (1件)

コメントする

目次