Guia de Processamento de PDF
Visão Geral
Este guia aborda operações essenciais de processamento de PDF usando bibliotecas Python.
Use a ferramenta execute_code para executar o código Python mostrado abaixo.
Todos os arquivos gerados devem ser salvos no diretório artifacts/.
Configuração de Fonte Coreana (Obrigatória — Incluir em todo código de criação de PDF)
Ao criar PDFs com texto em coreano, é obrigatório registrar uma fonte coreana. Inclua o código de registro de fonte abaixo no início de todo código de criação de PDF.
Importante: O AppleSDGothicNeo.ttc do macOS possui outlines PostScript e não pode ser usado com reportlab.
Prioridade de fontes:
assets/NanumGothic-Regular.ttf(arquivo TTF — mais confiável)- Fonte CID
HYGothic-Medium(embutida no reportlab — não requer arquivo adicional, fallback seguro)
import os
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.pdfbase.cidfonts import UnicodeCIDFont
def register_korean_font():
"""Registra uma fonte coreana e retorna o nome da fonte. Deve ser chamado antes da criação do PDF."""
# 1ª opção: NanumGothic TTF
ttf_paths = [
os.path.join("assets", "NanumGothic-Regular.ttf"),
"/usr/share/fonts/truetype/nanum/NanumGothic.ttf",
"/usr/share/fonts/nanum/NanumGothic.ttf",
"/Library/Fonts/NanumGothic.ttf",
]
for path in ttf_paths:
if os.path.exists(path):
try:
pdfmetrics.registerFont(TTFont("KoreanFont", path))
return "KoreanFont"
except Exception:
continue
# 2ª opção: Fonte CID (embutida no reportlab, sem arquivo adicional)
try:
pdfmetrics.registerFont(UnicodeCIDFont("HYGothic-Medium"))
return "HYGothic-Medium"
except Exception:
pass
return "Helvetica" # Fallback final (sem suporte a coreano)
font_name = register_korean_font()
Criando Novos PDFs (reportlab)
Criação Básica de PDF (somente inglês)
from reportlab.lib.pagesizes import A4
from reportlab.pdfgen import canvas
import os
os.makedirs("artifacts", exist_ok=True)
c = canvas.Canvas("artifacts/hello.pdf", pagesize=A4)
width, height = A4
c.drawString(100, height - 100, "Hello World!")
c.save()
Criação de PDF com Coreano (padrão recomendado)
import os
from reportlab.lib.pagesizes import A4
from reportlab.lib.units import inch
from reportlab.lib import colors
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, PageBreak
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.pdfbase.cidfonts import UnicodeCIDFont
# 1) Registrar fonte coreana
font_name = "Helvetica"
for path in [os.path.join("assets", "NanumGothic-Regular.ttf"),
"/usr/share/fonts/truetype/nanum/NanumGothic.ttf"]:
if os.path.exists(path):
try:
pdfmetrics.registerFont(TTFont("KoreanFont", path))
font_name = "KoreanFont"
break
except Exception:
continue
if font_name == "Helvetica":
try:
pdfmetrics.registerFont(UnicodeCIDFont("HYGothic-Medium"))
font_name = "HYGothic-Medium"
except Exception:
pass
# 2) Definir estilos para coreano
styles = getSampleStyleSheet()
styles.add(ParagraphStyle("Title_KO", parent=styles["Title"], fontName=font_name, fontSize=20, spaceAfter=20, textColor=colors.HexColor("#1a1a2e")))
styles.add(ParagraphStyle("H1_KO", parent=styles["Heading1"], fontName=font_name, fontSize=16, spaceAfter=14, textColor=colors.HexColor("#16213e")))
styles.add(ParagraphStyle("H2_KO", parent=styles["Heading2"], fontName=font_name, fontSize=14, spaceAfter=12, textColor=colors.HexColor("#0f3460")))
styles.add(ParagraphStyle("Normal_KO", parent=styles["Normal"], fontName=font_name, fontSize=10, leading=14, spaceAfter=8))
styles.add(ParagraphStyle("Bullet_KO", parent=styles["Normal"], fontName=font_name, fontSize=10, leading=14, leftIndent=20, bulletIndent=10))
# 3) Construir PDF
os.makedirs("artifacts", exist_ok=True)
doc = SimpleDocTemplate("artifacts/report.pdf", pagesize=A4,
topMargin=0.8*inch, bottomMargin=0.8*inch, leftMargin=0.75*inch, rightMargin=0.75*inch)
story = []
story.append(Paragraph("Título do Relatório", styles["Title_KO"]))
story.append(Spacer(1, 16))
story.append(Paragraph("1. Visão Geral", styles["H1_KO"]))
story.append(Paragraph("Este relatório contém conteúdo de exemplo.", styles["Normal_KO"]))
story.append(Spacer(1, 8))
story.append(Paragraph("2. Detalhes", styles["H1_KO"]))
story.append(Paragraph("• Primeiro item", styles["Bullet_KO"]))
story.append(Paragraph("• Segundo item", styles["Bullet_KO"]))
story.append(PageBreak())
story.append(Paragraph("3. Apêndice", styles["H1_KO"]))
story.append(Paragraph("Conteúdo adicional.", styles["Normal_KO"]))
doc.build(story)
print("PDF criado: artifacts/report.pdf")
PDF com Tabela em Coreano
import os
from reportlab.lib.pagesizes import A4
from reportlab.platypus import SimpleDocTemplate, Table, TableStyle, Paragraph, Spacer
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib import colors
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.pdfbase.cidfonts import UnicodeCIDFont
# Registrar fonte
font_name = "Helvetica"
for path in [os.path.join("assets", "NanumGothic-Regular.ttf"),
"/usr/share/fonts/truetype/nanum/NanumGothic.ttf"]:
if os.path.exists(path):
try:
pdfmetrics.registerFont(TTFont("KoreanFont", path))
font_name = "KoreanFont"
break
except Exception:
continue
if font_name == "Helvetica":
try:
pdfmetrics.registerFont(UnicodeCIDFont("HYGothic-Medium"))
font_name = "HYGothic-Medium"
except Exception:
pass
styles = getSampleStyleSheet()
styles.add(ParagraphStyle("Title_KO", parent=styles["Title"], fontName=font_name, fontSize=18, textColor=colors.HexColor("#1a1a2e")))
styles.add(ParagraphStyle("Normal_KO", parent=styles["Normal"], fontName=font_name, fontSize=10))
os.makedirs("artifacts", exist_ok=True)
doc = SimpleDocTemplate("artifacts/table_report.pdf", pagesize=A4)
data = [
["Item", "Descrição", "Custo"],
["Servidor", "Instância EC2", "$120"],
["Armazenamento", "Bucket S3", "$45"],
["Banco de Dados", "RDS PostgreSQL", "$89"],
]
table = Table(data, colWidths=[120, 200, 80])
table.setStyle(TableStyle([
("BACKGROUND", (0, 0), (-1, 0), colors.HexColor("#e8eaf6")),
("TEXTCOLOR", (0, 0), (-1, 0), colors.HexColor("#1a1a2e")),
("FONTNAME", (0, 0), (-1, -1), font_name),
("FONTSIZE", (0, 0), (-1, -1), 10),
("GRID", (0, 0), (-1, -1), 0.5, colors.HexColor("#bdbdbd")),
("VALIGN", (0, 0), (-1, -1), "MIDDLE"),
("TOPPADDING", (0, 0), (-1, -1), 6),
("BOTTOMPADDING", (0, 0), (-1, -1), 6),
]))
doc.build([
Paragraph("Relatório de Análise de Custos", styles["Title_KO"]),
Spacer(1, 16),
table
])
print("PDF criado: artifacts/table_report.pdf")
Notas Importantes sobre reportlab
- Ao usar texto em coreano, inclua obrigatoriamente o código de registro de fonte acima.
- O
AppleSDGothicNeo.ttcdo macOS possui outlines PostScript e não pode ser usado com reportlab. Nunca o utilize. - Se a fonte TTF (
assets/NanumGothic-Regular.ttf) não estiver disponível, use a fonte CIDHYGothic-Medium. - Se a fonte não for registrada, o texto coreano aparecerá quebrado ou como quadrados vazios (□).
- NUNCA use caracteres Unicode de subscrito/sobrescrito (₀₁₂₃₄₅₆₇₈₉) em PDFs do ReportLab — use as tags
<sub>e<super>.
Lendo PDFs (pypdf)
Extrair Texto
from pypdf import PdfReader
reader = PdfReader("input.pdf")
text = ""
for page in reader.pages:
text += page.extract_text()
print(text)
Mesclar PDFs
from pypdf import PdfWriter, PdfReader
writer = PdfWriter()
for pdf_file in ["doc1.pdf", "doc2.pdf"]:
reader = PdfReader(pdf_file)
for page in reader.pages:
writer.add_page(page)
with open("artifacts/merged.pdf", "wb") as output:
writer.write(output)
Dividir PDF
from pypdf import PdfReader, PdfWriter
reader = PdfReader("input.pdf")
for i, page in enumerate(reader.pages):
writer = PdfWriter()
writer.add_page(page)
with open(f"artifacts/page_{i+1}.pdf", "wb") as output:
writer.write(output)
Rotacionar Páginas
from pypdf import PdfReader, PdfWriter
reader = PdfReader("input.pdf")
writer = PdfWriter()
page = reader.pages[0]
page.rotate(90)
writer.add_page(page)
with open("artifacts/rotated.pdf", "wb") as output:
writer.write(output)
Proteção com Senha
from pypdf import PdfReader, PdfWriter
reader = PdfReader("input.pdf")
writer = PdfWriter()
for page in reader.pages:
writer.add_page(page)
writer.encrypt("userpassword", "ownerpassword")
with open("artifacts/encrypted.pdf", "wb") as output:
writer.write(output)
Extração de Tabelas (pdfplumber)
import pdfplumber
with pdfplumber.open("input.pdf") as pdf:
for page in pdf.pages:
text = page.extract_text()
tables = page.extract_tables()
for table in tables:
for row in table:
print(row)
Referência Rápida
| Tarefa | Biblioteca | Função Principal |
|---|---|---|
| Criar PDF | reportlab | SimpleDocTemplate / canvas |
| Ler/Mesclar/Dividir PDF | pypdf | PdfReader / PdfWriter |
| Extrair tabelas | pdfplumber | page.extract_tables() |
| Proteger com senha | pypdf | writer.encrypt() |
| Rotacionar páginas | pypdf | page.rotate() |