Skip to content

Biblioteca Office para Python — Inicio Rápido

office_oxide es la biblioteca Python más rápida para documentos de Office. Núcleo en Rust puro, API natural en Python, sin dependencias en tiempo de ejecución. Lee DOCX, XLSX, PPTX (y los formatos heredados DOC, XLS, PPT) en menos de un milisegundo — de 8 a 100 veces más rápido que python-docx, openpyxl y python-pptx.

Instalación

pip install office-oxide

Las wheels están publicadas para CPython 3.8–3.14 en Linux, macOS y Windows. El nombre del paquete en PyPI es office-oxide (con guion); el de import es office_oxide (con guion bajo).

Leer un documento

from office_oxide import Document

with Document.open("report.docx") as doc:
    print(doc.plain_text())

O la función auxiliar de un solo paso:

import office_oxide
print(office_oxide.extract_text("report.docx"))

API principal

Document.open detecta el formato a partir de la extensión (y lo confirma con magic bytes). Acepta str, bytes o cualquier os.PathLike. Úsalo como gestor de contexto para que la memoria nativa se libere de forma determinista.

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 — Markdown estilo GitHub
    print(doc.to_html())        # str — HTML semántico
    ir = doc.to_ir()            # dict anidado (DocumentIR)

    doc.save_as("deck.docx")    # también funciona PPT heredado → PPTX

Cuando el archivo no está en disco, ábrelo desde bytes:

data = open("report.xlsx", "rb").read()
with Document.from_bytes(data, "xlsx") as doc:
    print(doc.plain_text())

Atajos a nivel de módulo:

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"

Edición

EditableDocument conserva tal cual todas las partes OPC sin modificar (imágenes, gráficos, estilos, relaciones) al guardar. Solo DOCX, XLSX y PPTX.

from office_oxide import EditableDocument

with EditableDocument.open("template.docx") as ed:
    n = ed.replace_text("{{name}}", "Alice")
    print(f"{n} reemplazos")
    ed.save("out.docx")

Reemplazar texto en 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 recorre los elementos <w:t> en DOCX y <a:t> en cada diapositiva del PPTX. Devuelve la cantidad de reemplazos.

Escribir celdas XLSX

from office_oxide import EditableDocument

with EditableDocument.open("budget.xlsx") as ed:
    ed.set_cell(0, "A1", "Total")     # cadena
    ed.set_cell(0, "B1", 42.5)        # número (int también vale)
    ed.set_cell(0, "C1", True)        # booleano
    ed.set_cell(0, "D1", None)        # vacío
    ed.save("budget.xlsx")

sheet_index empieza en cero; cell_ref usa la notación estándar de hojas de cálculo (A1, AA12).

IR independiente del formato

doc.to_ir() devuelve un dict anidado que refleja la DocumentIR de Rust: secciones con encabezados, párrafos, tablas, listas e imágenes. Útil para tuberías de procesamiento y para alimentar contexto estructurado a 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" | ...

Pipelines basados en bytes

from_bytes evita archivos temporales en flujos serverless y de streaming:

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

Formatos heredados

DOC, XLS y PPT usan la misma API. La extensión selecciona automáticamente el parser CFB heredado y save_as produce un OOXML moderno de forma transparente:

with Document.open("legacy.doc") as doc:
    print(doc.plain_text())
    doc.save_as("legacy.docx")     # DOC → DOCX en una línea

Errores

Los fallos de parseo e IO lanzan OfficeOxideError. Los fallos de IO en save_as se envuelven en 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 falló: {e}")
except FileNotFoundError:
    print("archivo no encontrado")

Solución de problemas

Síntoma Causa probable
OfficeOxideError: unsupported format: "" La ruta no tiene extensión — usa Document.from_bytes(data, "docx").
RuntimeError: Document is closed Saliste del with pero sigues teniendo la referencia. Abre un nuevo handle.
ImportError: _native La wheel no coincide con tu plataforma. pip install --force-reinstall office-oxide.
DOC heredado se ve corrupto El archivo puede estar cifrado (Word 97 RC4). office_oxide no descifra — descífralo primero con LibreOffice.
Problemas Unicode en Windows Usa pathlib.Path en vez de rutas en bytes; Document.open se encarga de la codificación de la plataforma.

Véase también