Exportação de Resultados SQL Diretamente para Excel Formatado com Python e Pandas

Exportação de Resultados SQL Diretamente para Excel Formatado com Python e Pandas

Em ambientes corporativos, a extração de dados armazenados em bancos de dados relacionais (como PostgreSQL, MySQL, SQL Server ou SQLite) é uma rotina diária para analistas e engenheiros de dados. Contudo, entregar resultados em arquivos CSV brutos ou dados sem formatação frequentemente gera retrabalho manual para equipes de negócios que dependem do Microsoft Excel para tomar decisões.

A combinação da biblioteca Pandas com a engine openpyxl permite construir pipelines automatizados em Python capazes de executar consultas SQL complexas, estruturar os dados e exportá-los diretamente para pastas de trabalho .xlsx altamente formatadas, com suporte a múltiplas abas, larguras de colunas ajustadas e formatação monetária.

1. Conectando ao Banco de Dados e Executando Consultas SQL

O primeiro passo para automatizar a geração de relatórios é conectar o Python ao banco de dados relacional e converter o resultado das consultas diretamente em um DataFrame do Pandas através da função pd.read_sql_query().

O Pandas interage com bancos de dados utilizando conectores padronizados como o SQLAlchemy (ou drivers nativos como sqlite3, psycopg2 ou pymysql). Esta abordagem garante que a execução da query ocorra diretamente no motor do banco de dados, trazendo para a memória do Python apenas o conjunto de resultados necessário.

import sqlite3
import pandas as pd
from sqlalchemy import create_engine

# Exemplo de conexão com banco de dados SQLite (ou via SQLAlchemy para PostgreSQL/MySQL)
engine = create_engine("sqlite:///empresa.db")

# Consulta SQL estruturada para extrair vendas por categoria
query_vendas = """
SELECT 
    p.categoria AS Categoria,
    p.nome_produto AS Produto,
    v.quantidade AS Unidades,
    v.preco_unitario AS Preco_Unitario,
    (v.quantidade * v.preco_unitario) AS Total_Vendas,
    v.data_venda AS Data
FROM vendas v
JOIN produtos p ON v.produto_id = p.id
WHERE v.data_venda >= '2026-01-01'
ORDER BY v.data_venda DESC;
"""

# Leitura direta da consulta SQL para um DataFrame
df_vendas = pd.read_sql_query(query_vendas, con=engine)

Ao utilizar pd.read_sql_query(), os nomes das colunas definidos nos aliases da consulta SQL (como categoria AS Categoria) são preservados no DataFrame, estabelecendo a estrutura que será exportada para a planilha.

2. Exportação Fundamental para Excel com to_excel()

Para exportar um DataFrame do Pandas para o formato .xlsx, o Python necessita da biblioteca openpyxl, que atua como o motor de escrita do Excel. O método nativo to_excel() realiza a conversão com poucas linhas de código.

Na exportação padrão, é essencial definir o parâmetro index=False. Por padrão, o Pandas inclui o seu índice numérico interno (0, 1, 2…) como a primeira coluna do arquivo exportado. Desativar o índice evita colunas desnecessárias que costumam confundir os leitores da planilha.

# Exportação simples para um arquivo Excel
df_vendas.to_excel("relatorio_vendas.xlsx", sheet_name="Vendas_2026", index=False)

Principais Parâmetros do Método to_excel()

A tabela a seguir destaca os parâmetros mais importantes do método to_excel() para personalizar a saída inicial dos dados:

ParâmetroTipoDescrição
excel_writerstr ou ExcelWriterCaminho do arquivo de destino ou objeto ExcelWriter ativo.
sheet_namestrNome da aba que será criada na planilha (Padrão: 'Sheet1').
indexboolDefine se o índice numérico do DataFrame será gravado na planilha (Padrão: True).
columnslistPermite selecionar e reordenar um subconjunto de colunas do DataFrame.
na_repstrTexto substituto para representar células com valores ausentes ou nulos (NaN).
startrowintLinha inicial de inserção da tabela, permitindo deixar espaço superior para títulos.

3. Consolidação de Múltiplas Consultas em Diferentes Abas com pd.ExcelWriter

Quando a automação exige a entrega de um relatório completo — contendo, por exemplo, os dados detalhados em uma aba e o resumo consolidado em outra —, chamadas consecutivas de to_excel() sobrescreveriam o arquivo anterior.

Para consolidar múltiplos DataFrames provenientes de diferentes consultas SQL no mesmo arquivo .xlsx, utiliza-se o gerenciador de contexto pd.ExcelWriter(). O bloco with garante que todas as abas sejam gravadas e o arquivo seja fechado e salvo de forma segura após a execução.

# Segunda consulta SQL: Resumo de vendas por categoria
query_resumo = """
SELECT 
    p.categoria AS Categoria,
    SUM(v.quantidade) AS Total_Unidades,
    SUM(v.quantidade * v.preco_unitario) AS Faturamento_Total
FROM vendas v
JOIN produtos p ON v.produto_id = p.id
GROUP BY p.categoria
ORDER BY Faturamento_Total DESC;
"""

df_resumo = pd.read_sql_query(query_resumo, con=engine)

# Exportando múltiplas consultas para abas distintas em um único arquivo
with pd.ExcelWriter("relatorio_executivo.xlsx", engine="openpyxl") as writer:
    df_resumo.to_excel(writer, sheet_name="Resumo_Executivo", index=False)
    df_vendas.to_excel(writer, sheet_name="Detalhamento_Vendas", index=False)

4. Formatação Avançada e Estilização com openpyxl

Embora o Pandas posicione os dados nas células corretamente, a planilha gerada nativamente carece de formatação visual: as colunas possuem largura fixa (o que frequentemente corta textos longos) e os valores numéricos aparecem sem símbolos de moeda ou separadores de milhar.

Ao acessar diretamente os objetos de planilha (worksheets) disponibilizados pelo pd.ExcelWriter(), é possível aplicar regras de estilização avançadas da biblioteca openpyxl.

from openpyxl.styles import Font, PatternFill, Alignment
from openpyxl.utils import get_column_letter

with pd.ExcelWriter("relatorio_formatado.xlsx", engine="openpyxl") as writer:
    df_vendas.to_excel(writer, sheet_name="Vendas", index=False)
    
    # Acesso aos objetos nativos do openpyxl
    workbook = writer.book
    worksheet = writer.sheets["Vendas"]
    
    # 1. Estilização do Cabeçalho (Linha 1)
    header_font = Font(name="Calibri", size=11, bold=True, color="FFFFFF")
    header_fill = PatternFill(start_color="1F497D", end_color="1F497D", fill_type="solid")
    
    for cell in worksheet[1]:
        cell.font = header_font
        cell.fill = header_fill
        cell.alignment = Alignment(horizontal="center", vertical="center")
        
    # 2. Formatação Monetária nas colunas Preco_Unitario e Total_Vendas (Colunas D e E)
    # Formato numérico em Real Brasileiro (R$)
    formato_moeda = 'R$ #,##0.00'
    
    for row in range(2, worksheet.max_row + 1):
        worksheet[f"D{row}"].number_format = formato_moeda
        worksheet[f"E{row}"].number_format = formato_moeda
        
    # 3. Ajuste Automático da Largura das Colunas
    for col in worksheet.columns:
        max_len = 0
        col_letter = get_column_letter(col[0].column) # Obtém a letra da coluna (A, B, C...)
        for cell in col:
            if cell.value is not None:
                max_len = max(max_len, len(str(cell.value)))
        worksheet.column_dimensions[col_letter].width = max(max_len + 3, 12)

Dica Prática: O ajuste dinâmico da largura calcula o tamanho da maior string contida em cada coluna e adiciona uma margem de segurança (como + 3 caracteres), garantindo que nenhum rótulo ou número fique oculto com os símbolos ### do Excel.

5. Boas Práticas e Processamento de Grandes Volumes de Dados

Ao trabalhar com bases de dados SQL volumosas contendo centenas de milhares de linhas, a leitura integral para a memória de uma só vez pode consumir recursos excessivos do sistema. Nesses cenários, é recomendado aplicar boas práticas de otimização:

  1. Filtragem Nativa na Consulta SQL: Sempre restrinja o volume de dados extraído utilizando cláusulas WHERE, agregando valores com GROUP BY ou selecionando apenas as colunas estritamente necessárias diretamente na query SQL, em vez de carregar tabelas inteiras no Pandas.
  2. Processamento em Blocos (chunksize): Para consultas que excedem a memória RAM disponível, utilize o parâmetro chunksize na função pd.read_sql_query(). Isso permite iterar sobre os dados em lotes menores e processar ou gravar registros gradualmente.
  3. Tratamento de Nulos na Exportação: Configure o parâmetro na_rep="N/A" ou na_rep="-" no método to_excel() para garantir que células vazias sejam exibidas de forma padronizada.
  4. Garantia de Fechamento de Recursos: Sempre envolva a gravação em blocos with pd.ExcelWriter(...) para evitar o corrompimento de arquivos caso ocorra uma falha durante o processo de gravação.

A automação da extração SQL diretamente para planilhas formatadas no Excel elimina etapas operacionais manuais, reduz riscos de erros humanos e garante que os relatórios sejam entregues com qualidade visual profissional e prontos para uso pelas equipes corporativas.

Thales de Oliveira Gomes

Thales de Oliveira Gomes é gestor de Tecnologia da Informação, especialista em infraestrutura de redes, computação em nuvem e operações de TI hospitalar, com mais de 18 anos de experiência na área. Graduado em Gestão de TI e pós-graduado em Engenharia de Redes e Telecomunicações, Cloud Computing, Redes de Computadores e Gestão Hospitalar, construiu uma trajetória sólida liderando projetos de alta complexidade, como a implementação e migração para nuvem de sistemas ERP de grande porte. Sua atuação no setor o levou a ser indicado ao prêmio IT Leaders Brasil na categoria Rising Leaders. Além da carreira corporativa e da paixão por tecnologia, Thales é autor independente com mais de 70 obras publicadas sobre redes, segurança da informação, Linux e física, além de criador de conteúdo no blog Vetor Tech e na plataforma CiberDicas. No universo das artes e do entretenimento, atua como produtor de música eletrônica sob o projeto Yknex, cria ilustrações digitais e compartilha walkthroughs de games no YouTube.

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *