Pythonで複数のExcelを1つに集計!pandasで支店別売上を月次レポートにまとめる自動化入門
「毎月、支店や担当者から届くExcelをコピペでまとめるのがしんどい…」「ファイルが増えるたびに集計表を作り直している」
こういう作業、地味に時間がかかりますよね。しかも手作業だと、貼り付け漏れや計算ミスも起きがちです。
この記事では、フォルダに入った複数のExcelファイルをPythonで1つにまとめ、支店×商品のクロス集計をして、見やすいExcelレポートとして保存するところまでを一緒に作っていきます。
難易度:初級〜中級(Pythonの基本文法とpandasのDataFrameを少し触ったことがある方向け)。副業やフリーランスで受ける「Excel集計の自動化」案件でも、そのまま使える基本パターンです🚀
完成イメージと準備

やることはシンプルで、イメージとしては「フォルダごと読み込む → 縦に積む → ピボットで集計 → Excelに書き出す」の4ステップです。
salesフォルダに売上_東京.xlsx・売上_大阪.xlsx・売上_福岡.xlsxがある- 各ファイルの列は「日付・商品・数量・単価」
- 最後に「集計」「明細」の2シートを持つ
月次売上レポート_2026-09.xlsxを作る
ライブラリは pandas と openpyxl を使います。pandas で .xlsx を読み書きするには openpyxl が別途必要なので、まとめて入れておきましょう。
pip install pandas openpyxl
今回の動作確認は Python 3.13・pandas 3.0.3・openpyxl 3.1.5 で行いました。
ステップ1:練習用のExcelファイルを作る
手元に実データがない方のために、まずはサンプルのExcelを3つ作ります。実際の業務では、ここは「各支店から届いたファイル」に置き換わる部分です。
from pathlib import Path
import pandas as pd
# 支店ごとの売上データ(本来は各支店から届くExcelファイル)
data = {
"東京": [("2026-09-01", "ノートPC", 2, 128000), ("2026-09-03", "マウス", 10, 2980),
("2026-09-10", "モニター", 3, 34800), ("2026-09-18", "ノートPC", 1, 128000)],
"大阪": [("2026-09-02", "モニター", 2, 34800), ("2026-09-09", "マウス", 6, 2980),
("2026-09-15", "キーボード", 4, 8980)],
"福岡": [("2026-09-05", "キーボード", 5, 8980), ("2026-09-12", "ノートPC", 1, 128000),
("2026-09-20", "マウス", 8, 2980)],
}
folder = Path("sales")
folder.mkdir(exist_ok=True)
for branch, rows in data.items():
df = pd.DataFrame(rows, columns=["日付", "商品", "数量", "単価"])
df.to_excel(folder / f"売上_{branch}.xlsx", index=False)
print(f"作成: 売上_{branch}.xlsx({len(df)}行)")

実行すると sales フォルダに3つのファイルができます。
ステップ2:フォルダ内のExcelをまとめてクロス集計する
ここがこの記事のメインです。ポイントをまとめるとこんな感じです👇
Path.glob("売上_*.xlsx")で、対象ファイルを名前のパターンで一括取得- ファイル名から支店名を取り出して列に追加(元のExcelに支店列がなくてもOK)
pd.concatで縦に1つの表へpivot_tableで「支店 × 商品」の金額合計を作る。margins=Trueで合計行・合計列も自動で付きます
from pathlib import Path
import pandas as pd
pd.set_option("display.unicode.east_asian_width", True) # 日本語の列をそろえて表示
folder = Path("sales")
frames = []
# フォルダ内の「売上_〇〇.xlsx」をすべて読み込む
for path in sorted(folder.glob("売上_*.xlsx")):
df = pd.read_excel(path)
df["支店"] = path.stem.removeprefix("売上_") # ファイル名から支店名を取り出す
frames.append(df)
# 縦に1つの表へまとめる
all_sales = pd.concat(frames, ignore_index=True)
all_sales["金額"] = all_sales["数量"] * all_sales["単価"]
print(f"読み込んだファイル: {len(frames)}件 / 合計 {len(all_sales)}行")
# 支店 × 商品のクロス集計(金額の合計)
summary = all_sales.pivot_table(
index="支店", columns="商品", values="金額",
aggfunc="sum", fill_value=0, margins=True, margins_name="合計",
)
print(summary)

実行結果は次のとおりです。東京のノートPCは「2台×128,000円+1台×128,000円=384,000円」で、ちゃんと合っていますね😊
ちなみに display.unicode.east_asian_width の設定を入れないと、日本語の列名で表示がガタガタにずれます。地味ですが、確認作業がぐっと楽になるので入れておくのがおすすめです。
ここが重要です👇 glob のパターンで「余計なファイル」を拾わない
Excelでファイルを開いている間、同じフォルダに ~$売上_東京.xlsx のような一時ファイルができます。*.xlsx で全部拾うと、これを読もうとしてエラーになることがあります。
今回のように 売上_*.xlsx と先頭の文字まで指定しておけば、~$ で始まる一時ファイルは対象外になります。ファイル名のルールを決めておくのが、集計自動化を安定させるコツです。
ステップ3:見やすいExcelレポートとして保存する
集計できたら、Excelに書き出します。pd.ExcelWriter を使うと、1つのファイルに複数シートを書けます。さらに openpyxl で、見出しの色・3桁区切り・列幅を整えます。
次のコードは、ステップ2のコードの末尾にそのまま追記してください。
# ---- ここから追記:集計結果をExcelレポートに書き出す ----
from openpyxl.styles import Font, PatternFill
output = "月次売上レポート_2026-09.xlsx"
with pd.ExcelWriter(output, engine="openpyxl") as writer:
summary.to_excel(writer, sheet_name="集計")
all_sales.to_excel(writer, sheet_name="明細", index=False)
# 見た目を整える(見出しを太字+色付き、金額を3桁区切り、列幅を広げる)
for ws in writer.book.worksheets:
for cell in ws[1]:
cell.font = Font(bold=True, color="FFFFFF")
cell.fill = PatternFill("solid", fgColor="4472C4")
for row in ws.iter_rows(min_row=2):
for cell in row:
if isinstance(cell.value, (int, float)):
cell.number_format = "#,##0"
for col in ws.columns:
ws.column_dimensions[col[0].column_letter].width = 14
print(f"保存しました: {output}")

つまり、writer.book が openpyxl のブック本体なので、pandas で書いた直後にそのまま装飾できる、というわけです。
実行すると、ターミナルにステップ2と同じ集計表が出たあと「保存しました: 月次売上レポート_2026-09.xlsx」と表示されます。保存したファイルを openpyxl で読み直して、「集計」「明細」の2シートができていること、金額に3桁区切りが付いていることを確認しました。
よくあるつまずき⚠️
| 症状 | 原因と対処 |
|---|---|
ImportError: Missing optional dependency 'openpyxl' |
openpyxl が入っていません。pip install openpyxl で解決します |
保存時に PermissionError |
出力先の Excel ファイルを開いたまま実行しています。閉じてから再実行しましょう |
| 集計結果が空・行数が少ない | ファイル名がパターンと合っていません。print(list(folder.glob("売上_*.xlsx"))) で拾えているか確認します |
列名が違って KeyError |
ファイルごとに「数量」「個数」など表記がバラバラなケース。読み込み直後に df.rename(columns={"個数": "数量"}) でそろえます |
これ、実務で一番多いのは最後の「列名のバラつき」です。自動化する前に、提出してもらうExcelのテンプレートをそろえてもらうだけで、トラブルがかなり減りますよ。
まとめ
Path.globでフォルダ内のExcelをパターン指定で一括取得できるpd.concatで縦に積み、pivot_table(margins=True)で合計付きのクロス集計が一発で作れるpd.ExcelWriterで複数シートを書き出し、writer.bookから openpyxl で見た目まで整えられる- ファイル名と列名のルールを決めておくのが、安定運用のいちばんのコツ
毎月30分かかっていたコピペ集計も、一度スクリプトにしてしまえば実行するだけで終わります。「むずかしそう」を「できそう」に変える第一歩として、ぜひ手元のExcelで試してみてください😊
こちらも読まれています
📚 関連商品・おすすめ書籍
※本記事にはアフィリエイトリンクが含まれます。





