Excelのセル装飾(フォント/罫線/背景色/列幅・行高)をPythonから自動化するならopenpyxlが最有力です。
本記事はコピペしてそのまま動くことを最優先に、初心者の方でも迷わないように、インストールから各種書式設定まで丁寧に解説します。
内容はセルのフォント・罫線・塗りつぶし・列幅/行の高さに絞って説明します。
初心者向けopenpyxlの基本
Excelの新規作成、既存ブックの読み込み、シートとセルの扱い方、値の読み書きまで、必要最小限の基本をまとめます。
ここでの土台が後続の書式設定をスムーズにします。
インストール
Pythonの環境がある前提で、pipでopenpyxlを追加します。
対象はxlsx形式(xlsは不可)です。
pip install openpyxl
出力例(環境により異なります):
Collecting openpyxl
...
Successfully installed openpyxl-3.1.5
Excelの新規作成/保存
最小コードで新規ブックを作り、値を書き込んで保存します。
# 新規Excelを作成し、A1とB2に値を書いて保存する例
from openpyxl import Workbook
wb = Workbook() # 新規ブック作成
ws = wb.active # アクティブなシートを取得
ws.title = "基本" # シート名を変更
ws["A1"] = "Hello, openpyxl!" # A1に文字列
ws["B2"] = 123 # B2に数値
wb.save("sample_basic.xlsx") # 保存
print("saved:", "sample_basic.xlsx") # 進捗表示
saved: sample_basic.xlsx
保存はwb.save(...)
を呼んだ時点でファイルに反映されます。
開いたままのExcelがあると上書きできないことがあるので、その場合はExcelを閉じてから実行します。
既存ファイルを開く
保存済みのファイルを開いてシートや値を読む例です。
# 既存Excelを開いて値を読む
from openpyxl import load_workbook
wb = load_workbook("sample_basic.xlsx") # 既存ブックを開く
ws = wb["基本"] # シート名で取得
print(ws["A1"].value, ws["B2"].value) # 値の取得
Hello, openpyxl! 123
シート選択とセル指定
セル参照はA1形式、行列番号、ユーティリティ変換の3通りを覚えておくと便利です。
from openpyxl import Workbook
from openpyxl.utils import get_column_letter, column_index_from_string
wb = Workbook()
ws = wb.active
ws.title = "参照"
# A1形式の参照
ws["C3"] = "C3"
# 行・列番号で参照(row=3, column=2 はB3)
ws.cell(row=4, column=2).value = "B4"
# 列番号と列記号の相互変換
print(get_column_letter(28)) # 28 -> AB
print(column_index_from_string("AD")) # AD -> 30
wb.save("address_demo.xlsx")
AB
30
A1形式の範囲はws["A1:C3"]
のように指定できます。
行ごとの処理にはiter_rows
が高速です。
値の読み書き
数値、文字列、日付など基本的な型を書けます。
日付はdatetime
を使うとExcelの日時として扱われます。
from openpyxl import Workbook
from datetime import datetime
wb = Workbook()
ws = wb.active
ws.title = "値"
ws["A1"] = "文字列"
ws["B1"] = 123.45
ws["C1"] = True
ws["D1"] = datetime(2025, 1, 23) # 日付
ws["D1"].number_format = "yyyy-mm-dd" # 表示形式を指定
wb.save("values_demo.xlsx")
# 読み出し
from openpyxl import load_workbook
wb2 = load_workbook("values_demo.xlsx")
ws2 = wb2["値"]
print(type(ws2["B1"].value), ws2["D1"].value) # 型と値を確認
<class 'float'> 2025-01-23 00:00:00
コピペ用テンプレ
毎回の雛形として、ブックを開く/新規作成して保存する処理を1つにまとめました。
このテンプレに後述の書式コードを足していけばOKです。
# Excelブックを開く(なければ作る)+保存のテンプレ
from openpyxl import Workbook, load_workbook
from pathlib import Path
def open_or_create_xlsx(path: str, sheet: str = "Sheet1"):
"""指定パスのxlsxを開く。存在しなければ新規作成。指定シートがなければ作成。"""
if Path(path).exists():
wb = load_workbook(path)
ws = wb[sheet] if sheet in wb.sheetnames else wb.create_sheet(sheet)
else:
wb = Workbook()
ws = wb.active
ws.title = sheet
return wb, ws
def save(wb, path: str):
"""保存して保存先を表示"""
wb.save(path)
print(f"saved: {path}")
def main():
xlsx = "demo.xlsx"
wb, ws = open_or_create_xlsx(xlsx, "書式")
ws["A1"] = "テンプレ準備OK"
save(wb, xlsx)
if __name__ == "__main__":
main()
saved: demo.xlsx
フォント設定
フォントはopenpyxl.styles.Font
で指定します。
フォント名、サイズ、太字/斜体/下線、文字色を組み合わせて設定できます。
フォント名/サイズ
フォント名とポイントサイズを指定します。
Windows環境なら「Meiryo」「MS Gothic」「MS Mincho」などが利用できます。
from openpyxl import Workbook
from openpyxl.styles import Font
wb = Workbook()
ws = wb.active
ws.title = "フォント"
ws["A1"] = "明朝14pt"
ws["A1"].font = Font(name="MS Mincho", size=14)
ws["A2"] = "メイリオ11pt"
ws["A2"].font = Font(name="Meiryo", size=11)
wb.save("font_demo.xlsx")
# 設定を読み出して確認
from openpyxl import load_workbook
wb2 = load_workbook("font_demo.xlsx")
ws2 = wb2["フォント"]
print(ws2["A1"].font.name, ws2["A1"].font.size)
MS Mincho 14.0
太字/斜体/下線
太字はbold=True
、斜体はitalic=True
です。
下線はunderline="single"
など種類を文字列で指定します。
from openpyxl import Workbook
from openpyxl.styles import Font
wb = Workbook()
ws = wb.active
ws.title = "文字装飾"
# 太字
ws["B1"] = "太字"
ws["B1"].font = Font(bold=True)
# 斜体
ws["B2"] = "斜体"
ws["B2"].font = Font(italic=True)
# 下線(単線/二重線/会計用)
ws["B3"] = "下線(single)"
ws["B3"].font = Font(underline="single")
ws["B4"] = "下線(double)"
ws["B4"].font = Font(underline="double")
ws["B5"] = "下線(singleAccounting)"
ws["B5"].font = Font(underline="singleAccounting")
wb.save("font_style_demo.xlsx")
# 確認
from openpyxl import load_workbook
wb2 = load_workbook("font_style_demo.xlsx")
ws2 = wb2["文字装飾"]
print(ws2["B1"].font.bold, ws2["B2"].font.italic, ws2["B3"].font.underline)
True True single
文字色
文字色は16進数のRGB(6桁RRGGBB
)またはARGB(8桁AARRGGBB
)で指定します。
不透明な色は6桁で十分です。
from openpyxl import Workbook
from openpyxl.styles import Font
wb = Workbook()
ws = wb.active
ws.title = "文字色"
ws["C1"] = "赤色(FF0000)"
ws["C1"].font = Font(color="FF0000") # 6桁RGB
ws["C2"] = "濃緑(00B050)"
ws["C2"].font = Font(color="00B050") # 6桁RGB
ws["C3"] = "半透明青(80-透明度)"
ws["C3"].font = Font(color="80007FFF") # 8桁ARGB: 80(透明度) + 007FFF(青)
wb.save("font_color_demo.xlsx")
# 読み出し確認
from openpyxl import load_workbook
wb2 = load_workbook("font_color_demo.xlsx")
ws2 = wb2["文字色"]
print(ws2["C1"].font.color.rgb)
00FF0000
Excelのテーマ色は開いたテーマに依存して色合いが変わります。
固定色にしたいときはRGB指定を使いましょう。
コピペ用サンプル
見出し行に一括でフォントを設定するスニペットです。
# 見出し行(A1:E1)にフォントを一括設定する例
from openpyxl import Workbook
from openpyxl.styles import Font
wb = Workbook()
ws = wb.active
ws.title = "フォント一括"
# 見出しを用意
headers = ["ID", "商品名", "数量", "単価", "金額"]
for col, text in enumerate(headers, start=1):
ws.cell(row=1, column=col).value = text
# フォント共通設定
head_font = Font(name="Meiryo", size=12, bold=True, color="FFFFFF")
# 範囲に反映
for cell in ws["A1:E1"][0]: # 1行目のセル群
cell.font = head_font
wb.save("font_batch_demo.xlsx")
print("saved: font_batch_demo.xlsx")
saved: font_batch_demo.xlsx
罫線設定
罫線はopenpyxl.styles.Border
とSide
を使います。
1セルだけ、範囲の外枠だけ、内側も含めたグリッドなど用途に応じて使い分けます。
1セルに罫線
セルの上下左右それぞれにSide
を割り当て、Border
として適用します。
from openpyxl import Workbook
from openpyxl.styles import Border, Side
wb = Workbook()
ws = wb.active
ws.title = "セル罫線"
# 罫線のスタイル(細線)
thin = Side(style="thin", color="000000")
ws["A1"] = "外枠のみ"
ws["A1"].border = Border(top=thin, left=thin, right=thin, bottom=thin)
wb.save("border_cell_demo.xlsx")
print("saved: border_cell_demo.xlsx")
saved: border_cell_demo.xlsx
範囲の外枠だけ付ける
外枠のみを描く関数です。
既存の罫線を壊さないよう、足し込みで設定します。
from openpyxl import Workbook
from openpyxl.styles import Border, Side
def set_cell_border(cell, top=None, right=None, bottom=None, left=None):
"""既存罫線を維持しつつ、指定がある辺だけ置き換える"""
cell.border = Border(
top=top or cell.border.top,
right=right or cell.border.right,
bottom=bottom or cell.border.bottom,
left=left or cell.border.left,
)
def outline_border(ws, min_row, min_col, max_row, max_col, style="thick", color="000000"):
"""範囲の外枠のみ罫線を引く"""
side = Side(style=style, color=color)
for r in range(min_row, max_row + 1):
for c in range(min_col, max_col + 1):
cell = ws.cell(row=r, column=c)
top = side if r == min_row else None
bottom = side if r == max_row else None
left = side if c == min_col else None
right = side if c == max_col else None
set_cell_border(cell, top=top, right=right, bottom=bottom, left=left)
# 使用例
wb = Workbook()
ws = wb.active
ws.title = "外枠"
# データを置く(見やすさ用)
for r in range(2, 8):
for c in range(2, 8):
ws.cell(row=r, column=c).value = f"{r},{c}"
# 外枠(太線)
outline_border(ws, min_row=2, min_col=2, max_row=7, max_col=7, style="thick", color="000000")
wb.save("border_outline_demo.xlsx")
print("saved: border_outline_demo.xlsx")
saved: border_outline_demo.xlsx
内側の罫線も付ける
外枠と内側を別スタイルで描く関数です。
表全体のグリッドを作るときに便利です。
from openpyxl import Workbook
from openpyxl.styles import Border, Side
def full_grid_border(ws, min_row, min_col, max_row, max_col,
outline_style="medium", outline_color="000000",
inside_style="thin", inside_color="D9D9D9"):
"""範囲の外枠と内側も罫線を引く"""
out_side = Side(style=outline_style, color=outline_color)
in_side = Side(style=inside_style, color=inside_color)
for r in range(min_row, max_row + 1):
for c in range(min_col, max_col + 1):
top = out_side if r == min_row else in_side
bottom = out_side if r == max_row else in_side
left = out_side if c == min_col else in_side
right = out_side if c == max_col else in_side
ws.cell(row=r, column=c).border = Border(top=top, right=right, bottom=bottom, left=left)
# 使用例
wb = Workbook()
ws = wb.active
ws.title = "外枠+内側"
for r in range(1, 6):
for c in range(1, 6):
ws.cell(row=r, column=c).value = r * c
full_grid_border(ws, 1, 1, 5, 5, outline_style="thick", inside_style="thin")
wb.save("border_full_demo.xlsx")
print("saved: border_full_demo.xlsx")
saved: border_full_demo.xlsx
線の種類/太さ
openpyxlが受け付けるスタイル名は下表のとおりです。
文字列は厳密一致なので、綴りを間違えないように気をつけます。
style | 説明 |
---|---|
hair | 最も細い線 |
thin | 細線 |
medium | 中線 |
thick | 太線 |
dashed | 破線 |
dotted | 点線 |
double | 二重線 |
mediumDashed | 中太の破線 |
mediumDashDot | 中太の一点鎖線 |
mediumDashDotDot | 中太の二点鎖線 |
dashDot | 一点鎖線 |
dashDotDot | 二点鎖線 |
slantDashDot | 斜めの一点鎖線 |
破線を外枠に使うにはSide(style="dashed")
とします。
コピペ用サンプル
よくある「外枠は太線・内側は薄いグレーの細線」のセットアップです。
from openpyxl import Workbook
from openpyxl.styles import Border, Side
def full_grid_border(ws, min_row, min_col, max_row, max_col,
outline_style="thick", outline_color="000000",
inside_style="thin", inside_color="D9D9D9"):
out_side = Side(style=outline_style, color=outline_color)
in_side = Side(style=inside_style, color=inside_color)
for r in range(min_row, max_row + 1):
for c in range(min_col, max_col + 1):
top = out_side if r == min_row else in_side
bottom = out_side if r == max_row else in_side
left = out_side if c == min_col else in_side
right = out_side if c == max_col else in_side
ws.cell(row=r, column=c).border = Border(top=top, right=right, bottom=bottom, left=left)
wb = Workbook()
ws = wb.active
ws.title = "罫線サンプル"
# ダミーデータ
for r in range(2, 12):
for c in range(2, 8):
ws.cell(row=r, column=c).value = (r - 1) * (c - 1)
# 範囲B2:G11に罫線
full_grid_border(ws, 2, 2, 11, 7, outline_style="thick", inside_style="thin")
wb.save("border_sample.xlsx")
print("saved: border_sample.xlsx")
saved: border_sample.xlsx
色と幅の設定
背景の塗りつぶし色、列幅、行の高さを整えることで、見やすい帳票を作れます。
塗りつぶし色
塗りつぶしはPatternFill
を使います。
fill_typeは”solid”、色はRGB(6桁)またはARGB(8桁)で指定します。
from openpyxl import Workbook
from openpyxl.styles import PatternFill
wb = Workbook()
ws = wb.active
ws.title = "塗りつぶし"
# ヘッダー行の背景色をゴールド(FFC000)に
fill_header = PatternFill(fill_type="solid", start_color="FFC000", end_color="FFC000")
for cell in ws["A1:E1"][0]:
cell.value = "Header"
cell.fill = fill_header
# 交互に淡いグレーを敷く
fill_gray = PatternFill(fill_type="solid", start_color="F2F2F2", end_color="F2F2F2")
for r in range(2, 12):
if r % 2 == 0:
for c in range(1, 6):
ws.cell(row=r, column=c).fill = fill_gray
wb.save("fill_demo.xlsx")
print("saved: fill_demo.xlsx")
saved: fill_demo.xlsx
start_colorとend_colorは同じ色にします(グラデーションではなくベタ塗り)。
列幅の変更
列幅はcolumn_dimensions["A"].width = 数値
で指定します。
数値はおおよそ「半角文字の表示数」を意味し、ピクセル単位ではありません。
from openpyxl import Workbook
wb = Workbook()
ws = wb.active
ws.title = "列幅"
# 列幅の設定(単位はおおよそ半角文字数)
ws.column_dimensions["A"].width = 6 # ID向け
ws.column_dimensions["B"].width = 24 # 商品名向け
ws.column_dimensions["C"].width = 10
ws.column_dimensions["D"].width = 10
ws.column_dimensions["E"].width = 12
wb.save("col_width_demo.xlsx")
print("saved: col_width_demo.xlsx")
saved: col_width_demo.xlsx
列幅はピクセルではないため、画面表示倍率やフォントによって見え方が変わります。
行の高さの変更
行の高さはrow_dimensions[行番号].height
でポイント値を設定します。
from openpyxl import Workbook
wb = Workbook()
ws = wb.active
ws.title = "行高"
# 1行目を見出しっぽく高くする
ws.row_dimensions[1].height = 28
# データ行は少し高めに
for r in range(2, 21):
ws.row_dimensions[r].height = 18
wb.save("row_height_demo.xlsx")
print("saved: row_height_demo.xlsx")
saved: row_height_demo.xlsx
コピペ用サンプル
フォント・塗り・罫線・列幅・行高を組み合わせた、見出し付きの表テンプレートです。
from openpyxl import Workbook
from openpyxl.styles import Font, PatternFill, Border, Side, Alignment
def full_grid_border(ws, min_row, min_col, max_row, max_col,
outline_style="thick", outline_color="000000",
inside_style="thin", inside_color="D9D9D9"):
out_side = Side(style=outline_style, color=outline_color)
in_side = Side(style=inside_style, color=inside_color)
for r in range(min_row, max_row + 1):
for c in range(min_col, max_col + 1):
top = out_side if r == min_row else in_side
bottom = out_side if r == max_row else in_side
left = out_side if c == min_col else in_side
right = out_side if c == max_col else in_side
ws.cell(row=r, column=c).border = Border(top=top, right=right, bottom=bottom, left=left)
wb = Workbook()
ws = wb.active
ws.title = "表テンプレ"
# ヘッダー
headers = ["ID", "商品名", "数量", "単価", "金額"]
for col, h in enumerate(headers, start=1):
ws.cell(row=1, column=col, value=h)
# 体裁(フォント・塗り)
head_font = Font(name="Meiryo", size=12, bold=True, color="FFFFFF")
head_fill = PatternFill(fill_type="solid", start_color="4F81BD", end_color="4F81BD") # ブルー
for cell in ws["A1:E1"][0]:
cell.font = head_font
cell.fill = head_fill
cell.alignment = Alignment(horizontal="center", vertical="center")
# 列幅
ws.column_dimensions["A"].width = 6
ws.column_dimensions["B"].width = 28
ws.column_dimensions["C"].width = 10
ws.column_dimensions["D"].width = 10
ws.column_dimensions["E"].width = 12
# 行高
ws.row_dimensions[1].height = 28
# ダミーデータ
data = [
(1, "りんご", 3, 120, 360),
(2, "バナナ", 5, 80, 400),
(3, "オレンジ", 2, 150, 300),
]
for r, row in enumerate(data, start=2):
for c, v in enumerate(row, start=1):
ws.cell(row=r, column=c, value=v)
# 罫線を表全体に
full_grid_border(ws, min_row=1, min_col=1, max_row=1 + len(data), max_col=5,
outline_style="thick", inside_style="thin")
wb.save("styled_table_demo.xlsx")
print("saved: styled_table_demo.xlsx")
saved: styled_table_demo.xlsx
このサンプルを土台に、フォントや色、罫線のスタイルを差し替えるだけで社内帳票の標準化が一気に進みます。
まとめ
openpyxlを使えば、Excelのフォント・罫線・塗りつぶし・列幅/行高といった見た目の調整をPythonコードで正確に再現できます。
記事内のスニペットはすべてコピペしてすぐ動作し、必要に応じて色やスタイル名を差し替えるだけで応用が利きます。
特に、Border
/Side
による外枠・内側の使い分け、PatternFill
での塗りと色の指定、column_dimensions
/row_dimensions
によるサイズ調整は実務で頻出です。
まずはテンプレに自分の標準書式を落とし込み、繰り返し作業を自動化していきましょう。