Библиотека Office Oxide для Python — быстрый старт
office_oxide — самая быстрая Python-библиотека для документов Office. Ядро на чистом Rust, удобный Python API, никаких зависимостей времени выполнения. Чтение DOCX, XLSX, PPTX (а также старых DOC, XLS, PPT) занимает меньше миллисекунды — в 8–100 раз быстрее, чем python-docx, openpyxl, python-pptx.
Установка
pip install office-oxide
Готовые wheel-пакеты опубликованы для CPython 3.8–3.14 на Linux, macOS и Windows. Имя дистрибутива в PyPI — office-oxide (через дефис), имя для импорта — 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 определяет формат по расширению (и проверяет magic-байтами). Принимает 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() # вложенный словарь (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 обходит элементы <w:t> в DOCX и <a:t> на каждом слайде PPTX, возвращает количество замен.
Запись ячеек 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 нумеруется с нуля; cell_ref — стандартная нотация (A1, AA12).
Формат-независимый IR
doc.to_ir() возвращает вложенный словарь (dict), отражающий Rust-структуру DocumentIR: секции из заголовков, абзацев, таблиц, списков и изображений. Удобно для конвейеров и подачи структурированного контекста в 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 избавляет от временных файлов в serverless и стриминговых сценариях:
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 одной функцией
Ошибки
Ошибки парсинга и ввода-вывода выбрасывают OfficeOxideError. Ошибки ввода-вывода в save_as оборачиваются в 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. |
| Проблемы с Unicode на Windows | Используйте pathlib.Path вместо байтовых путей; Document.open сам разберётся с кодировкой. |
Смотрите также
- Переход с python-docx — drop-in замена, в 14 раз быстрее
- Переход с openpyxl — то же покрытие XLSX, в 18 раз быстрее
- Переход с python-pptx — PPTX в 46 раз быстрее
- Бенчмарки производительности — полные цифры по 6 062 файлам
- Пакет на PyPI