Crear y Editar Documentos Word con Python y python-docx
python-docx permite crear, leer y modificar archivos .docx (Word) desde Python sin necesidad de tener Microsoft Word instalado. Ideal para generar informes, contratos y documentos automáticos.
Instalación
pip install python-docx
Crear un Documento Básico
from docx import Document
from docx.shared import Pt, Cm, RGBColor
doc = Document()
# Título principal
doc.add_heading("Informe de Ventas 2024", level=1)
# Párrafo con texto
doc.add_paragraph("Este informe resume las ventas del año fiscal 2024.")
# Párrafo con formato
p = doc.add_paragraph()
run = p.add_run("Resultado: ")
run.bold = True
run.font.size = Pt(12)
p.add_run("Superamos el objetivo en un 15%.")
doc.save("informe.docx")
print("Documento creado: informe.docx")
Estilos y Formato de Texto
from docx import Document
from docx.shared import Pt, RGBColor
from docx.enum.text import WD_ALIGN_PARAGRAPH
doc = Document()
# Encabezados por nivel
for nivel in range(1, 4):
doc.add_heading(f"Encabezado Nivel {nivel}", level=nivel)
# Párrafo centrado con color
p = doc.add_paragraph()
p.alignment = WD_ALIGN_PARAGRAPH.CENTER
run = p.add_run("Texto importante en color rojo")
run.font.color.rgb = RGBColor(0xFF, 0x00, 0x00)
run.font.size = Pt(14)
run.bold = True
run.italic = True
# Lista con viñetas
doc.add_paragraph("Primer elemento", style="List Bullet")
doc.add_paragraph("Segundo elemento", style="List Bullet")
doc.add_paragraph("Tercer elemento", style="List Bullet")
# Lista numerada
doc.add_paragraph("Paso uno", style="List Number")
doc.add_paragraph("Paso dos", style="List Number")
doc.save("formateado.docx")
Insertar Tablas
from docx import Document
from docx.shared import Pt, RGBColor
from docx.oxml.ns import qn
doc = Document()
doc.add_heading("Tabla de Productos", level=2)
datos = [
["Producto", "Precio", "Stock"],
["Widget A", "9.99", "150"],
["Widget B", "24.99", "80"],
["Widget C", "4.99", "320"],
]
tabla = doc.add_table(rows=len(datos), cols=3)
tabla.style = "Table Grid"
for i, fila in enumerate(datos):
for j, celda in enumerate(fila):
cell = tabla.cell(i, j)
cell.text = celda
if i == 0: # Encabezado en negrita
cell.paragraphs[0].runs[0].bold = True
doc.save("tabla.docx")
Insertar Imágenes y Saltos de Página
from docx import Document
from docx.shared import Cm
doc = Document()
doc.add_heading("Portada", level=1)
# Insertar imagen
try:
doc.add_picture("logo.png", width=Cm(6))
except FileNotFoundError:
doc.add_paragraph("[imagen no encontrada]")
# Salto de página
doc.add_page_break()
doc.add_heading("Contenido", level=1)
doc.add_paragraph("Aquí comienza el contenido del documento.")
doc.save("con_imagen.docx")
Leer y Extraer Texto de un DOCX
from docx import Document
def extraer_texto_docx(ruta):
doc = Document(ruta)
lineas = []
for para in doc.paragraphs:
if para.text.strip():
lineas.append(para.text)
# Texto en tablas
for tabla in doc.tables:
for fila in tabla.rows:
fila_texto = [celda.text.strip() for celda in fila.cells]
lineas.append(" | ".join(fila_texto))
texto = "\n".join(lineas)
with open("texto_extraido.txt", "w", encoding="utf-8") as f:
f.write(texto)
print(f"Extraídos {len(lineas)} párrafos")
return texto
extraer_texto_docx("informe.docx")
Generar Documentos desde Plantilla
from docx import Document
from docx.shared import Pt
import copy
def generar_contrato(plantilla_path, salida_path, datos):
doc = Document(plantilla_path)
# Reemplazar marcadores en párrafos
for para in doc.paragraphs:
for clave, valor in datos.items():
if clave in para.text:
for run in para.runs:
if clave in run.text:
run.text = run.text.replace(clave, str(valor))
doc.save(salida_path)
print(f"Contrato generado: {salida_path}")
datos_cliente = {
"{{NOMBRE}}": "Juan García",
"{{FECHA}}": "25 de abril de 2024",
"{{IMPORTE}}": "1.500,00 €",
"{{EMPRESA}}": "TechSolutions S.L.",
}
generar_contrato("plantilla_contrato.docx", "contrato_juan.docx", datos_cliente)
Recurso Adicional
Para convertir archivos DOCX a PDF, ODT o TXT sin instalar nada, usa KaijuConverter — gratis y sin registro.
Conversiones relacionadas
Conversiones de documento que siguen este tema: