faef9b47dc
Dify foi removido 06-03-2026. Skills brainstorm/discover ainda referenciam-no no corpo. Bump v1.2 + nota top-of-file. Reescrita workflow para próxima sessão. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
161 lines
4.3 KiB
Markdown
161 lines
4.3 KiB
Markdown
---
|
|
name: pdf
|
|
description: Processamento de ficheiros PDF — leitura, extracção, merge, split, OCR, formulários. Versão light para heartbeats.
|
|
---
|
|
|
|
# PDF — Referência Rápida
|
|
|
|
## Bibliotecas Python
|
|
|
|
### pypdf — operações básicas
|
|
|
|
```python
|
|
from pypdf import PdfReader, PdfWriter
|
|
|
|
# Ler e extrair texto
|
|
reader = PdfReader("documento.pdf")
|
|
for page in reader.pages:
|
|
text = page.extract_text()
|
|
|
|
# Merge
|
|
writer = PdfWriter()
|
|
for pdf in ["doc1.pdf", "doc2.pdf"]:
|
|
for page in PdfReader(pdf).pages:
|
|
writer.add_page(page)
|
|
with open("merged.pdf", "wb") as f:
|
|
writer.write(f)
|
|
|
|
# Split (uma página por ficheiro)
|
|
for i, page in enumerate(reader.pages):
|
|
w = PdfWriter()
|
|
w.add_page(page)
|
|
with open(f"page_{i+1}.pdf", "wb") as f:
|
|
w.write(f)
|
|
|
|
# Rotate
|
|
page = reader.pages[0]
|
|
page.rotate(90)
|
|
|
|
# Password
|
|
writer.encrypt("userpass", "ownerpass")
|
|
```
|
|
|
|
### pdfplumber — tabelas e texto com layout
|
|
|
|
```python
|
|
import pdfplumber
|
|
|
|
with pdfplumber.open("doc.pdf") as pdf:
|
|
for page in pdf.pages:
|
|
text = page.extract_text()
|
|
tables = page.extract_tables()
|
|
```
|
|
|
|
### reportlab — criação de PDFs
|
|
|
|
```python
|
|
from reportlab.platypus import SimpleDocTemplate, Paragraph, Table, TableStyle, PageBreak
|
|
from reportlab.lib.styles import getSampleStyleSheet
|
|
from reportlab.lib import colors
|
|
|
|
doc = SimpleDocTemplate("report.pdf")
|
|
styles = getSampleStyleSheet()
|
|
elements = [Paragraph("Título", styles['Title'])]
|
|
doc.build(elements)
|
|
```
|
|
|
|
**Subscripts/superscripts:** Nunca usar caracteres Unicode. Usar tags XML: `<sub>2</sub>`, `<super>2</super>`.
|
|
|
|
## CLI
|
|
|
|
```bash
|
|
# Extrair texto (poppler-utils)
|
|
pdftotext input.pdf output.txt
|
|
pdftotext -layout input.pdf output.txt
|
|
|
|
# Merge/split (qpdf)
|
|
qpdf --empty --pages file1.pdf file2.pdf -- merged.pdf
|
|
qpdf input.pdf --pages . 1-5 -- pages1-5.pdf
|
|
|
|
# Encriptar
|
|
qpdf --encrypt user_pass owner_pass 256 -- input.pdf encrypted.pdf
|
|
|
|
# Reparar
|
|
qpdf --check input.pdf
|
|
|
|
# Extrair imagens
|
|
pdfimages -j input.pdf output_prefix
|
|
|
|
# Render para PNG
|
|
pdftoppm -png -r 300 document.pdf output_prefix
|
|
```
|
|
|
|
## OCR (PDFs digitalizados)
|
|
|
|
```python
|
|
import pytesseract
|
|
from pdf2image import convert_from_path
|
|
|
|
images = convert_from_path('scanned.pdf')
|
|
text = ""
|
|
for image in images:
|
|
text += pytesseract.image_to_string(image)
|
|
```
|
|
|
|
## Formulários
|
|
|
|
### Verificar campos preenchíveis
|
|
|
|
```bash
|
|
python scripts/check_fillable_fields.py <file.pdf>
|
|
```
|
|
|
|
### Campos preenchíveis (nativos)
|
|
|
|
1. `python scripts/extract_form_field_info.py <input.pdf> <field_info.json>`
|
|
2. `python scripts/convert_pdf_to_images.py <file.pdf> <output_dir>`
|
|
3. Criar `field_values.json` com `field_id`, `page`, `value`
|
|
4. `python scripts/fill_fillable_fields.py <input.pdf> <field_values.json> <output.pdf>`
|
|
|
|
### Campos não preenchíveis (anotações)
|
|
|
|
1. `python scripts/extract_form_structure.py <input.pdf> form_structure.json`
|
|
2. **Abordagem A (estrutura):** Analisar JSON, criar `fields.json` com `pdf_width`/`pdf_height` e bounding boxes
|
|
3. **Abordagem B (visual):** Converter para imagens, identificar campos, refinar com crop
|
|
4. `python scripts/check_bounding_boxes.py fields.json`
|
|
5. `python scripts/fill_pdf_form_with_annotations.py <input.pdf> fields.json <output.pdf>`
|
|
6. `python scripts/create_validation_image.py <page> <fields.json> <input_img> <output_img>`
|
|
|
|
## Referência rápida
|
|
|
|
| Tarefa | Ferramenta | Comando |
|
|
|--------|-----------|---------|
|
|
| Merge | pypdf/qpdf | `writer.add_page()` / `qpdf --pages` |
|
|
| Split | pypdf/qpdf | Uma página por ficheiro |
|
|
| Texto | pdfplumber | `page.extract_text()` |
|
|
| Tabelas | pdfplumber | `page.extract_tables()` |
|
|
| Criar | reportlab | Canvas ou Platypus |
|
|
| OCR | pytesseract | Converter para imagem primeiro |
|
|
| Formulários | pypdf/scripts | Ver secção acima |
|
|
|
|
## Caminhos Descomplicar
|
|
|
|
| Local | Caminho |
|
|
|-------|---------|
|
|
| Documentos empresa | `/media/ealmeida/Dados/GDrive/Cloud/Descomplicar/` |
|
|
| Propostas | `/media/ealmeida/Dados/Hub/03-Propostas/` |
|
|
| Arquivo clientes | `/media/ealmeida/Dados/GDrive/Arquivo_de_Clientes/` |
|
|
| Knowledge Base | `/media/ealmeida/Dados/Hub/06-Operacoes/Knowledge-Base/PDFs/` |
|
|
| Temporários | `~/.claude-work/` (limpar ao concluir) |
|
|
|
|
## Workflow
|
|
|
|
1. Localizar PDF (filesystem ou Google Drive)
|
|
2. Descarregar para `~/.claude-work/` se necessário
|
|
3. Processar
|
|
4. Guardar no destino final
|
|
5. Limpar temporários
|
|
|
|
---
|
|
**Versão**: 1.0.0-light | **Base**: 1.0.0
|