Переход с python-docx
Office Oxide — drop-in замена для самых частых сценариев python-docx (извлечение текста, обход абзацев, чтение таблиц, find-and-replace) в 14 раз быстрее и с pass-rate на 3,8 п. п. выше на корпусе из 2 538 DOCX. Бонус: вам больше не нужно тащить отдельные библиотеки для .xlsx (openpyxl), .pptx (python-pptx) и legacy .doc (catdoc / antiword) — один pip install покрывает все шесть форматов.
Когда мигрировать
Переключайтесь, если делаете что-то из перечисленного:
- Извлекаете текст или Markdown из
.docxдля ингеста / RAG / поиска - Гоните find-and-replace-шаблоны по тысячам документов
- Читаете таблицы из договоров или отчётов
- Хотите заодно обрабатывать
.xlsx,.pptxили legacy без новых зависимостей
Останьтесь на python-docx, если делаете это и не готовы спускаться в формат-специфичный Rust-API:
- Строите сложный DOCX с нуля с custom-стилями и темами
- Нужны расширения python-docx (например,
docxcompose,python-docx-ng)
Установка
pip uninstall python-docx
pip install office-oxide
Имя дистрибутива в PyPI — office-oxide (через дефис), import — office_oxide (через подчёркивание).
Шпаргалка side-by-side
Plain text
python-docx
from docx import Document
doc = Document("report.docx")
text = "\n".join(p.text for p in doc.paragraphs)
office_oxide
from office_oxide import Document
with Document.open("report.docx") as doc:
text = doc.plain_text()
Один вызов метода, включая колонтитулы, и в ~14 раз быстрее.
Markdown / HTML
python-docx — встроенного Markdown / HTML нет; пришлось бы цеплять pandoc, mammoth или писать свой конвертер.
office_oxide
from office_oxide import Document
with Document.open("report.docx") as doc:
md = doc.to_markdown()
html = doc.to_html()
Обход абзацев
python-docx
from docx import Document
doc = Document("report.docx")
for p in doc.paragraphs:
print(p.style.name, p.text)
office_oxide (через IR)
from office_oxide import Document
with Document.open("report.docx") as doc:
ir = doc.to_ir()
for section in ir["sections"]:
for el in section["elements"]:
if el["kind"] == "Heading":
print(f"H{el['level']}", el["text"])
elif el["kind"] == "Paragraph":
print("P", " ".join(r["text"] for r in el["runs"]))
Обход таблиц
python-docx
from docx import Document
doc = Document("report.docx")
for table in doc.tables:
for row in table.rows:
cells = [cell.text for cell in row.cells]
print(cells)
office_oxide
from office_oxide import Document
with Document.open("report.docx") as doc:
ir = doc.to_ir()
for section in ir["sections"]:
for el in section["elements"]:
if el["kind"] == "Table":
for row in el["rows"]:
print(row)
Find and replace (шаблонизация)
python-docx — нет first-class-API; типичный паттерн — обход всех run и переписывание текста, что ломается на cross-run-совпадениях. Многие тащат docx-mailmerge или пишут хрупкие regex.
office_oxide
from office_oxide import EditableDocument
with EditableDocument.open("template.docx") as ed:
n = ed.replace_text("{{client_name}}", "Acme Corp")
print(f"{n} замен")
ed.save("filled.docx")
replace_text обрабатывает cross-run-совпадения прозрачно и сохраняет все нетронутые OPC-части (изображения, диаграммы, стили).
Чтение core properties
python-docx
from docx import Document
doc = Document("report.docx")
print(doc.core_properties.author)
print(doc.core_properties.modified)
office_oxide
from office_oxide import Document
with Document.open("report.docx") as doc:
props = doc.as_docx().core_properties()
print(props.author)
print(props.modified)
Что office_oxide пока не выставляет
Унифицированный EditableDocument покрывает шаблонизацию. Для богатее DOCX-конструкции — добавление абзацев, программная сборка таблиц, применение именованных стилей — спускайтесь в формат-специфичный модуль:
from office_oxide.docx import DocxBuilder
builder = DocxBuilder()
builder.add_heading("Q4-отчёт", level=1)
builder.add_paragraph("Выручка выросла на 18%.")
builder.save("report.docx")
Или генерируйте из IR через create_from_ir(ir, "docx", "report.docx"). См. Сборка из IR.
Производительность
Тот же корпус из 2 538 файлов, single-thread:
| Библиотека | Среднее | p99 | Pass rate |
|---|---|---|---|
| office_oxide | 0,8 мс | 3,9 мс | 98,9% |
| python-docx | 11,8 мс | 98 мс | 95,1% |
Ингест миллиона документов, который у python-docx занимает 3 ч 16 мин, на том же железе у office_oxide заканчивается за 14 минут.
Смотрите также
- Переход с openpyxl — XLSX
- Переход с python-pptx — PPTX
- Бенчмарки производительности — полные числа
- Обзор редактирования — что сохраняет
EditableDocument