【完全ガイド】openpyxlでExcelを自動作成

ソニック

書式・色・グラフまで完璧

「毎月の請求書作成に何時間もかかる」「Excelに装飾を入れる作業を自動化したい」

そんな悩みを解決するのが、Pythonのライブラリ「openpyxl(オープンパイエックスエル)」です。

pandasがデータの集計に強い一方、openpyxlは「Excel書式の自動化」に特化しています。セルの色、フォント、罫線、数式、グラフまで――Excelで人が手作業でやることを、すべてコードで再現できます。

この記事では、openpyxlを使った業務Excel自動化を、コピペで使えるコード付きで完全解説します。

第1章|なぜopenpyxlなのか

目次

pandasとの違い

pandasとopenpyxlは、Excelを扱うライブラリとして似ていますが、得意分野が異なります。

用途pandasopenpyxl
データ集計・分析◎ 最適
書式設定(色・罫線)✗ 不可◎ 最適
数式の自動入力◎ 最適
グラフの自動作成◎ 最適
既存Excelの加工◎ 最適

「データの集計はpandas、装飾はopenpyxl」と使い分けるのが理想です。両者は一緒に使うことも多く、組み合わせで強力なExcel自動化が実現できます。

openpyxlが活躍する業務シーン

  • 毎月の請求書・納品書を自動作成
  • 見栄えの良い月次レポートを自動生成
  • 既存Excelファイルに書式・グラフを追加
  • テンプレートExcelに動的にデータを流し込む
  • 複雑な数式を含むExcelファイルを大量生成

第2章|環境準備(uv環境前提)

この記事は、uv環境でPythonを使う前提で進めます。まだuvをインストールしていない方は、別記事「【完全版】uv入門」をご覧ください。

必要なライブラリ

# openpyxlのみインストール
# Excelの読み書き・書式設定・グラフ作成すべてに対応
uv add openpyxl

第3章|基本|Excelファイルの作成と書き込み

新しいExcelファイルを作る

# openpyxlを読み込む
from openpyxl import Workbook

# 新しいワークブック(Excelファイル)を作成
wb = Workbook()

# アクティブなシート(最初に開かれるシート)を取得
ws = wb.active

# シート名を変更
ws.title = "売上データ"

# A1セルに値を書き込む
ws["A1"] = "商品名"
ws["B1"] = "売上"

# 2行目以降にデータを書き込む
ws["A2"] = "商品A"
ws["B2"] = 15000
ws["A3"] = "商品B"
ws["B3"] = 8000

# Excelファイルとして保存
wb.save("売上データ.xlsx")
print("ファイルを作成しました")

既存のExcelファイルを開く

from openpyxl import load_workbook

# 既存のExcelファイルを読み込む
wb = load_workbook("売上データ.xlsx")

# シートを取得
ws = wb["売上データ"]

# セルの値を読み取る
print(ws["A2"].value)  # 商品A
print(ws["B2"].value)  # 15000

# 値を書き換える
ws["B2"] = 18000

# 保存(上書き)
wb.save("売上データ.xlsx")

複数セルへの一括書き込み

from openpyxl import Workbook

wb = Workbook()
ws = wb.active

# ヘッダー行を追加
ws.append(["商品名", "売上", "数量"])

# データ行を追加(複数行)
data = [
    ["商品A", 15000, 10],
    ["商品B", 8000, 5],
    ["商品C", 12000, 8],
]

# appendで1行ずつ追加
for row in data:
    ws.append(row)

wb.save("商品データ.xlsx")
print("3行追加しました")

第4章|書式設定|セルの色・フォント・罫線

openpyxlの真骨頂は、Excelの書式設定をすべてコードで自動化できること。プロが作ったような見栄えのExcelが作れます。

セルの背景色を設定

from openpyxl import Workbook
from openpyxl.styles import PatternFill

wb = Workbook()
ws = wb.active
ws["A1"] = "見出し"

# 背景色の塗りつぶしを設定
# fgColor="0066FF" は青色(マイペースブログカラー)
# fill_type="solid" でベタ塗り
fill = PatternFill(fgColor="0066FF", fill_type="solid")
ws["A1"].fill = fill

wb.save("色付き.xlsx")

フォント設定(色・太字・サイズ)

from openpyxl import Workbook
from openpyxl.styles import Font

wb = Workbook()
ws = wb.active
ws["A1"] = "重要なお知らせ"

# フォントを設定
# bold=True で太字
# size=14 でフォントサイズ14
# color="FFFFFF" で白文字
# name="Meiryo" で日本語フォント(Windows)
font = Font(name="Meiryo", size=14, bold=True, color="FFFFFF")
ws["A1"].font = font

wb.save("フォント設定.xlsx")

罫線を引く

from openpyxl import Workbook
from openpyxl.styles import Border, Side

wb = Workbook()
ws = wb.active
ws["A1"] = "枠付きのセル"

# 罫線のスタイルを定義
# style="thin" は細い実線
thin = Side(style="thin", color="000000")

# 4辺すべてに罫線を引く
border = Border(top=thin, bottom=thin, left=thin, right=thin)
ws["A1"].border = border

wb.save("罫線付き.xlsx")

セルの配置を設定

from openpyxl import Workbook
from openpyxl.styles import Alignment

wb = Workbook()
ws = wb.active
ws["A1"] = "中央寄せ"

# 配置を設定
# horizontal="center" は横方向中央
# vertical="center" は縦方向中央
align = Alignment(horizontal="center", vertical="center")
ws["A1"].alignment = align

wb.save("配置.xlsx")

列幅・行高さを変更

from openpyxl import Workbook

wb = Workbook()
ws = wb.active

# 列幅を設定(A列の幅を20に)
ws.column_dimensions["A"].width = 20
ws.column_dimensions["B"].width = 15

# 行高さを設定(1行目を30に)
ws.row_dimensions[1].height = 30

ws["A1"] = "幅広い列"
wb.save("サイズ調整.xlsx")

第5章|数式とSUMの自動入力

openpyxlでは、Excelの数式(SUM、AVERAGE、IFなど)も自動で入力できます。

SUMで合計を自動計算

from openpyxl import Workbook

wb = Workbook()
ws = wb.active

# データを入力
ws["A1"] = "商品名"
ws["B1"] = "売上"
ws["A2"] = "商品A"
ws["B2"] = 15000
ws["A3"] = "商品B"
ws["B3"] = 8000
ws["A4"] = "商品C"
ws["B4"] = 12000

# 合計行を追加
ws["A5"] = "合計"
# 数式は文字列として入力(=で始める)
ws["B5"] = "=SUM(B2:B4)"

wb.save("合計付き.xlsx")
print("合計付きExcelを作成しました")

AVERAGEで平均を計算

from openpyxl import Workbook

wb = Workbook()
ws = wb.active

# データ
ws["A1"] = "店舗"
ws["B1"] = "売上"
ws.append(["東京店", 150000])
ws.append(["大阪店", 120000])
ws.append(["名古屋店", 100000])

# 平均を計算
ws["A5"] = "平均"
ws["B5"] = "=AVERAGE(B2:B4)"

wb.save("平均付き.xlsx")

IFで条件分岐

from openpyxl import Workbook

wb = Workbook()
ws = wb.active

ws["A1"] = "売上"
ws["B1"] = "判定"
ws["A2"] = 50000
ws["A3"] = 120000

# IF関数:売上が100000以上なら「達成」、それ以外は「未達」
ws["B2"] = '=IF(A2>=100000,"達成","未達")'
ws["B3"] = '=IF(A3>=100000,"達成","未達")'

wb.save("条件付き.xlsx")

第6章|グラフの自動作成

openpyxlを使えば、データだけでなく**グラフも自動で作成**できます。月次レポートの自動化に必須の機能です。

棒グラフを作成

from openpyxl import Workbook
from openpyxl.chart import BarChart, Reference

wb = Workbook()
ws = wb.active

# データを入力
ws.append(["月", "売上"])
ws.append(["1月", 120])
ws.append(["2月", 150])
ws.append(["3月", 180])
ws.append(["4月", 165])
ws.append(["5月", 200])

# 棒グラフのオブジェクトを作成
chart = BarChart()
chart.title = "月別売上推移"
chart.y_axis.title = "売上(万円)"
chart.x_axis.title = "月"

# データ範囲を指定(B1:B6、ヘッダー含む)
data = Reference(ws, min_col=2, min_row=1, max_row=6, max_col=2)
# カテゴリ(X軸ラベル)の範囲を指定(A2:A6)
categories = Reference(ws, min_col=1, min_row=2, max_row=6)

chart.add_data(data, titles_from_data=True)
chart.set_categories(categories)

# グラフをD2セルから配置
ws.add_chart(chart, "D2")

wb.save("グラフ付き.xlsx")
print("グラフ付きExcelを作成しました")

折れ線グラフ・円グラフ

# 折れ線グラフ
from openpyxl.chart import LineChart
chart = LineChart()

# 円グラフ
from openpyxl.chart import PieChart
chart = PieChart()

# 使い方は BarChart と同じ
# add_data() と set_categories() でデータをセット

第7章|実務で使える完成スクリプト(請求書テンプレ)

実務でそのまま使える、月次請求書の自動作成スクリプトを紹介します。

月次請求書の自動作成

from openpyxl import Workbook
from openpyxl.styles import PatternFill, Font, Border, Side, Alignment
from datetime import datetime

def create_invoice(customer_name, items, save_path):
    """
    請求書を自動作成する関数
    customer_name: 顧客名
    items: [(商品名, 単価, 数量), ...] のリスト
    save_path: 保存先パス
    """
    wb = Workbook()
    ws = wb.active
    ws.title = "請求書"
    
    # === タイトル ===
    ws["A1"] = "請 求 書"
    ws["A1"].font = Font(name="Meiryo", size=20, bold=True, color="003D99")
    ws["A1"].alignment = Alignment(horizontal="center")
    # A1〜D1を結合
    ws.merge_cells("A1:D1")
    
    # === 顧客名 ===
    ws["A3"] = f"{customer_name} 御中"
    ws["A3"].font = Font(name="Meiryo", size=14, bold=True)
    
    # === 発行日 ===
    ws["D3"] = f"発行日: {datetime.now().strftime('%Y年%m月%d日')}"
    ws["D3"].alignment = Alignment(horizontal="right")
    
    # === ヘッダー(5行目) ===
    headers = ["品名", "単価", "数量", "金額"]
    for i, header in enumerate(headers, start=1):
        cell = ws.cell(row=5, column=i, value=header)
        # ヘッダー装飾
        cell.fill = PatternFill(fgColor="0066FF", fill_type="solid")
        cell.font = Font(name="Meiryo", color="FFFFFF", bold=True)
        cell.alignment = Alignment(horizontal="center")
    
    # === データ行 ===
    thin = Side(style="thin", color="000000")
    border = Border(top=thin, bottom=thin, left=thin, right=thin)
    
    for i, (name, price, qty) in enumerate(items, start=6):
        ws.cell(row=i, column=1, value=name)
        ws.cell(row=i, column=2, value=price)
        ws.cell(row=i, column=3, value=qty)
        # 金額は数式で自動計算
        ws.cell(row=i, column=4, value=f"=B{i}*C{i}")
        
        # 全セルに罫線
        for col in range(1, 5):
            ws.cell(row=i, column=col).border = border
    
    # === 合計行 ===
    total_row = 6 + len(items)
    ws.cell(row=total_row, column=3, value="合計").font = Font(bold=True)
    ws.cell(row=total_row, column=4, value=f"=SUM(D6:D{total_row-1})").font = Font(bold=True)
    
    # === 列幅調整 ===
    ws.column_dimensions["A"].width = 25
    ws.column_dimensions["B"].width = 12
    ws.column_dimensions["C"].width = 8
    ws.column_dimensions["D"].width = 15
    
    # === 保存 ===
    wb.save(save_path)
    print(f"請求書を作成しました:{save_path}")

# === 使用例 ===
items = [
    ("商品A", 1000, 5),
    ("商品B", 2000, 3),
    ("商品C", 500, 10),
]
create_invoice("株式会社サンプル", items, "請求書_202604.xlsx")

このスクリプトを使えば、顧客名と商品情報を変えるだけで、毎月の請求書が自動で生成されます。

拡張アイデア

  • CSVから顧客リストを読み込み、全顧客分の請求書を一括生成
  • PDFに変換して、メールで自動送信
  • Googleドライブにアップロードして共有
  • 会社ロゴ画像も埋め込み(add_image機能)

第8章|つまずき対処&まとめ

よくあるトラブル

トラブル1:「Excel ファイルが破損しています」と出る

原因:

openpyxlで保存する際、まだExcelで開いている状態だった。

対処:

Excelファイルを完全に閉じてから、Pythonスクリプトを実行してください。

トラブル2:数式が文字列として表示される

原因:

数式の先頭に「=」を付け忘れている。

対処:

# NG:これは文字列として表示される
ws["B5"] = "SUM(B2:B4)"

# OK:=を先頭につける
ws["B5"] = "=SUM(B2:B4)"

トラブル3:背景色が反映されない

原因:

fill_typeの指定漏れ、または色コードが間違っている。

対処:

# fill_type="solid" を必ず指定する
fill = PatternFill(fgColor="0066FF", fill_type="solid")

# 色コードは「#」なしの6桁HEX
# OK: "0066FF"
# NG: "#0066FF"

トラブル4:日本語が文字化けする

対処:

# Fontでname="Meiryo"を指定する(Windows)
from openpyxl.styles import Font
font = Font(name="Meiryo", size=11)
ws["A1"].font = font

# Macの場合は "Hiragino Sans" など

この記事のまとめ

  1. openpyxlはExcelの「書式設定」「数式」「グラフ」を自動化する強力ライブラリ
  2. pandasと使い分けると業務自動化の幅が一気に広がる
  3. セルの色・フォント・罫線・配置をすべてコードで制御可能
  4. SUM、AVERAGE、IFなどの数式も自動入力できる
  5. BarChart、LineChart、PieChartでグラフも自動生成
  6. テンプレ化すれば毎月の請求書作成が完全自動化

FAQ

Q1. pandasと両方使う必要はありますか?

用途次第ですが、両方使うのが理想です。データ集計はpandas、書式設定はopenpyxlと役割分担できます。両方を使うことで、Excel業務の自動化範囲が大きく広がります。

Q2. 既存のExcelテンプレートに値を流し込むことはできますか?

可能です。load_workbookで既存ファイルを開き、必要なセルに値を書き込み、別名で保存すれば、テンプレートを保ったまま新しいファイルを作成できます。

Q3. 結合セルの扱いはどうすればいいですか?

ws.merge_cells(“A1:D1”)で結合、ws.unmerge_cells()で解除できます。結合された範囲では、左上のセルにだけ値を書き込みます。

Q4. Excelの画像(ロゴ等)を埋め込めますか?

可能です。from openpyxl.drawing.image import Imageでインポート後、img = Image(“logo.png”)、ws.add_image(img, “A1”)のようにセル位置を指定して配置します。

Q5. xlsmマクロ付きファイルにも対応していますか?

openpyxlは.xlsx形式が基本で、マクロ付きの.xlsmファイルの保存には keep_vba=True オプションが必要です。ただし、xlwingsという別ライブラリの方がマクロ連携に強いです。

Excel自動化の世界へ

openpyxlを使えば、Excelで何時間もかかっていた装飾作業も、毎月の定型レポート作成も、コード1本で自動化できます。

pandasと組み合わせれば、データ処理から美しいレポート出力まで、すべての工程を自動化できる――それが業務効率化の理想形です。

最新の解説記事は、新着記事から順次公開しています。X(旧Twitter)でも更新情報を発信していますので、ぜひフォローしてください。

この記事を書いた人

ソニック|バックオフィス出身の業務効率化ブロガー。データサイエンス業務でクライアントへのレポート納品にopenpyxlを日常的に活用中。リアルな実体験をもとにしたノウハウを発信中。

→ 詳しいプロフィールはこちら→ はじめての方へ

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

CAPTCHA


目次