PythonでExcelに書き出す表の条件に合うセルに色を付ける手順|pandasのStylerで基準に届かない売上を目立たせる
Pythonで作った表をExcelに書き出すときに、条件に合うセルだけ背景色を付ける手順を、pandasのStylerで解説します。書き出せる色の書き方や、jinja2の版で止まるなどのつまずきを、架空の表で試して紹介します。
目次
この記事でわかること
- 条件に合うセルだけに、背景色を付けてExcelに書き出す方法
- いちばん大きい値に色を付けるhighlight_maxの使い方
- Excelに書き出せる色の書き方と、書き出されない書式
- jinja2の版や、文字の混ざった列で止まるときの直し方
売上の一覧をPythonで作ってExcelに渡すとき、「基準に届かない店だけ赤くしてほしい」と頼まれることがあります。書き出した後にExcelで色を塗ると、毎回の手作業になります。この記事では、pandasのStylerで、条件に合うセルにだけ色を付けたまま、別のファイルに書き出す手順をまとめます。
調べたのは、pandas 3.1.0の公式の資料(Styler.map、Styler.highlight_max、Styler.to_excelと、ユーザーガイドのTable Visualization)で、2026年11月1日に原文に当たりました。表の店舗と売上は、確かめるために作った架空のものです。
先に結論: mapで色の指定を返し、Stylerのto_excelで書き出す
セルの値を受け取って「background-color: #ffc7ce」のような色の指定を返す関数を作り、Stylerのmapで売上の列に当てます。 書き出しは、DataFrameではなくStylerのto_excelで行います。この記事で使う道具は次の3つです。
| 道具 | 働き | 記事のコード |
|---|---|---|
| map | セルごとに色の指定を付ける | 基準に届かない売上 |
| highlight_max | いちばん大きい値に色を付ける | 売上の最大 |
| to_excel | 色を付けたまま書き出す | index=False |
Stylerのしくみ
DataFrameの.styleで、表の見た目を決めるStylerが手に入ります。pandasの資料では、mapはCSSの書式を返す関数をセルごとに当てる機能で、関数は1つの値を受け取って文字を返すとしています。何も付けないセルには、空の文字かNoneを返します。
highlight_maxは、指定した向きのいちばん大きい値のセルに、背景色を付けます。資料では、色の初期の設定は黄色で、colorで変えられるとしています。どちらも、subsetで色を付ける列を絞れます。
ユーザーガイドでは、Excelに書き出せるのは、applyとmapなどで1つずつのセルに付けた書式だとしています。表全体にまとめて付ける書式(set_table_styles)は、書き出されません。
手順: 基準に届かない売上に色を付けて書き出す
次のコードは、架空の売上の表 sales.xlsx(店舗・売上の2列)を読み、売上が50000に届かないセルを薄い赤、いちばん大きい売上を薄い緑にして、sales_marked.xlsx に書き出します。sales.xlsx には書き込みません。基準の50000は、自分の表の基準の値に置き換えて使います。
import pandas as pd
shop_sales = pd.read_excel("sales.xlsx") # 元のファイルは読むだけ
def mark_short(value):
# 基準に届かない売上だけ、薄い赤の背景にする(それ以外は何も付けない)
return "background-color: #ffc7ce" if value < 50000 else ""
styled = (
shop_sales.style
.map(mark_short, subset=["売上"])
.highlight_max(subset=["売上"], color="#c6efce")
)
styled.to_excel("sales_marked.xlsx", index=False)
pandasのほかに、xlsxを書き出すopenpyxlと、Stylerが使うjinja2を入れておきます。pandas 3.1.0では、jinja2は3.1.6以上が必要です。
試した結果
架空の売上の表(6行)で動かしました。売上は62000・48000・75000・31000・空欄・50000で、ちょうど50000の行と、空欄の行を入れています。
- 48000と31000のセルに薄い赤(FFC7CE)、75000のセルに薄い緑(C6EFCE)が付きました
- ちょうど50000の行は「届かない」に入らず、色は付きませんでした。空欄の行も色なしでした
- 店舗の列と見出しの行には、色が付きませんでした
- 元の sales.xlsx のハッシュ値は、実行の前後で同じでした
試した環境は、Mac の作業PCのPython 3.12.15で、pandas 3.1.0・openpyxl 3.1.5・jinja2 3.1.6を入れています。色はopenpyxlでセルの塗りを読んで確かめました。Excelのアプリで開いた見え方は、確かめていません。
自分で直すか、相談するかの判断
目安は、「色を付ける基準が、1つの数で決まっているか」です。「50000に届かない」のように決まっていれば、上のコードの数を変えるだけで使えます。
店舗ごとに目標が違う、前の月と比べる、といった基準なら、関数の中身が変わります。どの値を基準にするか、ちょうど基準の値を「届かない」に入れるかを、表を受け取る人と先に決めておきます。
つまずきやすいところ
- 「.styleにはjinja2が要る」と止まる: 試したときも、jinja2 3.1.4が入った環境では、AttributeErrorで止まりました。入っていないのではなく、pandas 3.1.0が求める3.1.6より古いためです。jinja2を3.1.6以上にすると動きました
- 色の書き方が違う: 「rgb(255,199,206)」や、ない色の名前の「lightred」では、CSSWarningという警告が出るだけで止まらず、塗りの色は00000000になりました。#rrggbbの形で書きます
- DataFrameのto_excelで書き出す: 色を付けたのはStylerなので、元のshop_salesのto_excelでは色は付きません。styledのto_excelを使います
- formatで付けた桁区切りが消える: Stylerのformatで「62,000」の形にしても、書き出したセルの表示の形は「General」のままでした。セルに書式を付けるなら、mapで「number-format: #,##0」を返すと、その形が入りました。列の幅や桁区切りをまとめて整える方法は、PythonでExcel書き出しの列の幅と数値の書式を整える手順で紹介しています
- 売上の列に文字が混ざっている: 「未入力」のような文字があると、比べるところでTypeErrorになりました。先に数に直すか、空欄にしてから色を付けます
- 色ではなく、区分の列を足したい: 「達成」「未達」のような言葉の列を作る方法は、PythonでExcelの複数の条件から区分の列を作る手順にまとめています
- 毎月の報告書の形まで決まっている: 見出しの色や決まった表の形を含めて、報告書をまとめて作る流れは、Excelの定型レポートを自動化する手順が参考になります
まとめ
- 色の指定を返す関数を作り、Stylerのmapで列に当てます
- いちばん大きい値はhighlight_maxで目立たせられます
- 書き出しはStylerのto_excelで行い、色は#rrggbbの形で書きます
- jinja2の版が古いと止まるので、3.1.6以上を入れます
よくある質問
Excelの条件付き書式として残りますか?
残りません。試したときも、書き出したファイルに条件付き書式の決まりは1つもなく、セルに決まった背景色がそのまま付いていました。後で値を書き換えても、色は自動では変わらない前提で使います。Excelのアプリで条件付き書式の一覧を開いて確かめてはいません。
色の指定には、どんな書き方が使えますか?
pandasのユーザーガイドでは、Excelに書き出すときの色は、CSS2の色の名前と、#rgbか#rrggbbの形だけに対応しているとしています。試したときも、rgb(255,199,206)の書き方は警告が出て、指定した色になりませんでした。
1行ずつ、別の列の目標と比べて色を付けられますか?
できます。mapは1つのセルの値だけを見るので、同じ行の別の列と比べるときは、行ごとに関数を当てるapplyを使います。ユーザーガイドでは、Excelに書き出せるのは、applyとmapなどで1つずつのセルに付けた書式だとしています。
空欄のセルは、どうなりますか?
試した表では、空欄のセルには色が付きませんでした。空欄は数として比べると「基準より小さい」にならないためです。空欄も目立たせたいときは、highlight_nullを足します。
元のExcelのファイルの色も変わりますか?
変わりません。記事のコードは元のファイルを読むだけで、色を付けた表は別の名前のファイルに書き出します。試したときも、元のファイルのハッシュ値は実行の前後で同じでした。