Skip to content

Migrar desde python-docx

Office Oxide es una sustitución directa para los casos de uso más comunes de python-docx — extracción de texto, iteración de párrafos, lectura de tablas, find-and-replace — con 14× la velocidad y una tasa de éxito 3,8 puntos porcentuales superior sobre un corpus de 2.538 DOCX. Bonus: dejas de empaquetar librerías distintas para .xlsx (openpyxl), .pptx (python-pptx) y DOC heredado (catdoc / antiword) — un pip install cubre los seis formatos.

Cuándo migrar

Cambia si haces alguna de estas:

  • Extraer texto o Markdown de .docx para ingesta / RAG / búsqueda
  • Correr plantillas de find-and-replace sobre miles de documentos
  • Leer tablas de contratos o informes
  • Querer también procesar .xlsx, .pptx o formatos heredados sin añadir más dependencias

Quédate en python-docx si haces esto y no estás listo para bajar a la API Rust específica de formato:

  • Construir DOCX complejos desde cero con estilos y temas personalizados
  • Necesitas librerías de extensión de python-docx (p. ej. docxcompose, python-docx-ng)

Instalación

pip uninstall python-docx
pip install office-oxide

El nombre del paquete en PyPI es office-oxide (con guion); el import es office_oxide (con guion bajo).

Cheat sheet en paralelo

Texto plano

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()

Una sola llamada, incluye cabeceras y pies, ~14× más rápida.

Markdown / HTML

python-docx — sin Markdown / HTML integrado; tendrías que tirar de pandoc, mammoth o escribir un convertidor a mano.

office_oxide

from office_oxide import Document

with Document.open("report.docx") as doc:
    md   = doc.to_markdown()
    html = doc.to_html()

Iterar párrafos

python-docx

from docx import Document

doc = Document("report.docx")
for p in doc.paragraphs:
    print(p.style.name, p.text)

office_oxide (vía 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"]))

Iterar tablas

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 (plantillas)

python-docx — sin API de primera clase; el patrón habitual es recorrer cada run y reescribir texto, lo que se rompe con matches cross-run. La mayoría tira de docx-mailmerge o de regex frágiles.

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} reemplazos")
    ed.save("filled.docx")

replace_text maneja matches cross-run de manera transparente y conserva todas las partes OPC sin tocar (imágenes, gráficos, estilos).

Leer 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)

Lo que office_oxide no expone actualmente

El EditableDocument unificado cubre el caso de templating. Para construcción más rica de DOCX — añadir párrafos, montar tablas programáticamente, aplicar estilos nombrados — entra al módulo específico del formato:

from office_oxide.docx import DocxBuilder

builder = DocxBuilder()
builder.add_heading("Informe Q4", level=1)
builder.add_paragraph("Los ingresos crecieron 18%.")
builder.save("report.docx")

O genera desde el IR con create_from_ir(ir, "docx", "report.docx"). Ver Construir desde IR.

Rendimiento

Mismo corpus de 2.538 archivos, single-thread:

Librería Media p99 Tasa de éxito
office_oxide 0,8 ms 3,9 ms 98,9%
python-docx 11,8 ms 98 ms 95,1%

Una ingesta de un millón de documentos que con python-docx tarda 3 h 16 min acaba en 14 minutos con office_oxide en el mismo hardware.

Véase también