openpyxl / python-docx / reportlab
Três bibliotecas cobrem a maior parte da automação de documentos em Python: openpyxl para Excel, python-docx para Word e reportlab para geração de PDF - comum em fluxos de trabalho de relatórios, exportações e conformidade.
Receita
from openpyxl import Workbook
wb = Workbook()
ws = wb.active
ws.title = "Resumo"
ws.append(["sku", "qtde", "receita"])
ws.append(["ABC", 10, 199.90])
wb.save("relatorio.xlsx")Quando usar isso:
- Exportar resultados de consulta para Excel para finanças/operações
- Documentos Word no estilo mala direta a partir de dados do CRM
- Faturas, notas de embalagem e certificados como PDF
- Tarefas de relatório agendadas em Celery/cron
Exemplo de Trabalho
from __future__ import annotations
from datetime import datetime, timezone
from io import BytesIO
from openpyxl import Workbook
from reportlab.lib.pagesizes import letter
from reportlab.pdfgen import canvas
def build_sales_xlsx(rows: list[tuple[str, int, float]]) -> bytes:
wb = Workbook()
ws = wb.active
ws.title = "Vendas"
ws.append(["produto", "unidades", "receita"])
for product, units, revenue in rows:
ws.append([product, units, revenue])
buf = BytesIO()
wb.save(buf)
return buf.getvalue()
def build_invoice_pdf(invoice_id: str, total: float) -> bytes:
buf = BytesIO()
c = canvas.Canvas(buf, pagesize=letter)
c.setFont("Helvetica", 12)
c.drawString(72, 720, f"Fatura {invoice_id}")
c.drawString(72, 700, f"Total: ${total:,.2f}")
c.drawString(72, 680, datetime.now(timezone.utc).isoformat())
c.showPage()
c.save()
return buf.getvalue()
if __name__ == "__main__":
xlsx = build_sales_xlsx([("widget", 3, 59.97)])
pdf = build_invoice_pdf("INV-1001", 59.97)
print(len(xlsx), len(pdf))O que isso demonstra:
- Workbooks em memória via
BytesIOpara respostas HTTP - Planilha xlsx tabular simples sem a sobrecarga do pandas
- PDF mínimo com a API de canvas do reportlab
- Timestamp UTC no PDF para trilha de auditoria
Mergulho Profundo
Como Funciona
- openpyxl - OOXML xlsx;
load_workbookpara edições;data_only=Truelê valores de fórmula em cache. - python-docx - Manipula WordprocessingML; parágrafos, tabelas, estilos; mesclagem de modelo substituindo placeholders.
- reportlab - Canvas PDF de baixo nível mais Platypus flowables para layouts complexos.
Escolha da Biblioteca
| Saída | Biblioteca | Notas |
|---|---|---|
| exportação xlsx | openpyxl | Ou pandas to_excel (usa openpyxl/xlsxwriter) |
| Memo Word | python-docx | Mantenha o modelo .docx no repositório |
| Fatura PDF | reportlab | Ou WeasyPrint a partir de HTML se a equipe conhece CSS |
| PDF de Word | docx2pdf (Win/Mac) | Não para servidores Linux |
Notas de Python
from docx import Document
doc = Document("template.docx")
for p in doc.paragraphs:
if "{{NAME}}" in p.text:
p.text = p.text.replace("{{NAME}}", "Ada Lovelace")
buf = BytesIO()
doc.save(buf)Armadilhas
- Carregar xlsx não confiável - Existem variantes de XML bombs e billion-laughs. Correção: limites de tamanho, verificação de vírus, análise em worker de sandbox.
- Fórmulas vs valores -
load_workbookretorna fórmulas por padrão. Correção:data_only=Truepara valores exibidos (desatualizados até o Excel abrir). - Recursos não suportados pelo python-docx - Cabeçalhos/rodapés em modelos complexos podem falhar. Correção: simplifique o modelo ou use modelos docx mantidos no Word.
- Licenciamento de fontes do reportlab - Incorpore apenas fontes licenciadas para PDFs comerciais. Correção: use Helvetica embutido ou TTF licenciado.
- Memória em grandes exportações - Construir um xlsx de um milhão de linhas na RAM causa OOM. Correção: CSV para dados grandes, ou gravações em blocos com o modo
write_only=True. - Localização e datas no Excel - O Excel exibe o formato local; armazene ISO nos dados de origem. Correção: formatos de número explícitos em openpyxl.
Alternativas
| Alternativa | Usar Quando | Não Usar Quando |
|---|---|---|
pandas to_excel | DataFrame já em memória | Exportação simples de 3 colunas (openpyxl é mais leve) |
| WeasyPrint / wkhtmltopdf | Equipe prefere layouts HTML/CSS | Dependências mínimas em servidores restritos |
| API do Google Sheets | Planilhas ao vivo colaborativas | Relatórios offline/air-gapped |
| LaTeX | Qualidade de PDF científico | Usuários de negócios editam modelos no Word |
FAQs
openpyxl ou xlsxwriter?
openpyxl lê e escreve; xlsxwriter é apenas para escrita com formatação rica - escolha com base na necessidade de leitura.
Como retorno xlsx do FastAPI?
Response(content=bytes, media_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") com cabeçalho de anexo Content-Disposition.
O python-docx pode inserir imagens?
Sim - document.add_picture(path, width=Inches(2)) para logotipos em documentos gerados.
Como adiciono tabelas no Word?
table = doc.add_table(rows=1, cols=3) e depois preencha as células - estilize com os estilos de tabela embutidos.
reportlab vs ReportBro?
reportlab é baseado em código; ReportBro é uma interface de designer - escolha com base em quem mantém os layouts.
Excel protegido por senha?
openpyxl tem suporte limitado - descriptografe antes de carregar ou rejeite uploads criptografados.
Como faço testes unitários de saída PDF?
Afirme que o PDF começa com %PDF e contém o texto esperado extraído via pypdf nos testes.
xlsm habilitado para macro?
Evite no lado do servidor - macros são um risco de segurança; aceite apenas xlsx.
Unicode em PDF?
Registre um TTF que cubra seu conjunto de glifos - Helvetica embutido não possui CJK.
Tarefa Celery gerando relatórios?
Escreva no armazenamento de objetos (S3) e retorne URL assinado - não anexos de e-mail de vários MB.
Relacionados
- Noções Básicas de pandas - DataFrame para Excel
- celery - geração de relatórios assíncrona
- S3 - armazenamento de documentos gerados
- pendulum / arrow - datas em relatórios
Versões da Stack: Esta página foi escrita para Python 3.14.0 (estável 3.14, manutenção 3.13), FastAPI 0.115+, Django 5.2, Flask 3.1, Pydantic 2, PyTorch 2.6+, pandas 2.2+, Polars 1.x, ruff 0.9+ e uv 0.6+.