Skip to content

Extração por região — Obtenha conteúdo de uma área específica

Quando você processa notas fiscais, extratos bancários, formulários tributários ou qualquer layout baseado em template, normalmente já sabe onde ficam os campos. Em vez de extrair a página inteira e depois procurar o valor, aponte o PDF Oxide para o retângulo exato e receba apenas o que está ali.

A API fluente within(page, rect) devolve uma região delimitada na qual você pode encadear métodos de extração: extract_text(), extract_words(), extract_chars(), extract_tables().

Cobertura nos bindings. within(page, rect) está disponível em Python, Rust e WASM. Go e C# expõem os helpers de baixo nível equivalentes (ExtractTextInRect, ExtractWordsInRect, ExtractImagesInRect) — veja abaixo.

Exemplo rápido

rect é (x, y, width, height) em pontos do PDF, com origem no canto inferior esquerdo da página. Páginas tamanho Letter têm 612 × 792 pontos.

Python

from pdf_oxide import PdfDocument

doc = PdfDocument("invoice.pdf")

# 92 pontos do topo da página 0 — faixa típica do cabeçalho
header = doc.within(0, (0, 700, 612, 92)).extract_text()
print(header)

Rust

use pdf_oxide::PdfDocument;
use pdf_oxide::geometry::Rect;

let mut doc = PdfDocument::open("invoice.pdf")?;
let header = doc.within(0, Rect::new(0.0, 700.0, 612.0, 92.0)).extract_text()?;
println!("{}", header);

JavaScript (WASM)

import { WasmPdfDocument } from "pdf-oxide-wasm";

const doc = new WasmPdfDocument(bytes);
const headerRegion = doc.within(0, [0, 700, 612, 92]);
console.log(headerRegion.extractText());
doc.free();

Go (helper de baixo nível, mesmo efeito)

package main

import (
    "fmt"
    "log"
    pdfoxide "github.com/yfedoseev/pdf_oxide/go"
)

func main() {
    doc, err := pdfoxide.Open("invoice.pdf")
    if err != nil { log.Fatal(err) }
    defer doc.Close()

    // ExtractTextInRect(pageIndex, x, y, width, height)
    header, _ := doc.ExtractTextInRect(0, 0, 700, 612, 92)
    fmt.Println(header)
}

C# (helper de baixo nível)

using PdfOxide;

using var doc = PdfDocument.Open("invoice.pdf");
string header = doc.ExtractTextInRect(0, 0, 700, 612, 92);
Console.WriteLine(header);

Extração encadeada a partir de uma região

A forma fluente within() em Python / Rust / WASM permite chamar qualquer método de extração sobre a mesma região sem precisar especificar o retângulo de novo:

Python

doc = PdfDocument("invoice.pdf")
region = doc.within(0, (400, 100, 200, 200))   # caixa 200×200 no canto inferior direito

total_text = region.extract_text()              # texto puro
words      = region.extract_words()             # registros a nível de palavra
chars      = region.extract_chars()             # registros a nível de caractere

Rust

let region = doc.within(0, Rect::new(400.0, 100.0, 200.0, 200.0));
let text  = region.extract_text()?;
let words = region.extract_words()?;

Casos de uso comuns

Extração de campos de nota fiscal

Uma nota fiscal costuma ter endereço do fornecedor, número da nota e tabela de itens em zonas fixas. Defina os retângulos uma vez por template:

from pdf_oxide import PdfDocument

TEMPLATES = {
    "acme_v1": {
        "invoice_no":  (450, 720,  120,  20),
        "issue_date":  (450, 700,  120,  20),
        "vendor_name": ( 50, 740,  300,  40),
        "total":       (450, 100,  120,  24),
    },
}

def parse_invoice(path, template):
    doc = PdfDocument(path)
    out = {}
    for field, rect in template.items():
        out[field] = doc.within(0, rect).extract_text().strip()
    return out

print(parse_invoice("invoice-2025-04.pdf", TEMPLATES["acme_v1"]))

Lançamentos de extrato bancário

A maior parte dos extratos tem uma faixa estreita de “transações”. Recorte essa faixa e chame extract_words() para obter cada linha na ordem de leitura com sua bbox:

doc = PdfDocument("statement.pdf")
for page in range(doc.page_count()):
    txn_region = doc.within(page, (36, 72, 540, 650))   # pular cabeçalho + rodapé
    for w in txn_region.extract_words():
        print(f"page {page}: {w.text} at ({w.x0:.0f},{w.y0:.0f})")

Remover cabeçalhos e rodapés

Se você só vai indexar o miolo do conteúdo, corte a parte de cima e de baixo de cada página:

Rust

let mut doc = PdfDocument::open("book.pdf")?;
for i in 0..doc.page_count()? {
    let body = doc.within(i, Rect::new(0.0, 100.0, 612.0, 600.0))
                  .extract_text()?;
    // indexar `body` …
}

Detecção de região de tabela

Quando você já sabe que uma página contém uma tabela e onde ela fica, restrinja extract_tables() ao retângulo dessa tabela:

Python

tables = doc.within(0, (50, 200, 500, 400)).extract_tables()
for t in tables:
    for row in t["rows"]:
        print([c["text"] for c in row["cells"]])

Referência de coordenadas

O PDF usa origem no canto inferior esquerdo, em pontos (1 pt = 1/72 de polegada). Uma página Letter é (0, 0, 612, 792). Para mirar a faixa superior de 1 polegada, escreva:

(x, y, w, h) = (0, 792 - 72, 612, 72)
             = (0, 720,      612, 72)

Se você vem do mundo de coordenadas de imagem (origem no topo), inverta y conforme necessário.

Para obter a MediaBox real da página antes de calcular:

Python

doc = PdfDocument("doc.pdf")
mb = doc.page_media_box(0)       # (llx, lly, urx, ury)

Rust

let mb = editor.get_page_media_box(0)?;   // [f32; 4]

Go / C# — helpers por retângulo

Go e C# ainda não oferecem a cadeia fluente within(), mas os métodos de baixo nível subjacentes são os mesmos:

Método Go C#
Texto no retângulo doc.ExtractTextInRect(page, x, y, w, h) doc.ExtractTextInRect(page, x, y, w, h)
Palavras no retângulo doc.ExtractWordsInRect(page, x, y, w, h) (ainda não empacotado)
Imagens no retângulo doc.ExtractImagesInRect(page, x, y, w, h) (ainda não empacotado)

Para padrões que precisam de vários tipos de extração sobre o mesmo retângulo em Go ou C#, guarde o retângulo em variáveis e chame os helpers sequencialmente. A superfície fluente virá assim que a API do editor estabilizar.

Páginas relacionadas