概要(「決まった Excel レポート」を毎回ボタン一発にする)
Excel レポート自動作成は、
「毎月・毎週・毎日、ほぼ同じレイアウトの Excel を作る仕事」を
Python に肩代わりさせることです。
やることの流れは、だいたい次のようなイメージになります。
データ(CSV・DB・別の Excel)を読み込む。
pandas で集計や加工を行う。
テンプレートの Excel に書き込む、もしくは新規に書き出す。
必要なら書式(数値フォーマット・色・罫線・グラフ)も自動で設定する。
ここでは、初心者でも手を動かしやすいように、
「シンプルな日次売上レポート」を例にしながら、テンプレ型と新規作成型の両方をかみ砕いて説明します。
基本準備(フォルダ構成とライブラリ選定)
最低限そろえておきたいライブラリ
Excel レポート自動作成では、主役は pandas です。
書き出しのエンジンとして openpyxl や xlsxwriter を使います。
ターミナルやコマンドプロンプトで次のように入れておきます。
pip install pandas openpyxl xlsxwriter
pandas から to_excel を呼ぶとき、engine を指定すると xlsxwriter の書式機能を使いやすくなります。
フォルダ構成の例と Path の使い方
自動化を前提にするなら、フォルダ構成を先に決めておくと安定します。
たとえば次のような構成を想定します。
project_root
┗ data/ (元データの CSV など)
┗ output/ (作成されたレポート Excel)
┗ template/ (Excel テンプレート)
┗ scripts/ (Python スクリプト)
Python では、スクリプトの場所を基準に絶対パスを組み立てる癖をつけると、
どこから実行しても壊れなくなります。
from pathlib import Path
BASE_DIR = Path(__file__).resolve().parent.parent # scripts の一つ上を基準にする
DATA_DIR = BASE_DIR / "data"
OUT_DIR = BASE_DIR / "output"
TEMPLATE_DIR = BASE_DIR / "template"
OUT_DIR.mkdir(exist_ok=True)
Pythonこの「BASE_DIR を起点に Path で組み立てる」パターンは、Excel 自動化を含むバッチ系で非常に重要です。
例題データの準備と集計(pandas でレポートの中身を作る)
想定する元データ(売上明細の CSV)
次のような CSV が毎日増えていく場面を想定します。
列は、日付、店舗名、カテゴリ、売上金額。
ファイル名は、sales_2025-01-01.csv のように日付入り。
まずはこの CSV を読み込んで、「店舗別・カテゴリ別の集計表」を作ります。
import pandas as pd
from pathlib import Path
BASE_DIR = Path(__file__).resolve().parent.parent
DATA_DIR = BASE_DIR / "data"
csv_path = DATA_DIR / "sales_2025-01-01.csv"
df = pd.read_csv(csv_path, encoding="utf-8")
df["date"] = pd.to_datetime(df["date"], errors="coerce")
df["amount"] = pd.to_numeric(df["amount"], errors="coerce")
Pythonここで date と amount をきちんと型変換するのが重要です。
数値や日付が文字列のままだと、集計やソートがうまく動きません。
店舗別・カテゴリ別の売上集計
レポートの中に、「店舗×カテゴリの売上一覧」を Excel で出したいとします。
pandas の groupby と pivot_table を使うと一発で作れます。
summary = (
df.groupby(["store", "category"], as_index=False)["amount"]
.sum()
.rename(columns={"amount": "total_amount"})
)
pivot = summary.pivot_table(
index="store",
columns="category",
values="total_amount",
aggfunc="sum",
fill_value=0
)
print(pivot)
Pythonこの pivot が、そのまま Excel の「ピボットテーブルっぽい表」として使える形になります。
パターン1:新規に Excel レポートを作る(pandas + xlsxwriter)
to_excel でシンプルなレポートファイルを出力する
まずはテンプレートを使わずに、新しく Excel ファイルを作ってみます。
from datetime import datetime
OUT_DIR = BASE_DIR / "output"
OUT_DIR.mkdir(exist_ok=True)
report_date = df["date"].dt.date.max()
out_path = OUT_DIR / f"sales_report_{report_date}.xlsx"
with pd.ExcelWriter(out_path, engine="xlsxwriter") as writer:
df.to_excel(writer, sheet_name="明細", index=False)
pivot.to_excel(writer, sheet_name="集計")
Pythonこの段階で、「明細」シートと「集計」シートを持つ Excel ができあがります。
見た目は素っ気ないですが、ここまで来れば「機械で計算した正しい数字のレポート」が、毎回同じ手順で出せるようになります。
xlsxwriter で書式・見た目を整える
もう少し Excel らしく整えてみます。
xlsxwriter のフォーマットオブジェクトを使うと、
ヘッダーを太字にしたり、金額をカンマ付き表示にしたりできます。
with pd.ExcelWriter(out_path, engine="xlsxwriter") as writer:
df.to_excel(writer, sheet_name="明細", index=False)
pivot.to_excel(writer, sheet_name="集計")
workbook = writer.book
sheet_sum = writer.sheets["集計"]
header_format = workbook.add_format({
"bold": True,
"bg_color": "#D9E1F2",
"border": 1,
"align": "center"
})
money_format = workbook.add_format({
"num_format": "#,##0",
"border": 1
})
for col_num, value in enumerate(pivot.reset_index().columns.values):
sheet_sum.write(0, col_num, value, header_format)
nrows, ncols = pivot.reset_index().shape
for row in range(1, nrows + 1):
for col in range(1, ncols): # 0列目は店舗名なので金額ではない
sheet_sum.write(row, col, pivot.values[row - 1, col - 1], money_format)
sheet_sum.set_column(0, 0, 15)
sheet_sum.set_column(1, ncols, 12)
Python大事なポイントは、pandas で書き込んだあとに、writer.book と writer.sheets を使って
セルのフォーマットを上書きしているところです。
最初は「素の to_excel で出力してから」「必要なところだけ整える」という流れで十分です。
慣れてきたら、「列幅を自動で調整する」「条件付き書式を使う」「グラフを追加する」などを足していけます。
パターン2:既存の Excel テンプレートにデータだけ流し込む
テンプレートを使うメリットのイメージ
現場では、すでに「見た目を作り込んだ Excel」が使われていることが多いです。
罫線、色、ロゴ、説明文、計算式などがすべて入っているファイルです。
こういう場合は、テンプレートの見た目はそのままに、
「特定のセル範囲にだけ毎回データを流し込む」形にすると、現場に馴染みやすくなります。
たとえば、template/sales_report_template.xlsx の「集計」シートで、
B4 セルから店舗×カテゴリの表が始まる、と決めておきます。
openpyxl でテンプレに書き込む例
openpyxl を使うと、「既に存在する Excel を開いて、中身を書き換える」ことができます。
from openpyxl import load_workbook
template_path = TEMPLATE_DIR / "sales_report_template.xlsx"
out_path = OUT_DIR / f"sales_report_{report_date}.xlsx"
wb = load_workbook(template_path)
ws = wb["集計"]
pivot_reset = pivot.reset_index()
start_row = 4
start_col = 2 # B列
for j, col_name in enumerate(pivot_reset.columns, start=start_col):
ws.cell(row=start_row, column=j, value=str(col_name))
for i, (_, row) in enumerate(pivot_reset.iterrows(), start=start_row + 1):
for j, val in enumerate(row, start=start_col):
ws.cell(row=i, column=j, value=val)
wb.save(out_path)
Pythonここで大事なのは、次の3つです。
テンプレ側で「どのシートの」「どのセルから」「どのような表構造で書き込むか」を、最初に仕様として固定しておくこと。
pivot を reset_index して、「1行が1レコード、列名がヘッダー」というシンプルな DataFrame にしてから書くこと。
セルの見た目(罫線・色・フォント)をテンプレ側に持たせておくこと。書き込む側はあくまで値だけ入れる。
このスタイルにしておくと、「レイアウトを変えたい」という要望が来ても、
テンプレ Excel を直すだけで対応できるようになります(コードの変更は最小限で済む)。
つまずきポイントの深掘り(テンプレ変更・日本語・数値と文字・日付)
テンプレが変わったときに壊れないようにする工夫
現実世界では、「テンプレの列位置が変わった」「シート名が変わった」などが起きます。
完全に防ぐのは難しいですが、次のような工夫でダメージを減らせます。
書き込み位置を「セル番地」ではなく「見出し名」から探すようにする。
たとえば、ヘッダーの行を scan して、「店舗」「カテゴリ」「売上」が何列目かをコード側で判断する。
header_row = 4
col_map = {}
for col in range(1, 20):
val = ws.cell(row=header_row, column=col).value
if val in ("店舗", "カテゴリ", "売上"):
col_map[val] = col
Pythonこれで、「見出し名さえ変わらなければ位置がずれても追従できる」といった設計ができます。
数値が文字列になってしまう問題
openpyxl 経由で書き込むとき、数値に見えても実は文字列として入っているケースがあります。
Excel 上で右寄せと左寄せで見分けがつくあれです。
pandas から to_excel する場合は型を気にする必要はほとんどありませんが、
openpyxl で自前で書く場合は「数値は数値、日付は datetime」として渡すようにします。
from datetime import date
ws["B2"] = 12345 # 数値
ws["C2"] = date(2025, 1, 1) # 日付オブジェクト
Python文字列として入れると、Excel 関数やグラフでうまく扱えないことがあります。
日本語フォントや全角文字の扱い
日本語の文字列自体は特に特別扱いせずにそのまま書けますが、
フォントやサイズを制御したい場合は、テンプレ側にスタイルを持たせておく方が楽です。
Python でスタイルを全部組むこともできますが、
初心者のうちは「見た目は Excel 側で、値は Python 側で」と役割をはっきり分けた方が精神的に楽です。
自動化への接続(バッチ化して毎日レポートを吐く)
1本の「レポートバッチ」にまとめるイメージ
ここまでの流れを、1本のスクリプトにまとめておくと、
毎日「python make_report.py」と叩くだけでレポートを吐けるようになります。
ざっくりとした構造は次のようになります。
対象日を決める(例:昨日の日付)。
対象日の CSV を読み込み、pandas で集計。
pivot などレポート用の DataFrame を作る。
新規 Excel へ書き出す、またはテンプレへ書き込んで保存。
ログに成功・失敗・件数・ファイル名などを書き残す。
cron やタスクスケジューラと組み合わせれば、
毎朝決まった時間にレポートが勝手に生成される状態まで持っていけます。
まとめ(「pandasで中身を作り、Excelは入れ物として使う」発想を持つ)
Excel レポート自動作成の肝は、次のような考え方です。
計算や集計は pandas にやらせる。
Excel は「見せるための入れ物」として割り切る。
テンプレ型なら「どのセルに何を入れるか」を仕様として決めておく。
Path と絶対パスでファイルを管理し、毎回同じ場所・同じ名前ルールで出力する。
最初はシンプルに to_excel だけで動かし、徐々に書式設定やテンプレ連携を足していく。
この型さえ掴めば、「日次売上」「月次サマリ」「部署別集計」「KPI ダッシュボード」など、
今 Excel で手作業しているレポートのかなりの部分を、自動化の対象にできます。
