PythonでExcelの複数シートを読み込んでまとめる手順|シート名の確かめ方と結合
PythonでExcelの複数シートを読み込んでまとめる手順を、pandasのread_excelでシートの名前を確かめ、列をそろえて1つの表にする流れで解説します。月ごとのシートを結合するコードを、架空のブックで試した結果とあわせて紹介します。
本記事はプロモーションを含みます。紹介する情報は、実際の成果や効果を保証するものではありません。
目次
この記事でわかること
- 1つのExcelのブックにある、複数のシートの名前を確かめる方法
- pandasのread_excelで、すべてのシートを読み込む手順
- シートの名前を列に残して、1つの表にまとめるコード
- 架空のブックで試してわかった、つまずきやすいところ
月ごとの売上や経費を、1つのブックの中でシートを分けて記録していることがあります。1年分を集計したいときに、シートを1枚ずつ開いてコピーすると、貼り付け忘れや二重の貼り付けが起きやすくなります。この記事では、pandasでシートをまとめて読み込み、1つの表にしてから保存する手順を紹介します。
pandasの関数の説明は、pandas 3.0.6の公式の資料で確かめました。コードは、架空の売上のブックで実際に動かしています。
先に結論: シートの名前と列を確かめてからまとめる
先に結論を書くと、最初にシートの名前を一覧で確かめ、まとめるシートを決めてから読み込み、列がそろっているかを確かめて1つの表にします。 どのシートから来た行かが分かるように、シートの名前を列に残します。
| 作業 | 担当 |
|---|---|
| シート名の一覧 | Python |
| 対象を決める | 人 |
| 列の確認 | Python |
| 1つにまとめる | Python |
| 行数と合計の確認 | 人 |
例にする売上のブック
この記事では、次のような架空の売上のブック(sales_2026.xlsx)を例にします。シートは月ごとに分かれていて、どのシートにも伝票番号・品目・金額の3つの列があります。
- 7月: 3行
- 8月: 2行
- 9月: 3行
- 10月: 見出しの行だけで、まだ売上の行が無い
複数のファイルではなく、1つのブックの中にシートが並んでいる形です。月ごとに別のファイルになっているときは、Excelの複数ファイルを1つにまとめる方法の手順が合います。
手順: すべてのシートを読み込んで1つの表にする
次のコードは、sales_2026.xlsx のシートの名前を表示し、すべてのシートを読み込みます。行の無いシートは飛ばし、列が1枚目のシートと違うシートがあれば止まります。そうでなければ、シートの名前を先頭の列に入れてから1つの表にまとめ、sales_all.xlsx に保存します。
# 1つのブックにある月ごとのシートを、1つの表にまとめる
import pandas as pd
book = pd.ExcelFile("sales_2026.xlsx")
print("シートの名前:", book.sheet_names)
sheets = pd.read_excel(book, sheet_name=None)
parts = []
base = None
for name, sheet in sheets.items():
if sheet.empty:
print(name, "は行が無いので飛ばす")
continue
if base is None:
base = list(sheet.columns)
elif list(sheet.columns) != base:
raise SystemExit(f"{name} の列が違う: {list(sheet.columns)}")
sheet.insert(0, "シート", name)
parts.append(sheet)
print(name, len(sheet), "行 金額の合計", sheet["金額"].sum())
table = pd.concat(parts, ignore_index=True)
print("まとめた後", len(table), "行 金額の合計", table["金額"].sum())
table.to_excel("sales_all.xlsx", index=False)
- pd.ExcelFile と sheet_names: pandasの資料では、ExcelFileはExcelのシートを表として読み取るためのクラスで、sheet_namesはブックにあるシートの名前の一覧です。シートの名前を前もって知らないときに役に立つとされています
- sheet_name=None: pandasの資料では、Noneを指定すると、シートごとの表が入った辞書を返すとしています。辞書のキーがシートの名前です
- sheet.empty: 行の無いシートを見分けます。pandasの資料では、emptyは表が完全に空で、行か列の数が0のときにTrueになるとしています
- sheet.insert(0, "シート", name): 表の先頭に、シートの名前の列を足します。pandasの資料では、insertは指定した位置に列を入れる関数で、同じ名前の列がすでにあるとValueErrorになるとしています
- ignore_index=True: pandasの資料では、Trueにすると元の行番号を使わず、0から順に番号を振り直すとしています
1枚ずつ表をリストに集めて、最後に1回だけconcatでつなげています。pandasの資料でも、for文の中で1行ずつ足して表を作るのは勧められず、リストに集めてから1回のconcatで表を作るように書かれています。「金額」は合計を確かめる列なので、自分のブックの列の名前に変えます。
架空のブックで試した結果
架空のブックで試すと、シートの名前は「7月・8月・9月・10月」の順に表示されました。10月のシートは見出しの行しか無いため飛ばされ、7月の3行・8月の2行・9月の3行の、あわせて8行の表になりました。金額の合計は、シートごとの5,400・3,400・4,200を足した13,000と、まとめた後の合計が同じでした。保存した表の先頭の列には、どの行にもシートの名前が入っていました。元の sales_2026.xlsx は変わりませんでした。
検証は作業PCで行いました。使った版は、Pythonが3.12.10、pandasが3.0.6、openpyxlが3.1.5です。
シートの名前を確かめる
まとめる前に、コードの最初の行で表示されるシートの名前の一覧を見ます。pandasの資料では、sheet_nameに文字を渡すとシートの名前、数字を渡すと0から数えたシートの位置として扱うとしています。
同じブックに、メモや集計のシートがあるときは、すべてを読み込まずに、まとめるシートだけを名前で指定します。pandasの資料では、名前や位置をリストで渡すと、複数のシートを読み込めるとしています。
# まとめるシートを名前で指定して読み込む(この行を、手順のコードの sheets = の行と入れ替える)
sheets = pd.read_excel(book, sheet_name=["7月", "8月", "9月"])
架空のブックで試すと、リストで渡した3枚のシートだけが、渡した順の辞書として読み込まれました。
まとめた後に確かめること
まとめた表は、次の3つを見てから使います。
- 行数: シートごとの行数を足した数と、まとめた後の行数が同じか
- 合計: シートごとの金額の合計を足した値と、まとめた後の合計が同じか
- シートの列: どの行にもシートの名前が入っていて、まとめたいシートが全部あるか
手順のコードは、シートごとの行数と合計、まとめた後の行数と合計を表示します。表示された数字を見比べて、合わなければ、どのシートが抜けたかをシートの列で探します。まとめた表から品目ごとの件数と合計を出す手順は、PythonでCSVを集計する手順で紹介しています。
Pythonでまとめるかの判断
迷ったときは、「シートが毎月増えるか」で決めます。毎月シートが1枚ずつ増えるブックなら、Pythonの手順を決めておくと、同じ確かめ方で何度でもまとめ直せます。一度だけで、シートが2〜3枚なら、Excelでコピーして行数と合計を見比べるほうが早いこともあります。
まとめたい表が、1つのブックではなく別々のファイルに分かれているときは、Power Queryを含めた選び方をExcelの複数ファイルを1つにまとめる方法で紹介しています。
つまずきやすいところ
- 1枚目のシートしか読まれない: pandasの資料では、sheet_nameの初期の設定は0で、1枚目のシートを読み込みます。架空のブックでも、sheet_nameを付けないと7月の3行だけになりました。すべてのシートを読むときは sheet_name=None を付けます
- シートの名前の空白: 「9月」の後ろに空白が入った名前のシートを作って試すと、sheet_name="9月" では「Worksheet named '9月' not found」というエラーで止まりました。sheet_namesの一覧で、名前を正確に確かめます
- 列の名前がシートごとに違う: pandasの資料では、列が一部だけ重なる表をconcatでつなげると、重ならない列はNaNで埋められます。9月のシートだけ「金額」を「売上」に変えて試すと、そのままつなげた表は列が1つ増え、空の値が入りました。手順のコードでは、保存する前に止まり、sales_all.xlsx は作られませんでした
- シートの上にタイトルの行がある: 1行目に表のタイトルがあるシートを読むと、列の名前が「Unnamed: 1」のようになりました。pandasの資料では、headerは列の名前に使う行の番号(0から数える)です。header=1 を付けると、2行目が列の名前になりました
日付の列が文字や数字になって読み込まれるときは、PythonでExcelの日付を正しく読み込む手順で日付に直してから並べ替えます。
まとめ
- 最初にsheet_namesでシートの名前を確かめ、まとめるシートを決めます
- sheet_name=None ですべてのシートを、名前のリストで一部のシートを読み込めます
- 列が1枚目のシートとそろっているかを確かめ、シートの名前を列に残してからconcatで1つにします
- まとめた表は別のファイルに保存し、行数と合計をシートごとの値と見比べてから使います
よくある質問
すべてのシートを、一度に読み込めますか?
読み込めます。pandasのread_excelでsheet_name=Noneを指定すると、シートごとの表が入った辞書が返ります。辞書のキーがシートの名前なので、for文で1枚ずつ取り出して扱えます。
sheet_nameを指定しないと、どのシートが読まれますか?
pandasの資料では、sheet_nameの初期の設定は0で、1枚目のシートだけを読み込みます。架空のブックで試したときも、読み込まれたのは1枚目の7月のシートの3行だけでした。
一部のシートだけをまとめたいときは、どうしますか?
sheet_nameに、まとめたいシートの名前をリストで渡します。メモや集計のシートが同じブックにあるときは、月のシートだけを並べると、ほかのシートが混ざりません。
シートによって列の名前が違うと、どうなりますか?
そのままconcatでつなげると、名前の違う列は別の列になり、ない所は空の値(NaN)で埋められます。この記事のコードは、列が1枚目のシートと違えば、保存する前に止まります。
まとめた結果を保存すると、元のブックは変わりますか?
この記事のコードは、まとめた表を sales_all.xlsx という別のファイルに書き出すので、元の sales_2026.xlsx はそのままです。架空のブックで試したときも、元のファイルの中身は同じでした。