openpyxlの書き込み専用モードとWriteOnlyCellを徹底解説!メモリ効率を最大化するExcel術

openpyxl

「Pythonで大量のデータをExcelに出力しようとすると、メモリを大量に消費して処理が遅くなったり、最悪の場合は止まってしまう…」

大規模なデータ処理において、メモリ効率は避けて通れない課題です。openpyxlは非常に便利なライブラリですが、通常の方法では数百万行ものデータを扱うのは現実的ではありません。

しかし、ご安心ください。openpyxlには、メモリ効率を劇的に改善するための**「書き込み専用モード」と、その心臓部であるWriteOnlyCell**が用意されています。

この記事では、メモリ効率を最大化するための切り札、openpyxlの書き込み専用モードとWriteOnlyCellの仕組みや使い方を、初心者にも分かりやすく、実践的なコードを交えて徹底解説します。

はじめに:Pythonで数百万行のレポート作成、メモリは足りていますか?

openpyxlで通常モードでExcelファイルを作成すると、作成したすべてのセルオブジェクトがメモリ上に保持されます。数千行程度なら問題ありませんが、数十万、数百万行となると、あっという間に利用可能なメモリを使い果たしてしまいます。

この問題を解決するのが、書き込み専用(Write-Only)モードです。このモードでは、一度書き込んだセルの情報はメモリから破棄されるため、ほぼ無限の行数を持つExcelファイルを、ごくわずかなメモリで作成できるのです。

openpyxlの書き込み専用モードとは?

書き込み専用モードは、その名の通り、データをExcelシートに書き込む(追記していく)ことだけに特化した動作モードです。

最大のメリットは、なんといっても超省メモリであること。ws.append()で一行データを書き込むと、そのデータはすぐにXMLファイルに書き出され、メモリ上には保持されません。これにより、PCのスペックに依存せず、非常に大規模なExcelファイルを生成できます。

書き込み専用モードを使うには、ワークブックを作成する際にwrite_only=Trueフラグを指定します。

import openpyxl

# 書き込み専用モードでワークブックを作成
wb = openpyxl.Workbook(write_only=True)

# シートを作成(このシートはWriteOnlyWorksheetになる)
ws = wb.create_sheet("大容量データシート")

print(type(ws))

実行結果:

<class 'openpyxl.worksheet.write_only.WriteOnlyWorksheet'>Code language: HTML, XML (xml)

WriteOnlyCellオブジェクトの正体

書き込み専用モードのシートに行を追加する際、内部的に使われるのがWriteOnlyCellオブジェクトです。

通常のCellオブジェクトとの決定的な違い

通常のCellオブジェクトがワークシート内に「実体」として存在し続けるのに対し、WriteOnlyCellデータを書き込むための一時的なオブジェクトにすぎません。ws.append()に渡された値やWriteOnlyCellは、書き込み処理が終わるとすぐにメモリから解放されます。

この「使い捨て」の性質こそが、書き込み専用モードが省メモリである理由です。そのため、一度書き込んだセルに後からアクセスして値を読み取ったり、変更したりすることはできません。

WriteOnlyCell自体は、valuefont, fillといったスタイル属性を持つことができますが、それらはws.append()に渡される瞬間にのみ意味を持ちます。

実践!書き込み専用モードでデータを追記するコード例

書き込み専用モードでのデータ追加は、ws.append()メソッドを使うのが最も簡単で効率的です。

データを一行ずつ追加する

リストやタプル形式でデータを用意し、append()に渡すだけで、シートの最終行にデータが追記されます。

import openpyxl
from openpyxl.styles import Font, Alignment

# 書き込み専用モードでワークブックを作成
wb = openpyxl.Workbook(write_only=True)
ws = wb.create_sheet("売上レポート")

# ヘッダー行を書き込む
header = ["商品ID", "商品名", "単価", "数量", "合計金額"]
ws.append(header)

# サンプルデータ(実際にはDBなどから大量のデータを取得)
sales_data = [
    (101, "商品A", 500, 10, 5000),
    (102, "商品B", 800, 5, 4000),
    (103, "商品C", 300, 20, 6000),
    # ... ここに数百万行のデータが続く想定
]

# データを一行ずつ追記
for row_data in sales_data:
    ws.append(row_data)

# ファイルを保存
wb.save("sales_report_large.xlsx")

print("大容量のExcelファイルを作成しました。")

WriteOnlyCellを使ってスタイルを適用する

ws.append()には、値のリストだけでなく、WriteOnlyCellオブジェクトのリストを渡すことも可能です。これにより、セルごとにスタイルを指定できます。

from openpyxl.cell import WriteOnlyCell
from openpyxl.styles import Font

# ... (前のコードの続き) ...
ws_styled = wb.create_sheet("スタイル付きレポート")

# ヘッダー用のスタイル
header_font = Font(bold=True, color="FFFFFF")

# WriteOnlyCellを使ってヘッダーを作成
header_cells = []
for col_name in ["商品ID", "商品名", "金額"]:
    cell = WriteOnlyCell(ws_styled, value=col_name)
    cell.font = header_font
    header_cells.append(cell)
ws_styled.append(header_cells)

# ... データ行の追加 ...

wb.save("sales_report_styled.xlsx")

書き込み専用モードの重要な制約と注意点

非常に強力な書き込み専用モードですが、いくつかの重要な制約があります。

  • 前方追記のみ: ws.append()による追記しかできず、特定のセル(例:’A5’)を直接指定して書き込むことはできません。
  • 読み取り・編集不可: 一度書き込んだデータは、そのプログラム内で再度読み取ったり、上書きしたりすることはできません。
  • 幅・高さの調整不可: 列の幅や行の高さを自動調整したり、明示的に指定したりすることはできません。

これらの制約から、書き込み専用モードは「一方通行のデータ出力」に特化した機能であることがわかります。

通常モードと書き込み専用モードの使い分け

どちらのモードを使うべきか、目的を明確にして判断しましょう。

書き込み専用モードが最適なケース

✅ 数十万〜数百万行のログデータやDBのテーブル内容をExcelに出力する ✅ メモリが限られた環境(Webサーバーなど)でExcelファイルを生成する ✅ とにかく高速に、大量のデータをExcel形式でダンプしたい場合

通常モードを選ぶべきケース

✅ 既存のExcelファイルを読み込んで編集・加工する場合 ✅ 複雑な書式設定、条件付き書式、グラフ作成などが必要な場合 ✅ 作成するファイルの行数が比較的小さい(数万行程度まで)場合

まとめ

今回は、openpyxlでメモリ効率を最大化しながら巨大なExcelファイルを作成する「書き込み専用モード」とWriteOnlyCellについて解説しました。

  • 巨大なExcelファイル生成には Workbook(write_only=True) を使う
  • 書き込み専用モードでは、超省メモリでデータを追記できる
  • データ追加は ws.append() を使い、一度書き込んだセルには再アクセスできない
  • WriteOnlyCell オブジェクトを使えば、追記時にスタイルも指定可能
  • ログ出力やデータダンプなど、一方通行の大量書き込みに最適

メモリ不足で諦めていた大量データのExcel出力も、書き込み専用モードを使えばきっと実現できます。ぜひこのテクニックを活用して、あなたのデータ処理業務をさらに効率化してください。

コメント

タイトルとURLをコピーしました