Extraire le texte PDF en colonnes dans l’ordre de lecture
Quatre blocs mélangés d'une page à deux colonnes reviennent dans l'ordre gauche premier, gauche second, droite premier et droite second. Les colonnes sont repérées par des bords gauches proches, puis lues de gauche à droite et de haut en bas. Gratuit dans votre navigateur.
- Gratuit
- Fonctionne dans votre navigateur
- Sans inscription
- Vos données restent sur votre appareil
Lancer gratuitement
L’extraction d’un PDF peut restituer tous les mots correctement, mais dans une séquence inutilisable. Sur une page à plusieurs colonnes, un simple tri vertical alterne entre des paragraphes sans rapport. Cette capacité reçoit les blocs avec leurs cadres, reconnaît ceux d’une même colonne, ordonne les colonnes de gauche à droite, puis leurs blocs de haut en bas. Le résultat contient le texte reconstruit et toute la géométrie ordonnée afin que vous puissiez la contrôler ou la réutiliser.
Pourquoi l’extraction perd l’ordre de lecture
Un PDF décrit généralement l’endroit où les glyphes sont dessinés, et non l’ordre sémantique dans lequel une personne doit les lire. Les bibliothèques peuvent donc restituer les blocs selon le flux d’objets, l’ordre de dessin ou un tri vertical global qui saute d’une colonne à l’autre. Un article sur deux colonnes peut devenir le premier paragraphe gauche, le premier droit, puis le deuxième gauche.
Fournissez chaque bloc avec son texte, sa coordonnée gauche, sa coordonnée supérieure, sa largeur et sa hauteur. Cette capacité exploite cette géométrie pour déduire les groupes dont les bords gauches sont proches. Toutes les coordonnées doivent appartenir au même repère de page et `y` doit désigner le haut du bloc.
Une détection des colonnes entièrement déterministe
L’appartenance à une colonne dépend de la distance entre les coordonnées gauches des blocs. Par défaut, la tolérance vaut un quart de la largeur positive médiane. Elle s’adapte ainsi aux échelles courantes tout en absorbant les petits retraits et le bruit d’extraction.
Une valeur faible sépare des bords légèrement différents ; une valeur élevée rattache les paragraphes en retrait ou les titres à leur colonne. Après regroupement, les colonnes sont classées selon leur position gauche moyenne. Leurs blocs sont classés par position supérieure, position gauche, puis indice initial.
Ces départages assurent un résultat stable lorsque des cadres partagent leurs coordonnées. L’algorithme n’utilise ni réseau, ni hasard, ni heure courante, ni OCR, ni modèle de langage.
Exploiter le résultat dans votre chaîne documentaire
Conservez les tableaux structurés pour la traçabilité, le surlignage, les calques de page ou le débogage ; employez le texte assemblé pour l’indexation, le résumé, l’accessibilité ou l’export. Cette capacité n’analyse pas le fichier PDF et n’effectue pas d’OCR : fournissez les blocs issus de votre extracteur. Elle ne reconnaît pas non plus les tableaux, encadrés, titres transversaux, notes de bas de page ou enchaînements entre pages.
Cas d’usage
Préparer des articles pour la recherche
Transformez les blocs d’une revue ou lettre à deux colonnes en texte cohérent avant l’indexation.
Créer des exports accessibles
Produisez une séquence prévisible pour un lecteur d’écran ou une conversion accessible.
Auditer une chaîne d’extraction
Conservez les cadres ordonnés et indices sources pour justifier la place de chaque paragraphe.
Questions fréquentes
Cette capacité accepte-t-elle un fichier PDF ?
Non. Elle reçoit les blocs déjà extraits d’une page PDF, avec leurs cadres.
Comment les colonnes sont-elles détectées ?
Les blocs dont les coordonnées gauches sont assez proches sont regroupés.
Quel est le tarif ?
La même logique déterministe peut aussi s’exécuter dans le navigateur comme capacité de niveau A.
Puis-je envoyer plusieurs pages à la fois ?
Envoyez une page à la fois. Les positions de pages différentes ne sont pas comparables tant que vous ne les ramenez pas vous-même à une échelle commune, et les mélanger brouillerait les colonnes.
Reconnaît-il les tableaux, les encadrés ou les notes de bas de page ?
Non. Il ordonne le texte uniquement par colonne et par hauteur sur la page. Tableaux, encadrés, titres sur plusieurs colonnes et notes de bas de page ne sont pas devinés, alors marquez-les avant ou ajustez la tolérance de colonne et vérifiez le résultat.
Outils associés
Pour les développeurs — accès API
Tout sur cette page est disponible par programmation. Cette section s'adresse aux équipes qui veulent l'intégrer à leurs systèmes ; les autres peuvent simplement utiliser l'outil ci-dessus.
Endpoint
Authentification par jeton Bearer : un seul POST met la tâche en file d’attente, et le résultat vous parvient par webhook ou lien signé.
Appeler depuis votre 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)Exemple de requête
{
"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
}
]
}Exemple de réponse
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "pdf.text_extract_column_order",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}L’API est asynchrone : chaque appel renvoie un task_id immédiatement, puis vous interrogez l’état à raison d’une requête par seconde.
Tarifs
Le prix est publié, sans tokens ni crédits. Une tâche qui échoue n’est pas facturée.
Limites
max_items | 10000 |
Erreurs
| HTTP | Code | Signification |
|---|---|---|
401 | unauthorized | Clé API absente ou invalide : vérifiez l’en-tête Authorization. |
402 | insufficient_balance | Solde insuffisant : rechargez votre compte pour lancer cette tâche. |
404 | unknown_type | Type de tâche inconnu : vérifiez le champ type de votre requête. |
429 | rate_limited | Trop de requêtes : ralentissez la cadence, puis réessayez. |
Notes techniques
Pourquoi l’extraction perd l’ordre de lecture
Elle place ensuite les colonnes de gauche à droite et leurs blocs de haut en bas. `reading_order` conserve la géométrie et l’indice source : vous pouvez vérifier chaque classement au lieu de faire confiance à une transformation opaque.
Une détection des colonnes entièrement déterministe
Pour une géométrie atypique, indiquez `column_tolerance`.
Exploiter le résultat dans votre chaîne documentaire
La réponse présente plusieurs vues de la même décision. `columns` expose chaque colonne détectée avec ses blocs ordonnés. `reading_order` les aplatit dans la séquence exacte à transmettre au traitement suivant. `text` assemble les contenus avec un séparateur configurable, par défaut une ligne vide afin de préserver les paragraphes. Traitez une page PDF par requête, car les coordonnées de pages distinctes ne sont pas comparables sans normalisation. Préclassez ces éléments si nécessaire, ou réglez `column_tolerance` et contrôlez les affectations renvoyées.
Questions techniques
Que se passe-t-il si aucun bloc n’est fourni ?
La requête échoue avec `invalid_input`, car aucun ordre de lecture ne peut être déduit sans bloc de texte.
Quel repère de coordonnées faut-il utiliser ?
Tout repère cohérent convient si `x` désigne la gauche et `y` le haut de chaque bloc.