Skip to content

Extracción por región — Obtén contenido de un área específica

Cuando procesas facturas, extractos bancarios, formularios fiscales o cualquier diseño con plantilla, normalmente ya sabes dónde viven los campos. En vez de extraer toda la página y buscar el valor, apunta PDF Oxide al rectángulo exacto y recibirás solo lo que hay ahí.

La API fluida within(page, rect) devuelve una región acotada sobre la que puedes encadenar métodos de extracción: extract_text(), extract_words(), extract_chars(), extract_tables().

Cobertura de bindings. within(page, rect) está disponible en Python, Rust y WASM. Go y C# exponen los equivalentes de bajo nivel (ExtractTextInRect, ExtractWordsInRect, ExtractImagesInRect) — mira más abajo.

Ejemplo rápido

rect es (x, y, width, height) en puntos PDF, con el origen en la esquina inferior izquierda de la página. Las páginas tamaño Letter miden 612 × 792 puntos.

Python

from pdf_oxide import PdfDocument

doc = PdfDocument("invoice.pdf")

# Los 92 puntos superiores de la página 0 — banda típica del encabezado
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 bajo nivel, mismo efecto)

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 bajo nivel)

using PdfOxide;

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

Extracción encadenada desde una región

La forma fluida within() en Python / Rust / WASM te permite llamar cualquier método de extracción sobre la misma región sin volver a especificar el rectángulo:

Python

doc = PdfDocument("invoice.pdf")
region = doc.within(0, (400, 100, 200, 200))   # caja 200×200 inferior derecha

total_text = region.extract_text()              # texto plano
words      = region.extract_words()             # registros a nivel de palabra
chars      = region.extract_chars()             # registros a nivel de carácter

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 comunes

Extracción de campos de factura

Una factura suele tener la dirección del proveedor, el número de factura y la tabla de ítems en zonas fijas. Define los rectángulos una vez por plantilla:

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"]))

Movimientos de un extracto bancario

La mayoría de los extractos tienen una banda estrecha de “transacciones”. Recorta esa banda y llama a extract_words() para obtener cada línea en orden de lectura con su bbox:

doc = PdfDocument("statement.pdf")
for page in range(doc.page_count()):
    txn_region = doc.within(page, (36, 72, 540, 650))   # omitir encabezado + pie
    for w in txn_region.extract_words():
        print(f"page {page}: {w.text} at ({w.x0:.0f},{w.y0:.0f})")

Quitar encabezados y pies de página

Si solo indexas el cuerpo del contenido, recorta la parte superior e inferior 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` …
}

Detección de región de tabla

Cuando ya sabes que una página contiene una tabla y dónde está, acota extract_tables() solo a ese rectángulo:

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"]])

Referencia de coordenadas

PDF usa origen inferior izquierdo, medido en puntos (1 pt = 1/72 de pulgada). Una página Letter es (0, 0, 612, 792). Para apuntar a la banda superior de 1 pulgada, escribe:

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

Si vienes del mundo de coordenadas de imagen (origen superior izquierdo), invierte y de acuerdo con eso.

Para obtener el MediaBox real de una 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 rectángulo

Go y C# todavía no exponen la cadena fluida within(), pero los métodos subyacentes de bajo nivel son los mismos:

Método Go C#
Texto en rectángulo doc.ExtractTextInRect(page, x, y, w, h) doc.ExtractTextInRect(page, x, y, w, h)
Palabras en rectángulo doc.ExtractWordsInRect(page, x, y, w, h) (todavía no envuelto)
Imágenes en rectángulo doc.ExtractImagesInRect(page, x, y, w, h) (todavía no envuelto)

Si necesitas varios tipos de extracción sobre el mismo rectángulo en Go o C#, guarda el rectángulo en variables y llama a los helpers secuencialmente. La superficie fluida llegará cuando la API del editor se estabilice.

Páginas relacionadas