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
- Migrar desde python-docx — sustitución directa, 14× más rápida
- Migrar desde openpyxl — misma cobertura XLSX, 18× más rápida
- Migrar desde python-pptx — PPTX 46× más rápida
- Benchmarks de rendimiento — cifras completas sobre 6.062 archivos
- Paquete en PyPI