「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自体は、valueやfont, 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出力も、書き込み専用モードを使えばきっと実現できます。ぜひこのテクニックを活用して、あなたのデータ処理業務をさらに効率化してください。


コメント