Extraire les informations texte d'un fichier PDF
Note : You can use Storga builtin PDF viewer in order to see the coordinates of a various text sequences in a PDF.
You can also select 'Grab: Debug' (ctrl+d&d left_button) in order to display the text séquences of a selected area.
Présentation du jeu d'instructions de décodage du texte contenu dans le fichier PDF
var File f
...
read_file f "pdf_text decimal [dq],[dq]"
each_pdf_text
...
L'option 'decimal' permet de spécifier à l'instruction 'value' (voir ci-dessous) le séparateur décimal utilisé dans le fichier PDF.
La fonction 'each_pdf_text' parcourt successivement les différentes séquences de texte dans le fichier PDF.
Il peut y avoir plusieurs séquences sur une même ligne.
Les séquences sont parcourues dans l'ordre des pages, puis des lignes, puis de gauche à droite.
Les éléments utilisables pendant l'exécution de la fonction 'each_pdf_text' sont :
|
text
|
La séquence de texte.
|
|
page
|
Le numéro de la page sur laquelle se trouve cette séquence.
|
|
new_page
|
Un booléen qui indique si la séquence de texte est la première de la page.
|
|
y
|
La position verticale en millimètres de la ligne. Zéro représente le dessus de la page.
|
|
x
|
La position horizontale en millimètres du début de la séquence. Zéro représente le bord gauche de la page.
|
|
box_x0 box_y0 box_x1 box_y1
|
La position en millimètres de la boite d'encombrement du texte.
|
|
vertical
|
Un booléen qui indique si le texte est tourné à 90°
|
|
ignore
|
Un booléen qui permet de marquer certaines séquences comme à ignorer par les instructions 'line' 'multiline' et 'area'
|
|
stop
|
Un booléen qui permet de marquer la séquence comme un stop pour l'instruction 'multiline'
|
|
section
|
Une chaîne de caractères que vous pouvez librement positionner pour identifier les différentes zones.
|
'ignore' 'stop' et 'section' servent à effectuer un décodage en plusieurs passes. Voir les exemples ci-dessous.
Voici maintenant les fonctions utilisables pendant l'exécution de la fonction 'each_pdf_text' :
|
range x0 x1
|
Retourne un booléen qui indique si la séquence de texte commence entre x0 et x1 millimètres du bord gauche. Ceci est donc équivalent à :
x>=x0 and x<=x1
|
|
line x0 x1
|
Retourne la concaténation des séquences sur la ligne en cours, qui commencent entre x0 et x1 millimètres du bord gauche. Les séquences avec l'attribut 'ignore' positionné ne sont pas prises en compte.
|
|
multiline x0 x1 multiline x0 x1 options
|
C'est un peut la même chose que 'line', mais les séquences trouvées sur des ligne en dessous sont ajoutées, séparées par des caractères retour à la ligne. Le parcours vers le bas s'arrête :
•
|
Quand on rencontre une séquence avec l'attribut 'stop' positionné, qui n'est pas sur la ligne en cours.
|
•
|
Quand on arrive au bas de la page.
|
Le paramètre option permet de mofifier ces règles. Voir ci-dessous.
|
|
area x0 y0 x1 y1 area x0 y0 x1 y1 options
|
Retourne la concaténation des séquences de la page en cours, qui commencent dans la zone spécifiée.
|
|
value t
|
Converti le texte sous forme de valeur décimale, en ignorant les caractères superflus, et en utilisant le séparateur décimal spécifié au niveau des options de l'instruction 'read_file'. Le plus souvent, on trouve utilise la fonction 'value' en complément de la fonction 'line'. Par exemple :
value:(line 50 70)
retourne la valeur numérique du texte qui commence entre 50 et 70 mm du bord gauche, sur la ligne en cours.
|
Voici les options que l'on peut utiliser au niveau des fonctions 'multiline' et 'area' :
|
continue
|
Ignore l'attribut 'stop'
|
|
space v
|
Arrête la collecte dès que l'espace entre deux lignes est supérieur ou égal à v millimètres.
|
|
cross
|
N'arrête pas la collecte au bas de la page. Utilisable uniquement dans la fonction 'multiline'.
|
L'exemple suivant extrait le paragraphe sous le libellé 'Pour nous joindre :', sachant que la fin de ce paragraphe est matérialisée par un saut de ligne de 5 mm ou plus :
each_pdf_text
if text="Pour nous joindre :"
var Str contact := area 0 y+1 210 999 "space 5"
Un exemple de décodage d'une table
Voici un exemple permettant de décoder le détail des opération d'un relevé de banque. Chaque opération est présentée sous forme d'une date dans la colonne 10-30 mm, d'un libellé multi-lignes dans la colonne 40-140 mm, et d'un débit ou crédit dans les colonnes 140-170, et 170-200 mm.
A la première passe, on positionne les attributs 'stop'.
A la seconde, on peut utiliser l'instruction 'multiline' pour extraire facilement les libellés multilignes.
# Première passe :
each_pdf_text
if (range 10 30) and (text parse (var Int day) "/" (var Int month) "/" (var Int year)) # on a trouvé une date d'opération
stop := true
if text="suite >>>"
stop := true
if text="TOTAUX DES MOUVEMENTS"
stop := true
# Seconde passe
each_pdf_text
if (range 10 30) and (text parse (var Int day) "/" (var Int month) "/" (var Int year))
var Date d := date year month day
var Float m := -1 * value:(line 140 170)
if t_amount=undefined
t_amount := value (line 170 200)
var Str l := multiline 40 140 # le libellé