何をしたいテクニックなのか
ゴールはこうです。
「pandas の DataFrame を Excel に書き出すとき、
ただの“罫線付きの表”ではなく、Excel の“テーブル機能(フィルタ付きのあれ)”として出したい」
Excel の「テーブル」は、見た目が整うだけでなく、
フィルタボタンが自動で付く
行を追加しても数式が自動で伸びる
スタイル(帯状の色など)が一括で変えられる
といったメリットがあります。
これをコードから作るのが、xlsxwriter の add_table です。
pandas と組み合わせるときは、
engine="xlsxwriter"to_excel でデータを書き出すworksheet.add_table(...) でその範囲をテーブル化する
という流れになります。
一番シンプルな「DataFrame → テーブル」の例
最小コードで全体像をつかむ
import pandas as pd
df = pd.DataFrame({
"日付": ["2025-01-01", "2025-01-02", "2025-01-03"],
"商品": ["りんご", "みかん", "バナナ"],
"金額": [1000, 800, 1200]
})
with pd.ExcelWriter("table_basic.xlsx", engine="xlsxwriter") as writer:
df.to_excel(writer, sheet_name="売上", index=False)
workbook = writer.book
worksheet = writer.sheets["売上"]
rows = len(df)
cols = len(df.columns)
first_row = 0
first_col = 0
last_row = first_row + rows
last_col = first_col + cols - 1
worksheet.add_table(
first_row,
first_col,
last_row,
last_col,
{
"columns": [{"header": col} for col in df.columns],
"style": "Table Style Medium 9"
}
)
Pythonこのコードを実行すると、「売上」シートの A1 から C4 までが、
Excel の“テーブル”として認識されます(フィルタボタン付き・スタイル付き)。
ここから、重要な部分を順番にかみ砕いていきます。
add_table の「範囲指定」を理解する
行・列は 0 始まりで指定する
add_table の最初の 4 つの引数は、
開始行
開始列
終了行
終了列
です。すべて 0 始まりで数えます。
上の例では、
ヘッダー行を含めた範囲をテーブルにしたい
ヘッダーは 1 行目(0 行目)
データは 3 行ぶん(行数 = 3)
という前提で、こう計算しています。
rows = len(df) # データ行数(3)
cols = len(df.columns) # 列数(3)
first_row = 0 # ヘッダー行(1 行目)
first_col = 0 # A 列
last_row = first_row + rows # 0 + 3 = 3(0,1,2,3 → ヘッダー+3 行)
last_col = first_col + cols - 1 # 0 + 3 - 1 = 2(A=0, B=1, C=2)
Pythonつまり、add_table(0, 0, 3, 2, ...) は、
A1 から C4 までをテーブルにする
という意味になります。
ここで大事なのは、「ヘッダー行も範囲に含める」ということです。
ヘッダー行+データ行、全部まとめてテーブルの範囲にします。
columns オプションで「ヘッダー情報」を渡す
DataFrame の列名をそのままテーブルのヘッダーに使う
add_table の第 5 引数はオプションの辞書です。
その中の "columns" キーで、列ごとの設定を渡します。
一番シンプルには、こう書きます。
{
"columns": [{"header": col} for col in df.columns]
}
Pythonこれは、
列ごとに {"header": 列名} の辞書を作る
それをリストにして "columns" に渡す
という形です。
to_excel(index=False) で書き出したとき、
A1, B1, C1 にはすでにヘッダー(列名)が入っていますが、add_table にも "header" を渡しておくのが正しい使い方です。
テーブルスタイルを指定する
見た目を「Excel の標準スタイル」から選ぶ
"style" キーで、テーブルの見た目を指定できます。
"style": "Table Style Medium 9"
Pythonこの名前は、Excel の「テーブルデザイン」タブで選べるスタイル名と対応しています。
よく使うのは、
“Table Style Medium 2”
“Table Style Medium 9”
“Table Style Light 9”
などの “Medium” や “Light” 系です。
スタイルを指定しない場合でもテーブルにはなりますが、
色付きの帯やヘッダーの強調が欲しいなら、何かしら指定しておくと見栄えがよくなります。
実務テンプレート:集計結果をテーブルとして出す
月次集計をテーブル形式で出力する例
import pandas as pd
df = pd.read_excel("sales.xlsx", parse_dates=["日付"])
df["金額"] = pd.to_numeric(df["金額"], errors="coerce")
monthly = (
df.assign(月=df["日付"].dt.to_period("M"))
.groupby("月", as_index=False)["金額"].sum()
)
with pd.ExcelWriter("sales_monthly_table.xlsx", engine="xlsxwriter") as writer:
monthly.to_excel(writer, sheet_name="月次集計", index=False)
workbook = writer.book
worksheet = writer.sheets["月次集計"]
rows = len(monthly)
cols = len(monthly.columns)
first_row = 0
first_col = 0
last_row = first_row + rows
last_col = first_col + cols - 1
worksheet.add_table(
first_row,
first_col,
last_row,
last_col,
{
"columns": [{"header": col} for col in monthly.columns],
"style": "Table Style Medium 9"
}
)
Pythonこのファイルを開くと、「月次集計」シートの表が、
フィルタ付き・帯状の色付きの“テーブル”として扱われます。
フィルタで特定の月だけ絞り込んだり、
テーブル全体を選択してグラフを作ったり、
Excel 側の操作が一気にやりやすくなります。
startrow / startcol と組み合わせる
シートの途中からテーブルを置きたい場合
タイトル行や説明文を上に置いて、
その下からテーブルを始めたいこともあります。
例えば、「3 行目の B 列からテーブルを置きたい」なら、to_excel と add_table の両方で位置を合わせます。
import pandas as pd
df = pd.DataFrame({
"日付": ["2025-01-01", "2025-01-02"],
"商品": ["りんご", "みかん"],
"金額": [1000, 800]
})
with pd.ExcelWriter("table_offset.xlsx", engine="xlsxwriter") as writer:
df.to_excel(
writer,
sheet_name="レポート",
index=False,
startrow=2,
startcol=1
)
workbook = writer.book
worksheet = writer.sheets["レポート"]
rows = len(df)
cols = len(df.columns)
first_row = 2
first_col = 1
last_row = first_row + rows
last_col = first_col + cols - 1
worksheet.add_table(
first_row,
first_col,
last_row,
last_col,
{
"columns": [{"header": col} for col in df.columns],
"style": "Table Style Medium 9"
}
)
Pythonここでは、
3 行目(startrow=2)・B 列(startcol=1)から DataFrame を書き出す
同じ位置から add_table の範囲を指定する
というふうに、位置を揃えています。
よくあるつまずきポイント
engine=”xlsxwriter” を忘れると add_table が使えない
worksheet.add_table は XlsxWriter の機能です。ExcelWriter(..., engine="xlsxwriter") を指定していないと、writer.book や writer.sheets[...] が XlsxWriter のオブジェクトにならず、add_table が呼べません。
「テーブルを作るときは、必ず engine=’xlsxwriter’」
これはセットで覚えてください。
範囲指定を間違えるとヘッダーが二重になったり、行が欠けたりする
add_table の範囲には「ヘッダー行も含める」必要があります。last_row を first_row + rows - 1 にしてしまうと、
ヘッダー行がテーブルに含まれず、Excel 側でヘッダーを勝手に作られてしまいます。
ヘッダー+データ行数、という意識で last_row を計算するのがポイントです。
小さな練習アイデア
自分で小さな DataFrame を作って、
1 回目は普通に to_excel だけ
2 回目は、ここで紹介した add_table 付き
の 2 パターンを出力して、Excel で開いてみてください。
フィルタボタンの有無、スタイルの違い、
テーブルとして選択したときの挙動などを比べると、
「ただの表」と「テーブル」の差が体感でわかります。
そこまで見えたら、
「このシートはテーブルにしておくと、あとで誰が触っても楽だな」
という設計の目線が自然に育っていきます。
