Extraer texto PDF por columnas en orden de lectura
Cuatro bloques desordenados de una página a dos columnas vuelven como izquierda primero, izquierda segundo, derecha primero y derecha segundo. Las columnas se detectan por bordes izquierdos parecidos y se leen de izquierda a derecha y de arriba abajo. Gratis en su navegador.
- Gratis
- Funciona en su navegador
- Sin registro
- Sus datos no salen de su equipo
Ejecutar — gratis
La extracción de texto de un PDF puede recuperar las palabras correctamente y, aun así, entregarlas en una secuencia inútil. En páginas con dos o más columnas, ordenar solo de arriba abajo mezcla párrafos que no guardan relación. Esta capacidad recibe bloques de texto con sus cuadros delimitadores, identifica cuáles pertenecen a la misma columna, ordena las columnas de izquierda a derecha y cada columna de arriba abajo. El resultado incluye el texto reconstruido y toda la geometría ordenada para revisarla o procesarla después.
Por qué se pierde el orden de lectura al extraer un PDF
Un PDF suele describir dónde se dibujan los glifos, no el orden semántico en que una persona debe leerlos. Por ello, las bibliotecas de extracción pueden devolver bloques según el flujo interno de objetos, el orden de dibujo o una ordenación vertical global que salta entre columnas. Un artículo a dos columnas puede aparecer como el primer párrafo izquierdo, el primero derecho y después el segundo izquierdo.
Envíe cada bloque extraído con su texto, coordenada izquierda, coordenada superior, anchura y altura. La capacidad emplea esa geometría para deducir grupos con bordes izquierdos similares. Todas las coordenadas deben pertenecer al mismo sistema de la página y `y` debe representar el borde superior del bloque.
Cómo se detectan columnas de forma determinista
La pertenencia a una columna se decide por la distancia entre las coordenadas izquierdas de los bloques. De forma predeterminada, la tolerancia equivale a una cuarta parte de la anchura positiva mediana. Así se adapta a escalas habituales y admite pequeñas sangrías o imprecisiones de extracción dentro de una columna.
Un valor menor separa bloques cuyos bordes difieren ligeramente; uno mayor reúne párrafos sangrados o encabezados con la columna circundante. Tras agruparlos, las columnas se ordenan por su posición izquierda media. Dentro de cada una, los bloques se ordenan por posición superior, posición izquierda e índice original.
Estos desempates garantizan resultados idénticos cuando varios cuadros comparten coordenadas. El algoritmo no utiliza red, aleatoriedad, hora actual, OCR ni modelos de lenguaje.
Cómo utilizar el resultado ordenado en su flujo documental
Mantenga los arrays estructurados si necesita procedencia, resaltado, superposiciones sobre la página o depuración; use el texto unido para búsquedas, resúmenes, accesibilidad o exportación. Esta capacidad no analiza archivos PDF ni realiza OCR: debe alimentarla con bloques de su extractor. Tampoco identifica tablas, barras laterales, titulares que abarcan varias columnas, notas al pie ni continuaciones entre páginas.
Qué puede hacer con ella
Preparar artículos para búsquedas
Convierta bloques de revistas o boletines a dos columnas en texto coherente antes de indexarlos.
Crear exportaciones accesibles
Genere una secuencia predecible para lectores de pantalla o conversiones a documentos accesibles.
Auditar una canalización de extracción
Conserve cuadros ordenados e índices de origen para explicar la posición asignada a cada párrafo.
Preguntas frecuentes
¿Acepta esta capacidad un archivo PDF?
No. Recibe bloques de texto ya extraídos de una página PDF, junto con sus cuadros delimitadores.
¿Cómo se detectan las columnas?
Se agrupan los bloques cuyas coordenadas izquierdas son suficientemente parecidas.
¿Cuánto cuesta?
La misma lógica determinista también puede ejecutarse en el navegador como capacidad de nivel A.
¿Puedo enviar varias páginas a la vez?
Envíe una página cada vez. Las posiciones de páginas distintas no se pueden comparar salvo que usted las lleve antes a una escala común, así que mezclarlas desordenaría las columnas.
¿Reconoce tablas, recuadros laterales o notas al pie?
No. Solo ordena el texto por columna y por altura en la página. Las tablas, los recuadros, los titulares que ocupan varias columnas y las notas al pie no se deducen, así que márquelos antes o ajuste la tolerancia de columna y revise el resultado.
Herramientas relacionadas
Para desarrolladores — acceso por API
Todo lo de esta página está disponible por programación. Esta sección es para equipos que quieren integrarlo en sus sistemas; el resto puede usar la herramienta de arriba sin más.
Endpoint de API
¿Prefiere automatizarlo? Un POST autenticado crea la tarea; el resultado llega por webhook o enlace firmado. La misma capacidad también se ejecuta aquí en la web, por email y desde Telegram — y pronto también desde nuestra app.
Llámela desde su stack
curl -X POST https://api.kit.forhosting.com/pdf/text-extract-column-order \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"blocks":[{"text":"Left heading","x":40,"y":40,"width":210,"height":20},{"text":"Right heading","x":320,"y":42,"width":210,"height":20},{"text":"Right body","x":322,"y":90,"width":208,"height":60},{"text":"Left body","x":42,"y":92,"width":208,"height":60}]}'const res = await fetch("https://api.kit.forhosting.com/pdf/text-extract-column-order", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"blocks": [
{
"text": "Left heading",
"x": 40,
"y": 40,
"width": 210,
"height": 20
},
{
"text": "Right heading",
"x": 320,
"y": 42,
"width": 210,
"height": 20
},
{
"text": "Right body",
"x": 322,
"y": 90,
"width": 208,
"height": 60
},
{
"text": "Left body",
"x": 42,
"y": 92,
"width": 208,
"height": 60
}
]
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/pdf/text-extract-column-order",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"blocks": [
{
"text": "Left heading",
"x": 40,
"y": 40,
"width": 210,
"height": 20
},
{
"text": "Right heading",
"x": 320,
"y": 42,
"width": 210,
"height": 20
},
{
"text": "Right body",
"x": 322,
"y": 90,
"width": 208,
"height": 60
},
{
"text": "Left body",
"x": 42,
"y": 92,
"width": 208,
"height": 60
}
]
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/pdf/text-extract-column-order", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"blocks":[{"text":"Left heading","x":40,"y":40,"width":210,"height":20},{"text":"Right heading","x":320,"y":42,"width":210,"height":20},{"text":"Right body","x":322,"y":90,"width":208,"height":60},{"text":"Left body","x":42,"y":92,"width":208,"height":60}]}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"blocks":[{"text":"Left heading","x":40,"y":40,"width":210,"height":20},{"text":"Right heading","x":320,"y":42,"width":210,"height":20},{"text":"Right body","x":322,"y":90,"width":208,"height":60},{"text":"Left body","x":42,"y":92,"width":208,"height":60}]}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/pdf/text-extract-column-order", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Ejemplo de solicitud
{
"blocks": [
{
"text": "Left heading",
"x": 40,
"y": 40,
"width": 210,
"height": 20
},
{
"text": "Right heading",
"x": 320,
"y": 42,
"width": 210,
"height": 20
},
{
"text": "Right body",
"x": 322,
"y": 90,
"width": 208,
"height": 60
},
{
"text": "Left body",
"x": 42,
"y": 92,
"width": 208,
"height": 60
}
]
}Ejemplo de respuesta
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "pdf.text_extract_column_order",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}La API es asíncrona: la llamada devuelve un task_id al instante y el resultado llega por webhook. El polling está limitado a 1 req/s por tarea.
Precio
Precio publicado — sin tokens ni créditos inventados. Una tarea fallida no se cobra.
Límites
max_items | 10000 |
Errores
| HTTP | Código | Significado |
|---|---|---|
401 | unauthorized | API key ausente o inválida. |
402 | insufficient_balance | El saldo no cubre el precio de la tarea. |
404 | unknown_type | El tipo de tarea no existe. |
429 | rate_limited | Demasiadas peticiones. Use el webhook en vez de sondear. |
Notas técnicas
Por qué se pierde el orden de lectura al extraer un PDF
Luego coloca las columnas de izquierda a derecha y ordena sus bloques de arriba abajo. `reading_order` conserva la geometría original y el índice de origen, para que usted pueda comprobar cada posición en vez de confiar en una transformación opaca que solo devuelve texto.
Cómo se detectan columnas de forma determinista
En documentos con geometría inusual, indique `column_tolerance`.
Cómo utilizar el resultado ordenado en su flujo documental
La respuesta ofrece varias vistas de una misma decisión. `columns` muestra cada columna detectada y sus bloques ordenados. `reading_order` aplana esas columnas en la secuencia exacta que debe consumir el siguiente proceso. `text` une el contenido con un separador configurable; por defecto inserta una línea en blanco para conservar los límites entre párrafos. Procese una página PDF por solicitud, pues las coordenadas de páginas distintas no son comparables sin normalizarlas. Si esas estructuras importan, clasifíquelas antes o ajuste `column_tolerance` y revise las columnas devueltas.
Preguntas técnicas
¿Qué sucede si no se proporcionan bloques?
La solicitud falla con `invalid_input`, porque no se puede deducir un orden de lectura sin bloques de texto.
¿Qué sistema de coordenadas debo utilizar?
Sirve cualquier sistema coherente por página, siempre que `x` sea la coordenada izquierda y `y` la superior de todos los bloques.