Como automatizar relatórios em Excel com Python
Para automatizar um relatório em Excel com Python, use o pandas para ler e resumir os dados (CSV, outra planilha ou banco), grave o resultado com pd.ExcelWriter e formate com o openpyxl. Depois agende o script no Agendador de Tarefas do Windows ou no cron do Linux, para o arquivo ficar pronto antes de alguém chegar ao escritório.
Atualizado em · Por Luis Henrique Cuba
Quando vale trocar o relatório manual por um script
O candidato clássico é o relatório semanal que alguém monta toda segunda-feira: exporta o CSV do sistema, cola numa planilha, faz tabela dinâmica, pinta o cabeçalho e manda por e-mail. Se os passos são sempre os mesmos, o Python faz tudo em segundos.
O que não vale automatizar é o relatório que muda de formato a cada mês por pedido da diretoria. Primeiro estabilize o modelo; depois escreva o script.
Preparação
- 01
Instale o Python
Baixe em python.org. No Windows, marque a opção de adicionar o Python ao PATH durante a instalação.
- 02
Crie uma pasta e um ambiente virtual
Um ambiente por projeto evita que a atualização de um pacote quebre outro script.
python -m venv .venv - 03
Ative o ambiente e instale os pacotes
No Windows: .venv\Scripts\activate. No Linux ou macOS: source .venv/bin/activate.
pip install pandas openpyxl - 04
Organize as pastas
Uma pasta dados para a origem (por exemplo, vendas.csv exportado do ERP) e uma pasta saida para os relatórios gerados.
Script completo: resumo semanal de vendas
from datetime import date, timedelta
from pathlib import Path
import pandas as pd
from openpyxl import load_workbook
from openpyxl.styles import Font, PatternFill
PASTA = Path(__file__).resolve().parent
ORIGEM = PASTA / "dados" / "vendas.csv"
COLUNAS = {"data", "vendedor", "regiao", "valor"}
# 1. Ler e conferir a origem (CSV brasileiro: ; e vírgula decimal)
df = pd.read_csv(ORIGEM, sep=";", decimal=",", encoding="utf-8")
faltando = COLUNAS - set(df.columns)
if faltando:
raise SystemExit(f"Colunas ausentes no arquivo de origem: {faltando}")
df["data"] = pd.to_datetime(df["data"], dayfirst=True)
# 2. Filtrar a semana anterior (segunda a domingo)
hoje = date.today()
inicio = hoje - timedelta(days=hoje.weekday() + 7)
fim = inicio + timedelta(days=6)
semana = df[(df["data"].dt.date >= inicio) & (df["data"].dt.date <= fim)]
# 3. Resumir por região e vendedor
resumo = (
semana.groupby(["regiao", "vendedor"], as_index=False)["valor"]
.sum()
.sort_values("valor", ascending=False)
)
# 4. Gravar as duas abas com pandas
saida = PASTA / "saida" / f"vendas_{inicio:%Y-%m-%d}.xlsx"
saida.parent.mkdir(exist_ok=True)
with pd.ExcelWriter(saida, engine="openpyxl") as writer:
resumo.to_excel(writer, sheet_name="Resumo", index=False)
semana.to_excel(writer, sheet_name="Detalhe", index=False)
# 5. Formatar com openpyxl
wb = load_workbook(saida)
for ws in wb.worksheets:
for celula in ws[1]:
celula.font = Font(bold=True, color="FFFFFF")
celula.fill = PatternFill("solid", start_color="1F4E78")
ws.freeze_panes = "A2"
ws.auto_filter.ref = ws.dimensions
for coluna in ws.columns:
largura = max(len(str(c.value or "")) for c in coluna) + 2
ws.column_dimensions[coluna[0].column_letter].width = min(largura, 40)
if coluna[0].value == "valor":
for c in coluna[1:]:
c.number_format = '"R$" #,##0.00'
if coluna[0].value == "data":
for c in coluna[1:]:
c.number_format = "DD/MM/YYYY"
wb.save(saida)
print(f"Relatório gerado: {saida} ({len(semana)} vendas)")Por que pandas e openpyxl juntos
pandas
Lê CSV, Excel e bancos de dados, filtra, agrupa e cruza tabelas. É onde fica a lógica do relatório.
openpyxl
Mexe no arquivo .xlsx em si: fontes, cores, largura de coluna, formato de moeda e data, congelar painéis, filtros. O pandas usa o openpyxl por baixo para gravar.
A conferência das colunas
O passo 1 do script para tudo com uma mensagem clara se o sistema de origem mudar o nome de uma coluna. É a falha mais comum desse tipo de rotina, e é melhor ela aparecer como erro do que como relatório com dados errados.
O que costuma dar errado
- O sistema de origem exporta o CSV com outro separador ou codificação (por exemplo, latin-1 em vez de utf-8). Teste com um arquivo real antes de agendar.
- Valores chegam como texto, com R$ e ponto de milhar. Limpe a coluna antes de somar, senão o pandas concatena em vez de somar.
- O arquivo de saída está aberto no Excel de alguém na hora em que o script roda, e o Windows bloqueia a gravação. Gerar um nome por data, como no exemplo, evita isso.
- A pasta de rede não está montada quando a tarefa roda de madrugada. Prefira caminhos locais ou confira o acesso no log.
- Ninguém percebe que o relatório parou. Faça o script avisar por e-mail quando falhar, ou confira o log na primeira semana de cada mudança.
Agendar no Windows e no Linux
- 01
Windows: crie um .bat
Um arquivo rodar.bat na pasta do projeto chama o Python do ambiente virtual. Assim o agendador não depende do PATH.
cd /d C:\relatorios .venv\Scripts\python.exe gerar_relatorio.py >> log.txt 2>&1 - 02
Windows: agende toda segunda às 7h
No Prompt de Comando, ou pela interface do Agendador de Tarefas (Criar Tarefa Básica).
schtasks /create /tn "Relatorio de vendas" /tr C:\relatorios\rodar.bat /sc weekly /d MON /st 07:00 - 03
Linux: edite o crontab
Rode crontab -e e adicione a linha abaixo (segunda-feira, 7h). Use caminhos absolutos, porque o cron não carrega o seu ambiente.
0 7 * * 1 cd /opt/relatorios && .venv/bin/python gerar_relatorio.py >> log.txt 2>&1 - 04
Confira o log
Os dois exemplos gravam a saída e os erros em log.txt. Na primeira semana, abra o log todo dia.
Como automatizar relatórios em Excel com Python: dúvidas comuns
Dá para enviar o relatório por e-mail automaticamente?
Dá, com a biblioteca smtplib do próprio Python e a classe EmailMessage para anexar o arquivo. Guarde usuário e senha do e-mail em variáveis de ambiente, nunca no código.
O openpyxl abre arquivos .xls antigos?
Não. O openpyxl trabalha com .xlsx e formatos relacionados. Para .xls antigo, salve como .xlsx no Excel ou leia com o pandas usando outro mecanismo de leitura.
Posso atualizar uma planilha existente sem apagar as fórmulas?
Pode, carregando o arquivo com load_workbook e escrevendo só nas células de dados. Evite regravar a planilha inteira com o pandas, que cria o arquivo de novo e perde a formatação e as fórmulas.
Python ou Power Query?
O Power Query resolve bem a transformação dentro do próprio Excel, sem programar. O Python é melhor quando o relatório precisa rodar sozinho em horário fixo, juntar fontes variadas ou ser enviado por e-mail.
Preciso ter o Excel instalado para rodar o script?
Não. O pandas e o openpyxl leem e gravam o arquivo .xlsx diretamente, então o script roda até num servidor Linux sem Office.
Precisa de ajuda para resolver isso na sua empresa?
Respondemos em até 24 horas com as próximas perguntas e uma proposta objetiva.