Python Office ライブラリ — クイックスタート
office_oxide は Office ドキュメントを扱う Python ライブラリの中で最速です。純粋 Rust コア、Python らしい API、ランタイム依存ゼロ。DOCX、XLSX、PPTX(およびレガシーな DOC、XLS、PPT)を 1 ミリ秒未満で読み込め、python-docx、openpyxl、python-pptx の 8 〜 100 倍高速です。
インストール
pip install office-oxide
CPython 3.8 〜 3.14 の wheel が Linux、macOS、Windows 向けに公開されています。PyPI 上のパッケージ名は office-oxide(ハイフン)、import 名は office_oxide(アンダースコア)です。
ドキュメントを読み込む
from office_oxide import Document
with Document.open("report.docx") as doc:
print(doc.plain_text())
ワンショットヘルパーも使えます。
import office_oxide
print(office_oxide.extract_text("report.docx"))
コア API
Document.open は拡張子からフォーマットを判定し(マジックバイトでも検証)、str、bytes、os.PathLike を受け付けます。コンテキストマネージャとして使えば、ネイティブメモリが確実に解放されます。
from pathlib import Path
from office_oxide import Document
with Document.open(Path("data/deck.pptx")) as doc:
print(doc.format) # "pptx"
print(doc.plain_text()) # str
print(doc.to_markdown()) # str — GitHub Flavored Markdown
print(doc.to_html()) # str — セマンティックな HTML
ir = doc.to_ir() # ネストした dict(DocumentIR)
doc.save_as("deck.docx") # 古い PPT → PPTX への変換も可能
ファイルがディスク上にない場合はバイト列から開きます。
data = open("report.xlsx", "rb").read()
with Document.from_bytes(data, "xlsx") as doc:
print(doc.plain_text())
モジュールレベルのショートカット:
import office_oxide
office_oxide.extract_text("file.docx") # → str
office_oxide.to_markdown("file.pptx") # → str
office_oxide.to_html("file.xlsx") # → str
office_oxide.version() # → "0.1.0"
編集
EditableDocument は、変更されていない OPC パーツ(画像、グラフ、スタイル、リレーションシップ)を保存時にすべて温存します。対応形式は DOCX、XLSX、PPTX のみです。
from office_oxide import EditableDocument
with EditableDocument.open("template.docx") as ed:
n = ed.replace_text("{{name}}", "Alice")
print(f"{n} 件置換")
ed.save("out.docx")
DOCX / PPTX のテキスト置換
from office_oxide import EditableDocument
with EditableDocument.open("slides.pptx") as ed:
ed.replace_text("Q3", "Q4")
ed.replace_text("2024", "2025")
ed.save("slides_q4.pptx")
replace_text は DOCX の <w:t>、PPTX の <a:t> を走査し、置換件数を返します。
XLSX セルへの書き込み
from office_oxide import EditableDocument
with EditableDocument.open("budget.xlsx") as ed:
ed.set_cell(0, "A1", "Total") # 文字列
ed.set_cell(0, "B1", 42.5) # 数値(int も可)
ed.set_cell(0, "C1", True) # 真偽値
ed.set_cell(0, "D1", None) # 空セル
ed.save("budget.xlsx")
sheet_index は 0 始まり、cell_ref は標準の表計算記法(A1、AA12)です。
フォーマット非依存の IR
doc.to_ir() は Rust の DocumentIR をそのまま反映したネストした dict を返します — 見出し、段落、テーブル、リスト、画像のセクション群です。パイプラインや LLM への構造化コンテキスト供給に便利です。
ir = doc.to_ir()
for section in ir["sections"]:
print(section.get("title"))
for el in section["elements"]:
kind = el["kind"] # "Heading" | "Paragraph" | "Table" | "List" | ...
バイト列ベースのパイプライン
from_bytes を使うと、サーバーレス・ストリーミングのワークフローで一時ファイルを作らずに済みます。
import requests
from office_oxide import Document
data = requests.get("https://example.com/doc.docx").content
with Document.from_bytes(data, "docx") as doc:
print(doc.to_markdown())
レガシーフォーマット
DOC、XLS、PPT も同じ API で扱えます。拡張子からレガシー CFB パーサが自動選択され、save_as で透過的にモダンな OOXML へ変換できます。
with Document.open("legacy.doc") as doc:
print(doc.plain_text())
doc.save_as("legacy.docx") # DOC → DOCX を 1 行で
エラー
パース失敗・IO 失敗は OfficeOxideError を送出します。save_as の IO 失敗は IOError でラップされます。
from office_oxide import Document, OfficeOxideError
try:
with Document.open("weird.file") as doc:
print(doc.plain_text())
except OfficeOxideError as e:
print(f"office_oxide 失敗: {e}")
except FileNotFoundError:
print("ファイルが見つかりません")
トラブルシューティング
| 症状 | 原因 |
|---|---|
OfficeOxideError: unsupported format: "" |
パスに拡張子がありません — Document.from_bytes(data, "docx") を使ってください。 |
RuntimeError: Document is closed |
with ブロックを抜けた後にハンドルを参照しています。新しく開き直してください。 |
ImportError: _native |
wheel がプラットフォームに合っていません。pip install --force-reinstall office-oxide。 |
| レガシー DOC が文字化け | ファイルが暗号化されている可能性があります(Word 97 RC4)。office_oxide は復号しません — 先に LibreOffice で復号してください。 |
| Windows での Unicode 問題 | バイト列パスではなく pathlib.Path を使ってください。Document.open がプラットフォームのエンコーディングを処理します。 |
関連項目
- python-docx からの移行 — ドロップイン置換、14 倍高速
- openpyxl からの移行 — XLSX のカバレッジは同等、18 倍高速
- python-pptx からの移行 — PPTX で 46 倍高速
- パフォーマンスベンチマーク — 6,062 ファイルの計測結果
- パッケージ: PyPI