XL 2016 Macro pour convertir .PDF en .XLSX

saidoush

XLDnaute Junior
Bonjour,

J'ai tenté de reproduire les instructions d'une video en vu de convertir via une macro un document .pdf en .xlsx.

Chez lui,... ça marche lol 🥹

les seules différence c'est que moi j'utilise Foxit et l'adresse du fichier...(forcément)

Merci pour votre aide!!!
et bon dimanche.


Option Explicit

Sub convert_pdf_doc()

Dim foxitApp As Object
Dim av_doc As Object
Dim pdf_doc As Object
Dim jso_obj As Object

Dim sfile As String
Dim dfile As String
Dim ext As String

ext = "xlsx"
sfile = "C:\Users\FAMILLE\Documents\devis dentaire.pdf"
dfile = Replace(sfile, ".pdf", "." & ext, 1)


Set foxitApp = CreateObject("FoxitPDFReader.Application")

Set av_doc = foxitApp.GetActiveDoc()

If Not av_doc Is Nothing Then

Set pdf_doc = av_doc.GetPDDoc()
Set jso_obj = pdf_doc.GetJSObject

jso_obj.SaveAs dfile, "com.foxitpdf.reader." & ext

av_doc.Close

End If

Set foxitApp = Nothing
Set av_doc = Nothing
Set pdf_doc = Nothing
Set jso_obj = Nothing

End Sub
 

laurent950

XLDnaute Barbatruc
Bonsoir le forum,

J'ai complété le code, plus besoin de sélectionner via le document Word. Les tableaux sont récupérés, ainsi qu'une ligne dans un paragraphe multiligne.
a tester avec le fichier en Poste #1 ci-dessous :

A suivre pour les objets Shapes.

Un grand merci à @patricktoulon qui a donné l'astuce en Poste #37. de cette discussion.
Merci Patrick

VB:
Option Explicit
Sub ParcourirParagraphesTabMultiLignes()
    Dim wdWapp As Object ' .......................................................................................... Application Word
    Dim wdDoc As Document ' ......................................................................................... Le document word en cours d'analyse
    Dim wdParagraphe As Paragraph ' ................................................................................. Chaque paragraphe du document Word en cours
' Compteur
    Dim wdNbParagph As Long ' ....................................................................................... le numéro du paragraphe en cours
    Dim wdNbLignesParagph As Long ' ................................................................................. le nombre de lignes de chaque paragraphe
    Dim wdLigneIndex As Long ' ...................................................................................... l'index de la ligne en cours du paragraphe
    Dim wdTexteLigne As String ' .................................................................................... Texte de la ligne
    Dim wdWin As Long: wdWin = 1 ' .................................................................................. Numéro de la fenêtre Word (dans ce cas, la première fenêtre)
    Dim wdNoPage As Long: wdNoPage = 1 ' ............................................................................ Numéro de la page Word (dans ce cas, la première page)
' Les tableaux
    Dim wdTbl As Table ' ............................................................................................ Variable pour stocker une référence à un tableau dans le document Word
    Dim wdCel As Cell ' ............................................................................................. Variable pour stocker une référence à une cellule dans un tableau dans le document Word

    Set wdWapp = CreateObject("Word.Application") ' Créer une instance de l'application Word
        wdWapp.Visible = True    ' .................................................................................. Rendre l'application Word visible (facultatif)
' Ouvrir le document spécifié
    Set wdDoc = wdWapp.Documents.Open("E:\00_17-04-2024\Module VBA - PDF to Word_2024-04-17\" _
                                       & "Pour_Test_Images_Tableaux_Paragraphes Simple et MultilignesFacture.docx")
        wdDoc.Range(0, 0).Select ' .................................................................................. Déplacer la sélection au début du document
' Parcourir chaque paragraphe dans le document
    For Each wdParagraphe In wdDoc.Paragraphs
        wdNbParagph = wdNbParagph + 1 ' ............................................................................. Vérifier si le paragraphe n'est pas vide
        If Len(wdParagraphe.Range.Text) > 1 Then
            ' Si le paragraphe est dans un tableau Alors :
                If wdParagraphe.Range.Information(wdWithInTable) Then
                    If wdParagraphe.Range.Cells.Count > 0 Then
                        Set wdTbl = wdParagraphe.Range.Tables.Item(1) ' ............................................. Obtenir le tableau
                            Set wdCel = wdParagraphe.Range.Cells(1) ' ............................................... Obtenir la première cellule
                                If wdCel.RowIndex = 1 And wdCel.ColumnIndex = 1 Then
                                    'Debug.Print wdTbl.Cell(wdCel.RowIndex, wdCel.ColumnIndex).Range.Text ' ......... Afficher le texte de la cellule (du Tableau en cour)
                                                wdTbl.Cell(wdCel.RowIndex, wdCel.ColumnIndex).Range.Select ' ........ Sélectionner le contenu de la cellule (du Tableau en cour)
                                    ' Comme le curseur est actuellement dans la premiére cellule du tableau
                                                wdTbl.Select ' ...................................................... Sélectionne le premier tableau trouvé
                                    ' Bonus : debug.print de tableau à 2 dimensions
                                                Dim Tb2d() As Variant
                                            ' Redimensionnez la variable tableau 2D en fonction de la taille du tableau Word
                                                Dim regEx As Object
                                                    Set regEx = CreateObject("VBScript.RegExp")
                                                        regEx.Global = True
                                                        regEx.IgnoreCase = True
                                                        regEx.Pattern = "[\n\r\f\v]" ' Motif pour trouver les retours à la ligne, les retours chariot, etc.
                                                ReDim Tb2d(1 To wdTbl.Rows.Count, 1 To wdTbl.Columns.Count)
                                                Dim ligne As Long
                                                Dim colonne  As Long
                                                Dim n As Variant
                                                Dim maligne As String
                                                ' Boucle à travers chaque cellule du tableau Word et copiez-la dans la variable tableau 2D
                                                For ligne = 1 To wdTbl.Rows.Count
                                                    maligne = ""
                                                        For colonne = 1 To wdTbl.Columns.Count
                                                            Tb2d(ligne, colonne) = regEx.Replace(wdTbl.Cell(ligne, colonne).Range.Text, "") ' Supprime les retours à la ligne
                                                            'maligne = maligne & Tb2d(ligne, colonne) & " "
                                                            maligne = maligne & Tb2d(ligne, colonne) & vbTab  ' Ajoutez le contenu de la cellule avec un séparateur de tabulation
                                                        Next colonne
                                                Debug.Print Left(maligne, Len(maligne) - 1)
                                                Next ligne
                                                ligne = Empty: colonne = Empty: n = Empty: maligne = Empty
                                ' Non Utilisé ici.
                                ' Car le tableau doit être selectionné qu'une seule fois dans la boucle (PARAGRAPHE !)
                                ' Else
                                    'vDebug.Print wdTbl.Cell(wdCel.RowIndex, wdCel.ColumnIndex).Range.Text ' ........ Afficher le texte de la cellule suivante (du Tableau en cour)
                                               ' wdTbl.Cell(wdCel.RowIndex, wdCel.ColumnIndex).Range.Select ' ....... Sélectionner le contenu de la cellule suivante (du Tableau en cour)
                                End If
                    End If
                Else
            ' Si le Paragraphe n'est pas dans un tableau Alors :
                wdNbLignesParagph = wdParagraphe.Range.ComputeStatistics(wdStatisticLines) ' ........................ Obtenir le nombre de lignes du paragraphe
                    If wdNbLignesParagph = 1 Then ' ................................................................. Si le paragraphe a une seule ligne
                        ' Si le Paragraphe a une seule ligne Alors : ................................................ Sélectionner la ligne en cours
                            wdTexteLigne = wdParagraphe.Range.Text ' ................................................ Récupérer le texte de la ligne
                            Debug.Print wdTexteLigne ' .............................................................. Afficher le texte de la ligne dans la fenêtre de débogage
                            wdParagraphe.Range.Select ' ............................................................. Sélectionner la ligne
                    Else
                        'Si le Paragraphe comporte plusieurs lignes Alors : Sélectionner la ligne en cours
                            For wdLigneIndex = 1 To wdNbLignesParagph ' ............................................. Parcourir chaque ligne du paragraphe
                                Debug.Print wdWapp.Windows(wdWin).ActivePane.Pages(wdNoPage).Rectangles(wdNbParagph) _
                                            .Lines(wdLigneIndex).Range.Text ' ....................................... Afficher le texte de la ligne en cours
                                            wdWapp.Windows(wdWin).ActivePane.Pages(wdNoPage).Rectangles(wdNbParagph) _
                                            .Lines(wdLigneIndex).Range.Select ' ..................................... Sélectionner la ligne
                            Next wdLigneIndex
                    End If
                End If
        End If
    Next wdParagraphe
End Sub
 
Dernière édition:

patricktoulon

XLDnaute Barbatruc
re
Bonsoir @laurent950
perso je trouve absurde une fonction qui récupère tout morceau par morceau puis reconstitue le document sur excel
tu veux tout ????
ben c'est simple
VB:
Sub test()
    Dim fichier$
    fichier = "C:\Users\patricktoulon\Desktop\1-Prépa-Compétence - Présentation Diaporama.pdf.pdf"
    GetEntirePdfDocument fichier

End Sub
Function GetEntirePdfDocument(fichier)
    Dim WordApp As Object, WordDoc As Object, tim
    Application.ScreenUpdating = False
    Set WordApp = CreateObject("Word.Application")
    WordApp.Visible = False    'Vous pouvez définir ceci sur False si vous ne souhaitez pas afficher Word
    Set WordDoc = WordApp.Documents.Open(fichier)    'Remplacez le chemin par le chemin de votre fichier PDF
    WordApp.Documents(1).Content.Copy
    Set sh = Sheets.Add(after:=Sheets(Sheets.Count))
    sh.Name = "temporaire"
    sh.Paste
    'tim = Timer: Do While Timer - tim < 2: DoEvents: Loop
    Application.CutCopyMode = False
    WordDoc.Close False
    WordApp.Quit
    Set WordDoc = Nothing: Set WordApp = Nothing
    MsgBox "transfert du fichier pdf terminé"
End Function

terminé ;)

maintenant des petites fonctions pour récupérer les pargraphes ou les tables ou les shapes et images
là oui je pense que c'est utile
 

laurent950

XLDnaute Barbatruc
Bonsoir @patricktoulon,

Je voulais revenir sur le script que j'ai partagé dans le message #44.
Il fonctionne plutôt bien (Avec Acrobat Pro) lorsque le fichier ne contient qu'une seule page, que ce soit en PDF ou en Word.

Cependant, dès qu'il y a plusieurs pages, surtout avec plusieurs tableaux, le processus de copie vers Excel ne fonctionne plus aussi efficacement.

J'ai réfléchi à une autre approche basée sur le code que tu as partagé dans le message #47.

Je me demandais s'il serait possible de copier une page à la fois (Word) et de coller cette page (Word) dans la Feuil1 Excel, plutôt que de le faire en une seule fois (Pour Cause de cellules fusionné avec les tableaux.

Par exemple, copier la page 1 (Word) et la coller sur la Feuille 1 d'Excel, puis copier la page 2 (Word) et la coller à la suite de la feuil1 Excel (Avec le point d'insertion en dernière cellule non vide) juste en dessous (de ce qui à déjà était copier) toujours a la suite sur la même Feuille 1 Excel, et ainsi de suite.

Est-ce quelque chose qui pourrait être réalisable selon toi ?
 
Dernière édition:

patricktoulon

XLDnaute Barbatruc
ben je suppose que ca doit être un truc du genre
VB:
Sub copypage()
    Dim Wapp As Object, WdoC As Object
    Dim NoPage As Long, NoParagraphe As Long, NoLigne As Long, win As Long

    NoPage = 1
    NoParagraphe = 8
    NoLigne = 2
    win = 1

    ' Créer une instance de l'application Word
    Set Wapp = CreateObject("Word.Application")
    Wapp.Visible = True    ' facultatif

    ' Ouvrir le document PDF dans Word
    Set WdoC = Wapp.Documents.Open("C:\Users\patricktoulon\Desktop\1-Prépa-Compétence - Présentation Diaporama.pdf.pdf")

    ' Copier la première page
    Wapp.Windows(win).ActivePane.Pages(NoPage).Range.Copy

    ' Coller le contenu dans Excel
    ActiveSheet.Cells(NoLigne, 1).PasteSpecial Paste:=xlPasteValues
    'ou
    'ActiveSheet.Paste

    ' Fermer le document et quitter l'application Word
    WdoC.Close False:    Wapp.Quit
    Set WdoC = Nothing:    Set Wapp = Nothing
End Sub
 

laurent950

XLDnaute Barbatruc
Bonjour @patricktoulon

' ici c'est le programme windows ?
' Copier la première page Wapp.Windows(win).ActivePane.Pages(NoPage).Range.Copy
' Créer une instance de l'application Word
Dim Wapp As Object
Set Wapp = CreateObject("Word.Application")

' Classe Windows fenêtre (Excel VBA)
soit :
Dim win as Window
Set win = ActiveWindow

' Renvoie un objet Pane qui représente le volet actif de la fenêtre. En lecture seule
Soit :
Dim Pane As Pane
Set Pane = ActiveWindow.ActivePane

A Partir de la c'est les classes du programme Word ?
Pages(NoPage).Range.Copy
 

laurent950

XLDnaute Barbatruc
Bonsoir @patricktoulon

Je me concentre actuellement sur le modèle objet Word.

Je recherche la structure du modèle objet Word, car retrouver celle d'Excel est relativement simple, mais celle de Word est plus complexe.

Je pense que la meilleure approche serait de récupérer les segments un par un pour reconstituer le PDF dans Excel, car une simple opération de copier-coller ne préserve pas la mise en forme.

Merci beaucoup pour ton aide, Patrick.
 

patricktoulon

XLDnaute Barbatruc
je sais pas mais pour la chose et simple
quand je charge un pdf dans word il est parfaitement bien représenté dans son intégralité

Alors oui mais l'analyse est très complexe et il est vrai que les fonctions et membres de l'object word sont complexes
alors il y a une astuce toute simple
quand j'ouvre word je load le pdf
et bien je sauve le .document en HTML
et voila j'ai un html qui pour moi est un régal a farfouiller

bureau des astuces à patosch bonjour 😂
 

laurent950

XLDnaute Barbatruc
Re c'est pas évident.

Lorsque je récupère un document au format PDF ou Word, celui-ci peut contenir des zones de texte composées de paragraphes d'une ou de plusieurs lignes, ainsi que des tableaux 2D de tailles et de dimensions différentes.

Ci-Dessous reconnu en Tableau : dans le document (PDF ou Word)

IntitulerUQtésPUMT
AML10,00660


Mais aussi :
Ce qui complique la tâche, c'est que parfois les tableaux ne sont pas reconnus comme tels, mais écrit sur une même ligne.
C'est alors que le tableau ci-dessous doit est recomposé comme ci-dessus

VB:
Intituler               U         Qtés       PU            MT
       A                 ML       10,00       6             60

De plus, il arrive souvent que des cellules soient fusionnées dans ces tableaux.

Je m'efforce donc de reconstituer ces données dans leur format d'origine vers Excel.

Pour tous copier et coller en une seule fois :
Alors, lorsque je colle ces données dans Excel, la mise en forme est désorganisée, en particulier à cause de ces fameux tableaux à deux dimensions de tailles diverses.

En conséquence, je me retrouve confronté à la tâche laborieuse de reconstituer ces données segment par segment dans Excel. Je prends grand soin de préserver la mise en forme initiale tout en recalculant les positions de Word et en adaptant les cellules Excel pour qu'elles reflètent au mieux la position réelle dans Word.
 

Staple1600

XLDnaute Barbatruc
Re, Bonsoir @laurent950 , @patricktoulon

Apparemment je suis invisible...
laurent950 à dit:
Il fonctionne plutôt bien (Avec Acrobat Pro) lorsque le fichier ne contient qu'une seule page, que ce soit en PDF ou en Word.
Comme je le disais dans le message#50, à partir du moment où sur son PC, on a installé Acrobat
(je parle d'Acrobat et pas d'Acrobat Reader), pourquoi passer par une macro ?
Puisque qu'Acrobat permet nativement d'exporter un fichier PDF en plusieurs type de fichiers
HTML​
TXT​
RTF​
WORD​
EXCEL
XML​
Comme je le disais, c'est ce que je fais tous les jours au boulot et cela marche très bien​
(et Acrobat DC standard peut suffire)​
 

laurent950

XLDnaute Barbatruc
Bonsoir @Staple1600

Tu n'es pas invisible, j'ai déjà réalisé ce que tu décris dans ton poste #56

J'ai même fait le bout de code en Poste #44 et dont tu peux tester aussi sans oublier de connecter les bibliothèques Adobe Acrobat Pro avant d'utiliser le code.

Pour ma part c'est bien plus complexe que cela avec certains documents.
 

Staple1600

XLDnaute Barbatruc
Re

@laurent950
Quel intérêt de faire une macro ???
Quand depuis Adobe, il suffit de faire Fichier/Exporter vers et choisir Classeur XLSX
Ce que je décris dans le poste#56 se fait depuis Adobe et non depuis Excel (et ne nécessite pas de VBA)

C'est là mon interrogation: on a un outil Adobe qui sait faire tout seul la conversion (avec un simple clic)

Pourquoi donc ne pas l'utiliser ?

NB: Et si on parle d'Excel, avec Office 365, on peut avec PowerQuery importer les tables d'un PDF
(là aussi en n'utilisant que la souris)
Import_PDF.png
 

Chanbern

XLDnaute Nouveau
Bonjour,

J'ai tenté de reproduire les instructions d'une video en vu de convertir via une macro un document .pdf en .xlsx.

Chez lui,... ça marche lol 🥹

les seules différence c'est que moi j'utilise Foxit et l'adresse du fichier...(forcément)

Merci pour votre aide!!!
et bon dimanche.


Option Explicit

Sub convert_pdf_doc()

Dim foxitApp As Object
Dim av_doc As Object
Dim pdf_doc As Object
Dim jso_obj As Object

Dim sfile As String
Dim dfile As String
Dim ext As String

ext = "xlsx"
sfile = "C:\Users\FAMILLE\Documents\devis dentaire.pdf"
dfile = Replace(sfile, ".pdf", "." & ext, 1)


Set foxitApp = CreateObject("FoxitPDFReader.Application")

Set av_doc = foxitApp.GetActiveDoc()

If Not av_doc Is Nothing Then

Set pdf_doc = av_doc.GetPDDoc()
Set jso_obj = pdf_doc.GetJSObject

jso_obj.SaveAs dfile, "com.foxitpdf.reader." & ext

av_doc.Close

End If

Set foxitApp = Nothing
Set av_doc = Nothing
Set pdf_doc = Nothing
Set jso_obj = Nothing

End Sub
Pour convertir un pdf en fichier autre (texte, word, excel etc ) un logiciel gratuit fait le travail!! C'est
PDF24 Toolbox le complément de PDF24. Ci-joint le fichier obtenu à partir d'une facture en pdf (J'ai modifié le nom et les coordonnées.
J'avoue que PDF24 et ses "Outils" sont particulièrement étonnants
Bonjour,

J'ai tenté de reproduire les instructions d'une video en vu de convertir via une macro un document .pdf en .xlsx.

Chez lui,... ça marche lol 🥹

les seules différence c'est que moi j'utilise Foxit et l'adresse du fichier...(forcément)

Merci pour votre aide!!!
et bon dimanche.


Option Explicit

Sub convert_pdf_doc()

Dim foxitApp As Object
Dim av_doc As Object
Dim pdf_doc As Object
Dim jso_obj As Object

Dim sfile As String
Dim dfile As String
Dim ext As String

ext = "xlsx"
sfile = "C:\Users\FAMILLE\Documents\devis dentaire.pdf"
dfile = Replace(sfile, ".pdf", "." & ext, 1)


Set foxitApp = CreateObject("FoxitPDFReader.Application")

Set av_doc = foxitApp.GetActiveDoc()

If Not av_doc Is Nothing Then

Set pdf_doc = av_doc.GetPDDoc()
Set jso_obj = pdf_doc.GetJSObject

jso_obj.SaveAs dfile, "com.foxitpdf.reader." & ext

av_doc.Close

End If

Set foxitApp = Nothing
Set av_doc = Nothing
Set pdf_doc = Nothing
Set jso_obj = Nothing

End Sub
Il existe une application PDF24 avec une panoplie d'outils PDF24 Toolbox. Voici le résultat d'une conversion d'une facture en .pdf. (J'ai caché mes coordonnées).
 

Pièces jointes

  • FA018770.xlsx
    15.3 KB · Affichages: 5
  • FA018770.pdf
    125.6 KB · Affichages: 3

Discussions similaires

Statistiques des forums

Discussions
314 729
Messages
2 112 274
Membres
111 485
dernier inscrit
jondot