[Python] Transfert de données d'un formulaire PDF rempli dans Calc

Vos meilleures macros et portions de code sont publiées dans cette section.
Aucun support sur une question de programmation ici !

Modérateur : Vilains modOOs

Règles du forum
Aucune question dans cette section !
Celle-ci rassemble les meilleures macros et portions de code. Vous pouvez en revanche commenter ou argumenter le code exposé. Vous pouvez même remercier l'auteur (cela fait toujours plaisir) en indiquant par exemple dans quel cadre ou contexte vous en avez eu l'utilité.
Si vous avez à poster quelque chose, faites-le depuis la section Macros et API et demandez à un modérateur de l'y déplacer.
Avatar de l’utilisateur
Jurassic Pork
PassiOOnné
PassiOOnné
Messages : 629
Inscription : 09 août 2017 22:15

[Python] Transfert de données d'un formulaire PDF rempli dans Calc

Message par Jurassic Pork »


La modération vous a écrit: Titre modifié : [Calc] s'applique pour du Basic exclusivement

Hello,
je vous propose une macro en python qui extrait les données d'un formulaire PDF rempli et vient les mettre dans une feuille de calc.
Pour faire fonctionner cette macro il vous faut la nouvelle version de l'extension APSO (voir ici). Grâce à cette nouvelle version, on peut installer dans le python de votre suite bureautique, des bibliothèques python disponibles sur le dépôt python pypi. Pour la macro on va utiliser le paquet python pypdf2. Ce module peut fonctionner sous OpenOffice et LibreOffice.
La première chose à faire est d'installer PyPDF2. Pour cela utiliser le gestionnaire de paquets d'APSO (voir comment l'utiliser ici dans le fichier PDF joint). Dans le champ Paquet taper pypdf2 et cliquer sur le bouton Installer paquet. Normalement pip va aller chercher la version du paquet qui correspond au python de votre suite bureautique.

Le classeur possède une feuille Collecte pour afficher les données (cliquer sur le bouton Extract Data après avoir rempli les paramètres) et une feuille Params pour paramètrer la récupération des données.
Dans la feuille Params il y a :
Fichier PDF : chemin du fichier PDF à lire
Destination : cellule de départ où seront mises les données extraites.
Vertical : indique dans quel sens seront disposées les données dans la feuille.
Si Vertical = oui : la première colonne contient le nom des champs du formulaire PDF et la deuxième colonne les valeurs de ces champs.
Si Vertical = non : les noms des champs sont écrits sur la première ligne de la cellule de départ, les valeurs sur la première ligne vide en dessous.
En pièce jointe le classeur de test et un formulaire PDF rempli.
Voici le code de la macro qui est "embarqué" dans le classeur de test :

Code : Tout sélectionner

# coding: utf-8
# Jurassic Pork Feb 2024
from __future__ import unicode_literals
import uno
from PyPDF2 import PdfReader

try:
    CTX = uno.getComponentContext()
    SM = CTX.getServiceManager()
    desktop = XSCRIPTCONTEXT.getDesktop()
    ODOC = desktop.getCurrentComponent()
    parentwin = ODOC.CurrentController.Frame.ContainerWindow
    dispatcher = SM.createInstanceWithContext("com.sun.star.frame.DispatchHelper", CTX)
    model = desktop.getCurrentComponent()
except:
    print("ModulePDF init Error")
    
def extractData(*args):
    vertical = model.NamedRanges.getByName("Vertical").getReferredCells().getString()
    horizontal = False if vertical=='oui' else True
    pdfFile = model.NamedRanges.getByName("pdfFile").getReferredCells().getString()
    header = model.NamedRanges.getByName("Dest").getReferredCells().getString()
    oFeuille = ODOC.getSheets().getByName("Collecte")
    reader = PdfReader(pdfFile)
    fields = reader.get_form_text_fields()
    if horizontal:
        tupHeader = (tuple([k for k, v in fields.items()]),)
        tupData = (tuple([v for k, v in fields.items()]),)
        cursor = oFeuille.createCursorByRange(oFeuille.getCellRangeByName(header))
        cursor.collapseToSize( len(tupHeader[0]) , 1 )
        cursor.setDataArray(tupHeader)
        cursor.gotoEnd()
        cursor = oFeuille.createCursorByRange(oFeuille.getCellRangeByName("A" + str(cursor.RangeAddress.EndRow + 2)))
        cursor.collapseToSize( len(tupData[0]) , 1)
        cursor.setDataArray(tupData)
    else:
        tup = tuple([(k, v) for k, v in fields.items()])
        cursor = oFeuille.createCursorByRange(oFeuille.getCellRangeByName(header))
        cursor.collapseToSize( len(tup[0]) , len(tup) )
        cursor.setDataArray(tup)
        
g_exportedScripts = extractData, 
Le classeur a été testé avec ces configurations :
Ubuntu 20.04 L.O 24.2.0.3 pypdf2 3.0.1 - A.O.O 4.1.15 pypdf2 1.28.6
Windows 11 L.O 7.4.6.2 pypdf2 3.0.1 - A.O.O 4.1.14 pypdf2 1.28.6
Macos 10.15 L.O 24.2.0.3 pypdf2 3.0.1 - A.O.O 4.1.12 pypdf2 1.28.6
CollectePDF.gif
Ami calmant, J.P
Vous ne pouvez pas consulter les pièces jointes insérées à ce message.
LibreOffice 7.6.2.1 et OpenOffice 4.1.15 sous windows 11
LibreOffice 24.2.0 et OpenOffice 4.1.15 sous Ubuntu 20.04