ODT (OpenDocument Text) es el formato estándar ISO para documentos de texto de LibreOffice y Apache OpenOffice. Es un archivo ZIP que contiene XML, imágenes y metadatos, totalmente abierto y sin dependencias de software propietario.
## ODT vs DOCX: comparativa
| Característica | ODT | DOCX |
|---|---|---|
| Estándar | ISO/IEC 26300 | ECMA-376 / ISO 29500 |
| Desarrollado por | OASIS / ISO | Microsoft |
| Soporte | LibreOffice, OpenOffice, Google Docs | Word, LibreOffice, Google Docs |
| Formato interno | XML abierto en ZIP | XML en ZIP (variante propietaria) |
| Compatibilidad histórica | Muy estable | Varía entre versiones Word |
| Uso en administraciones | Muy alto (España, UE) | Alto |
## Estructura interna de un ODT
```bash
# Un ODT es un ZIP — inspeccionar su contenido
unzip -l documento.odt
# Archive: documento.odt
# Length Name
# -------- ----
# 39 mimetype
# 2847 content.xml ← El texto del documento
# 1024 styles.xml ← Estilos y formato
# 512 meta.xml ← Metadatos (autor, fecha...)
# 256 settings.xml ← Configuración LibreOffice
# 128 manifest.rdf
# 128 META-INF/manifest.xml
# Extraer y ver el contenido XML
unzip -p documento.odt content.xml | python3 -m xml.etree.ElementTree
```
## Instalar odfpy
```bash
pip install odfpy
```
## Crear un documento ODT con odfpy
```python
from odf.opendocument import OpenDocumentText
from odf.style import Style, TextProperties, ParagraphProperties
from odf.text import P, H, Span
from odf import teletype
# Crear documento
doc = OpenDocumentText()
# Definir estilos
estilo_titulo = Style(name='MiTitulo', family='paragraph')
estilo_titulo.addElement(TextProperties(fontsize='18pt', fontweight='bold'))
estilo_titulo.addElement(ParagraphProperties(textalign='center'))
doc.styles.addElement(estilo_titulo)
# Añadir título
h = H(outlinelevel=1, stylename='Heading 1')
h.addText('Mi Primer Documento ODT')
doc.text.addElement(h)
# Añadir párrafos
p1 = P(stylename='Text Body')
p1.addText('Este documento fue creado con Python y odfpy.')
doc.text.addElement(p1)
p2 = P()
p2.addText('Odfpy permite crear documentos OpenDocument sin necesidad de LibreOffice instalado.')
doc.text.addElement(p2)
# Guardar
doc.save('mi_documento.odt')
print("Documento ODT creado correctamente")
```
## Extraer texto de un ODT
```python
from odf.opendocument import load
from odf.text import P, H
from odf import teletype
def extraer_texto_odt(ruta_odt):
"""Extrae todo el texto de un documento ODT."""
doc = load(ruta_odt)
texto = []
for elemento in doc.text.childNodes:
# Párrafos y encabezados
if elemento.qname[1] in ('p', 'h'):
linea = teletype.extractText(elemento).strip()
if linea:
texto.append(linea)
return '\n'.join(texto)
contenido = extraer_texto_odt('documento.odt')
print(contenido[:500])
```
## Leer metadatos
```python
from odf.opendocument import load
doc = load('documento.odt')
meta = doc.meta
print(f"Título: {meta.title}")
print(f"Autor: {meta.creator}")
print(f"Creado: {meta.creation_date}")
print(f"Palabras: {meta.word_count}")
print(f"Páginas: {meta.page_count}")
```
## Convertir ODT con LibreOffice CLI
LibreOffice puede convertir ODT a DOCX, PDF, HTML y otros formatos desde línea de comandos (sin interfaz gráfica):
```bash
# ODT → DOCX
libreoffice --headless --convert-to docx documento.odt
# ODT → PDF
libreoffice --headless --convert-to pdf documento.odt
# ODT → HTML
libreoffice --headless --convert-to html documento.odt
# Especificar directorio de salida
libreoffice --headless --convert-to pdf --outdir ./pdfs/ documento.odt
# Conversión masiva (todos los ODT del directorio)
libreoffice --headless --convert-to pdf *.odt
# En Linux/Mac con ruta absoluta
/usr/bin/libreoffice --headless --convert-to docx documento.odt
```
## Conversión masiva con Python
```python
import subprocess
from pathlib import Path
def convertir_odt_a_pdf(directorio_entrada, directorio_salida):
"""Convierte todos los ODT de una carpeta a PDF usando LibreOffice."""
entrada = Path(directorio_entrada)
salida = Path(directorio_salida)
salida.mkdir(parents=True, exist_ok=True)
archivos_odt = list(entrada.glob('*.odt'))
print(f"Encontrados: {len(archivos_odt)} archivos ODT")
for odt in sorted(archivos_odt):
print(f" Convirtiendo: {odt.name}")
resultado = subprocess.run(
[
'libreoffice',
'--headless',
'--convert-to', 'pdf',
'--outdir', str(salida),
str(odt),
],
capture_output=True,
text=True,
)
if resultado.returncode == 0:
pdf_nombre = odt.stem + '.pdf'
tam = (salida / pdf_nombre).stat().st_size / 1024
print(f" OK → {pdf_nombre} ({tam:.0f} KB)")
else:
print(f" ERROR: {resultado.stderr[:200]}")
print(f"\nConversión completa: {len(archivos_odt)} archivos procesados")
convertir_odt_a_pdf('documentos_odt/', 'pdfs_generados/')
```
## Convertir DOCX a ODT con python-docx + odfpy
```python
# Para conversión completa, usa LibreOffice CLI (más fiable)
subprocess.run(['libreoffice', '--headless', '--convert-to', 'odt', 'documento.docx'])
# Alternativa: Pandoc (maneja estilos básicos)
# pip install pypandoc
import pypandoc
pypandoc.convert_file('documento.docx', 'odt', outputfile='documento.odt')
```
## Cuándo usar ODT
- **Documentos de larga duración**: ODT es más estable que DOCX en versiones futuras de software
- **Sector público y administración**: requerido por muchas administraciones europeas
- **Evitar dependencia de Microsoft Office**: ecosistema completamente libre y gratuito
- **Interoperabilidad**: compatible con LibreOffice, OpenOffice, Google Docs, Zoho y otros
Guía