Actualizado 4 junio 2026 · 15 min de lectura
Automatizar reportes PDF y Excel desde base de datos
Cada mes, alguien en tu empresa abre Excel, copia datos del sistema, ajusta formatos, genera un PDF, y lo envía por email. Ese proceso manual toma 2-4 horas y es propenso a errores.
En este tutorial te muestro cómo automatizarlo completamente: tu script consulta la base de datos, genera el reporte (PDF o Excel), y lo envía por email. Todo en menos de 50 líneas de Python.
Arquitectura de la solución
El flujo es simple:
- Cron/scheduler dispara tu script cada mes (o semana, o día)
- Script Python consulta tu BD (PostgreSQL, MySQL, SQLite)
- JSON estructurado con los datos del reporte
- API Reportia convierte JSON → PDF/Excel profesional
- Email automático envía el reporte al destinatario
Sin Chromium. Sin LaTeX. Sin Excel COM. Solo HTTP + JSON.
1 Consultar la base de datos
import psycopg2
from datetime import datetime, timedelta
# Conectar a PostgreSQL
conn = psycopg2.connect(
host="localhost", dbname="mi_app",
user="readonly", password="secret"
)
cur = conn.cursor()
# Datos del mes anterior
mes_anterior = datetime.now().replace(day=1) - timedelta(days=1)
inicio = mes_anterior.replace(day=1)
fin = mes_anterior
cur.execute("""
SELECT producto, COUNT(*) as ventas, SUM(monto) as ingreso
FROM ordenes
WHERE fecha BETWEEN %s AND %s
AND status = 'completada'
GROUP BY producto
ORDER BY ingreso DESC
""", (inicio, fin))
productos = [
{"producto": r[0], "ventas": r[1], "ingreso": float(r[2])}
for r in cur.fetchall()
]
cur.execute("""
SELECT COUNT(DISTINCT cliente_id), SUM(monto), AVG(monto)
FROM ordenes
WHERE fecha BETWEEN %s AND %s AND status = 'completada'
""", (inicio, fin))
total = cur.fetchone()
resumen = {
"clientes_activos": total[0],
"ingreso_total": float(total[1]),
"ticket_promedio": round(float(total[2]), 2)
}
conn.close()
2 Generar el reporte con la API
import requests
response = requests.post(
"https://reportia.4l3.org/v1/render",
headers={"Authorization": "Bearer TU_API_KEY"},
json={
"template": "reporte-mensual",
"format": "pdf", # o "xlsx" para Excel
"data": {
"titulo": f"Reporte de ventas - {mes_anterior.strftime('%B %Y')}",
"periodo": f"{inicio.strftime('%d/%m/%Y')} - {fin.strftime('%d/%m/%Y')}",
"resumen": resumen,
"tabla": productos,
"generado": datetime.now().isoformat(),
"moneda": "MXN"
}
}
)
# Guardar el archivo
nombre = f"reporte_{mes_anterior.strftime('%Y-%m')}.pdf"
with open(nombre, "wb") as f:
f.write(response.content)
print(f"Reporte generado: {nombre} ({len(response.content)//1024} KB)")
3 Enviar por email
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email.mime.text import MIMEText
from email import encoders
msg = MIMEMultipart()
msg["From"] = "[email protected]"
msg["To"] = "[email protected]"
msg["Subject"] = f"Reporte de ventas - {mes_anterior.strftime('%B %Y')}"
body = f"""Hola,
Adjunto el reporte de ventas de {mes_anterior.strftime('%B %Y')}.
Resumen:
- Clientes activos: {resumen['clientes_activos']}
- Ingreso total: ${resumen['ingreso_total']:,.2f} MXN
- Ticket promedio: ${resumen['ticket_promedio']:,.2f} MXN
Este reporte se genera automáticamente.
"""
msg.attach(MIMEText(body, "plain"))
# Adjuntar PDF
with open(nombre, "rb") as f:
adjunto = MIMEBase("application", "pdf")
adjunto.set_payload(f.read())
encoders.encode_base64(adjunto)
adjunto.add_header("Content-Disposition", f"attachment; filename={nombre}")
msg.attach(adjunto)
with smtplib.SMTP("smtp.gmail.com", 587) as server:
server.starttls()
server.login("[email protected]", "app_password")
server.send_message(msg)
print("Email enviado")
4 Programar con cron
Agrega una línea al crontab para que se ejecute el primer día de cada mes:
# Ejecutar a las 8am del primer día de cada mes
0 8 1 * * cd /opt/reportes && python3 generar_reporte.py >> /var/log/reportes.log 2>&1
También funciona con:
- GitHub Actions: schedule: cron: '0 8 1 * *'
- n8n / Zapier: nodo HTTP Request al endpoint de Reportia
- Airflow: como un task de tu DAG
- Webhooks: dispara con un evento de tu app
Caso real: reportes semanales para agencia de marketing
Una agencia digital en CDMX genera reportes semanales de campañas para 15 clientes. Antes:
- 2 horas por reporte (abrir Analytics, copiar datos, formatear Excel, exportar PDF)
- 30 horas/mes solo en reportes
Después de automatizar con Reportia:
- Script conecta a Google Analytics API + Meta Ads API
- JSON con métricas de cada cliente
- Reportia genera 15 PDFs en 45 segundos
- Email automático a cada cliente
- 0 horas manuales/mes
PDF vs Excel: ¿cuál generar?
Genera ambos con el mismo JSON. Solo cambia el campo format:
- PDF: para clientes, gerencia, presentaciones. Inmutable, profesional.
- Excel: para contabilidad, operaciones, análisis. Editable, pivotable.
# Generar ambos formatos del mismo reporte
for fmt in ["pdf", "xlsx"]:
r = requests.post(api_url, json={**payload, "format": fmt}, headers=headers)
ext = "pdf" if fmt == "pdf" else "xlsx"
with open(f"reporte.{ext}", "wb") as f:
f.write(r.content)
Automatiza tus reportes hoy
50 documentos gratis al mes. Sin tarjeta. API REST para Python, JavaScript, PHP y más.
Empezar gratis →Preguntas frecuentes
¿Cómo automatizar la generación de reportes PDF mensuales?
Crea un script Python que consulte tu base de datos, estructure los datos en JSON, y los envíe a la API de Reportia. Programa el script con cron para que se ejecute automáticamente cada mes.
¿Puedo generar reportes Excel automáticos desde PostgreSQL?
Sí. Consulta tus datos con psycopg2 o SQLAlchemy, estructura el resultado en JSON, y envíalo a Reportia con format: xlsx. Recibes un .xlsx profesional con formato.
¿Qué es mejor para reportes automáticos, PDF o Excel?
Depende del receptor. PDF para presentación y distribución (clientes, gerencia). Excel para análisis y manipulación de datos (contabilidad, operaciones). Reportia genera ambos desde el mismo JSON.
¿Funciona con MySQL, MongoDB, SQLite?
Sí. Reportia recibe JSON estándar. No importa de dónde vengan los datos: PostgreSQL, MySQL, MongoDB, SQLite, archivos CSV, APIs externas. Tú generas el JSON, Reportia genera el documento.