Automatizar reportes de Excel con Python toma cuatro elementos: pandas para procesar datos, openpyxl para escribir el archivo con formato, smtplib para enviarlo por email, y cron o schedule para correr el script en horario fijo. Lo que antes ocupaba a tu analista dos horas cada lunes pasa a correr en 30 segundos sin intervención. Sin retainers, sin licencias atadas, código a tu nombre.
La arquitectura mínima
Cuatro piezas, una por capa:
- Extracción: pandas lee fuentes (CSV, SQL, API, Excel base)
- Transformación: pandas agrupa, filtra, calcula KPIs
- Escritura: openpyxl o xlsxwriter genera el Excel con formato
- Distribución: smtplib o cualquier API de email envía a stakeholders
Stack recomendado
| Librería | Para qué | Cuándo usarla |
|---|---|---|
| pandas | Manipular datos | Siempre |
| openpyxl | Leer y escribir xlsx con formato | Reportes ejecutivos con celdas formateadas |
| xlsxwriter | Solo escribir con dashboards y gráficos | Reportes con visualizaciones embebidas |
| matplotlib | Generar gráficos para embeber | Charts dinámicos en el Excel |
| schedule | Tareas recurrentes simples | Script corriendo como servicio Python |
| smtplib | Enviar email con adjunto | Distribución a equipo interno |
Esqueleto de script funcional
Un reporte semanal de ventas que extrae de PostgreSQL, agrupa por canal y envía por email cada lunes a las 7 AM:
import pandas as pd
from sqlalchemy import create_engine
from openpyxl import load_workbook
from openpyxl.styles import Font, PatternFill
import smtplib
from email.message import EmailMessage
from datetime import datetime, timedelta
# 1. Extraer
engine = create_engine("postgresql://user:pass@host/db")
hoy = datetime.now().date()
hace_7d = hoy - timedelta(days=7)
query = f"""
SELECT canal, SUM(monto) as ventas, COUNT(*) as transacciones
FROM ventas
WHERE fecha_pago BETWEEN '{hace_7d}' AND '{hoy}'
GROUP BY canal
ORDER BY ventas DESC;
"""
df = pd.read_sql(query, engine)
# 2. Transformar
df["ticket_promedio"] = df["ventas"] / df["transacciones"]
df["pct_total"] = (df["ventas"] / df["ventas"].sum() * 100).round(1)
# 3. Escribir con formato
archivo = f"reporte_semanal_{hoy}.xlsx"
df.to_excel(archivo, index=False, sheet_name="Ventas")
wb = load_workbook(archivo)
ws = wb["Ventas"]
header_fill = PatternFill(start_color="111827", fill_type="solid")
header_font = Font(color="FFFFFF", bold=True)
for cell in ws[1]:
cell.fill = header_fill
cell.font = header_font
wb.save(archivo)
# 4. Enviar por email
msg = EmailMessage()
msg["Subject"] = f"Reporte semanal ventas - {hoy}"
msg["From"] = "[email protected]"
msg["To"] = "[email protected]"
msg.set_content("Reporte adjunto.")
with open(archivo, "rb") as f:
msg.add_attachment(f.read(), maintype="application",
subtype="xlsx", filename=archivo)
with smtplib.SMTP_SSL("smtp.gmail.com", 465) as s:
s.login("[email protected]", "APP_PASSWORD")
s.send_message(msg)
Ese script corre en cron así (cada lunes a las 7 AM):
0 7 * * 1 /usr/bin/python3 /opt/scripts/reporte_semanal.py
El caso real: KPIs en código, no en celdas
Una distribuidora multi-país (case_028) necesitaba reportería avanzada para 100 franquicias con 5 secciones (Financials, Sales, Services, Complaints, System Usage). El error típico habría sido dejar que la IA calcule KPIs sobre los datos; lo correcto es lo opuesto.
Lo que se construyó:
- 28 KPIs calculados en código JavaScript determinístico, no en respuestas de IA
- IA solo genera narrativa explicativa sobre números ya calculados
- Browser-side compute (cero CPU del servidor)
- Patrón de dos niveles: headline KPI más párrafo IA explicativo
- Audit trail inmutable con SHA-256 hash chain verificable
El principio aplica idéntico a tu reporte semanal en Python: las métricas se calculan en código auditable. Si en algún momento agregas IA para generar narrativa, dale los KPIs ya calculados, no le pidas que los calcule. KPIs en código, no hallucinations.
Cuándo escala Python vs cuándo necesitas más
Python con cron resuelve si:
- Tu reporte corre menos de 1 vez al día
- Las fuentes están todas en un solo lugar (una BD, un Excel base)
- Los destinatarios son menos de 20 personas internas
- No necesitas dashboards interactivos navegables
Necesitas más infraestructura si:
- Tu pipeline tiene 5+ pasos con dependencias (usa Airflow o Prefect)
- Distribuyes a 100+ usuarios externos (usa portal web propio)
- Necesitas dashboards interactivos (combina con Looker Studio o Metabase)
- La narrativa explicativa requiere IA (combina con Anthropic Claude API)
7 errores que rompen reportes automatizados
- Hardcodear credenciales en el script (usa variables de entorno o secrets manager)
- No manejar errores de conexión a la BD (envuelve en try/except y notifica fallos)
- Olvidar zona horaria (usa pytz o zoneinfo explícito)
- Generar el archivo sin timestamp en el nombre (sobrescribes la versión previa)
- Confiar en el SMTP de Gmail sin app password (las contraseñas normales fallan con 2FA)
- No loguear cada corrida (cuando falle, no sabrás cuándo)
- No validar conteos antes de enviar (si la query devuelve 0 filas, no mandes el reporte vacío)
¿Cuánto cuesta no automatizar?
Un analista financiero a 30 USD la hora cargada que arma reporte semanal de ventas en 2 horas son 60 USD por reporte, 3,120 USD al año, 9,360 USD a 3 años. Y eso solo en costo directo: el costo de oportunidad (la hora que el analista no dedica a análisis profundo) es mayor.
Un script Python que corre solo cuesta:
- 8 a 20 horas de desarrollo inicial (240 a 600 USD por única vez)
- 10 a 20 USD/mes de hosting si lo despliegas en cloud
- 30 minutos al año de mantenimiento
Paga su costo en menos de 3 meses. Tu equipo vuelve al trabajo real.
¿Tu reportería está sangrando?
Si tu equipo dedica más de 10 horas semanales a generar reportes manuales en Excel, no tienes problema de productividad: tienes problema de arquitectura. Lo que antes tomaba 30 ingenieros y 18 meses lo entregamos en semanas, y los reportes automáticos son la parte fácil del paquete.
Próximos pasos
Si tienes equipo técnico interno, empieza hoy con el esqueleto Python que dejé arriba. En 4 horas tienes el primer reporte corriendo. Si tu empresa pasa de 15 reportes manuales recurrentes y los datos viven en 5+ sistemas distintos, no necesitas más scripts: necesitas Data Lake unificado.
MAGIA Core construye Data Lake con reportería automatizada en 12 semanas, dashboards por rol, KPIs en código y código a tu nombre por 15,000 USD únicos. Para profesionales individuales que necesitan reportería simple integrada a su negocio, MAGIA Solo entrega web, CRM y analytics en 15 días por 4,500 USD. Llamada de 30 min, sin pitch deck, conversación real sobre tu operación.