XL 2021 VBA - Enregistrer en fichier un Embbeded PDF créé en présence d'Adobe Acrobat sur le PC

  • Initiateur de la discussion Initiateur de la discussion Dudu2
  • Date de début Date de début

Boostez vos compétences Excel avec notre communauté !

Rejoignez Excel Downloads, le rendez-vous des passionnés où l'entraide fait la force. Apprenez, échangez, progressez – et tout ça gratuitement ! 👉 Inscrivez-vous maintenant !

Dudu2

XLDnaute Barbatruc
Bonjour,

Je n'utilise généralement pas Adobe Acrobat pour visualiser les PDF, lui préférant PDF-XChange Viewer plus léger et moins invasif.
Cependant l'ayant installé, il créé de nombreux problèmes avec les PDF intégrés (embbeded).

Ce logiciel intrusif modifie les propriétés du PDF embbeded et rend impossible l'ouverture par un autre logiciel qu'Acrobat alors que sous PDF-XChange Viewer, le PDF embbeded peut être ouvert par n'importe quel PDF Viewer.
De plus il faut désactiver le "Mode protégé au démarrage" (Acrobat / Menu / Préférence / Protection (renforcée) / Décocher "Activer le mode protégé au démarrage") pour visualiser les PDF embbeded.

Si j'arrive sans problème à enregistrer en fichier un PDF qui a été intégré (embbeded) en l'absence d'Adobe Acrobat sur le PC (seulement PDF-XChange Viewer), je n'y arrive pas lorsque le PDF a été intégré (embbeded) en présence d'Adobe Acrobat sur le PC.

La question: comment enregistrer en fichier un PDF qui a été intégré (embbeded) en présence d'Adobe Acrobat sur le PC ? (Voir le fichier joint).
Ou alors comment modifier les propriétés du PDF embbeded pour qu'il soit ouvrable par n'importe quel PDF Viewer ?

Justification: en enregistrant en fichier le PDF intégré en présence d'Acrobat, on pourrait alors le lancer quelque soit le PDF Viewer installé.
 

Pièces jointes

Dernière édition:
Solution
pas besoin de renommer il faut en fait explorer le fichier qui est ouvert pour extraire les .bin qui correspondent aux PDF intégrés . Ces .bin ils contiennent les PDF mais il faut "décapsuler" les PDF des .bin qui sont en OLE.
Pour la deuxième question c'est bizarre j'ai mis ton message intégral.
Je viens d'essayer de "décapsuler" les 2 .bin qui sont dans ton classeur avec Notepad++. Ben apparemment il suffit de chercher la chaine %PDF et de supprimer tout ce qu'il y a avant. En donnant des extensions .pdf alors à ces fichiers , j'arrive à les lire sans problème avec un lecteur PDF.
Voici du code VBA généré par I.A (j'ai seulement suggéré à l'I.A d'utiliser le tar windows et de supprimer ce qu'il y a avant %PDF ) qui :
1 -...
Salut Dudu2,
tu devrais avoir recours à l'I.A car tu poses une question très clairement. Avec l'I.A l'avantage c'est qu'elle te répond tout de suite, essaie de te dire d'où vient le problème et te propose des solutions. J'ai mis ton message comme question à ChatGpt et voici ce qu'il m'a répondu :

Ta question est très pertinente — et c’est un problème réellement connu avec Adobe Acrobat qui s’arroge le contrôle exclusif des PDF « embedded » (intégrés), notamment dans des fichiers Word, Excel, ou même d’autres PDF (PDF dans PDF).
Voici une explication claire, puis plusieurs solutions techniques selon le niveau d’accès que tu veux garder.

🔍 Pourquoi cela se produit​

Quand Adobe Acrobat est installé, il :
  • enregistre des classes COM et des associations de fichiers (ActiveX, OLE, MIME) qui font que Windows considère Acrobat comme le seul gestionnaire des objets PDF embarqués ;
  • modifie le handler d’objet embeddé (PDF.1, PDF.2, etc.) dans la base de registre ;
  • et, si le « mode protégé » est activé, empêche l’accès aux fichiers PDF embarqués par d’autres applications (sécurité sandbox).
Ainsi, quand un PDF est intégré (embbeded) dans un autre document (souvent un .docx ou un .pdf contenant un autre .pdf) en présence d’Acrobat, Windows/OLE inscrit que ce PDF doit être ouvert avec Acrobat exclusivement.
PDF-XChange Viewer, Foxit, Sumatra, etc., n’arrivent alors plus à l’extraire ou le visualiser directement.

🧰 Solutions possibles​

✅ Solution 1 — Extraire manuellement le PDF intégré (sans Acrobat)​

Si le PDF est intégré dans un autre fichier (Word, Excel, ou PDF) :

🪟 Si c’est un PDF intégré dans Word/Excel :​

  1. Ouvre le fichier contenant l’objet.
  2. Clique droit sur l’icône du PDF intégréObjet PDF → Exporter (si possible).
  3. Si cette option n’existe pas :
    • Clique droit → Packager l’objetEnregistrer sous (ou glisse sur le Bureau).
  4. Si tout échoue : renomme ton .docx en .zip, puis :
    • Ouvre le ZIP,
    • Va dans le dossier word/embeddings/,
    • Tu trouveras un fichier du type oleObject1.bin → extrait-le.
    • Convertis ce .bin en PDF avec un extracteur OLE, par exemple avec 7-Zip, 7ttx OLE Extractor, ou un script Python (je peux t’en générer un si tu veux).

📄 Si c’est un PDF intégré dans un autre PDF :​

Tu peux utiliser PDF-XChange Editor (version gratuite) ou PDFsam Basic :
  • Menu : Document → Attachments → Export
  • Cela te permet de récupérer le fichier PDF original, même s’il est tagué “Adobe PDF Embedded Object”.

✅ Solution 2 — Réinitialiser le gestionnaire OLE des PDF à PDF-XChange​

Adobe change la clé OLE suivante dans le Registre Windows :
Code:
HKEY_CLASSES_ROOT\AcroExch.Document.DC
ou selon version :
Code:
HKEY_CLASSES_ROOT\AcroExch.Document.7
Pour revenir à PDF-XChange :
  1. Ferme Acrobat et tes viewers.
  2. Lance regedit.
  3. Recherche les clés suivantes :
    Code:
    HKEY_CLASSES_ROOT\AcroExch.Document.DC
    HKEY_CLASSES_ROOT\AcroExch.Document.7
    HKEY_CLASSES_ROOT\.pdf
  4. Sauvegarde ces clés (clic droit > Exporter).
  5. Modifie la valeur par défaut de .pdf pour qu’elle pointe vers :
    Code:
    PDFXView.PDF
    au lieu de AcroExch.Document.DC.
  6. Redémarre Windows.
Cela permet de désassocier Acrobat des objets OLE PDF et rend à PDF-XChange (ou tout autre viewer) le droit de les ouvrir.

✅ Solution 3 — Modifier les propriétés du PDF embbeded​

Si tu veux rendre le PDF “neutre”, sans restriction Adobe :
  1. Ouvre-le dans Acrobat (malgré tout).
  2. Va dans :
    • Fichier → Propriétés → Sécurité
    • Change la sécurité en Aucune sécurité (si ce n’est pas déjà le cas).
  3. Ensuite, réenregistre le PDF avec un autre nom.
  4. Ouvre ce nouveau PDF dans PDF-XChange Viewer, puis intègre-le à nouveau dans ton document.
    → Cette version ne contiendra plus les métadonnées “Adobe-only”.

✅ Solution 4 — Supprimer le mode protégé Adobe (temporairement)​

Tu l’as déjà mentionné, mais pour que ce soit clair :
Acrobat → Menu → Préférences → Protection (renforcée) → décocher « Activer le mode protégé au démarrage ».
Cela permet de rouvrir des PDF embeddés qui étaient “sandboxés”.

💡 En résumé​

ObjectifMéthode
Extraire un PDF intégré dans un documentExporter via PDF-XChange ou renommer .docx en .zip
Forcer PDF-XChange comme lecteur OLE par défautModifier les clés de registre .pdf et AcroExch.Document.*
Rendre le PDF “universel”Réouvrir et réenregistrer sans sécurité dans Acrobat
Contourner la protection AcrobatDésactiver le mode protégé temporairement
 
Merci @nullosse, tu as les bons réflexes.
Quelle question as-tu posée exactement à ChatGPT ?

Et ça confirme qu'Acrobat est une belle daube se permet de s'attribuer l'exclusivité de la gestion des embbeded objects qu'il peut ouvrir.

Le problème demeure car la solution 1 que j'aurais peut-être pu convertir en VBA, indique des options en clic droit que je n'ai pas.
1760517774711.png


Les solutions 2 & 3 ne sont pas applicables dans un outil généraliste utilisable par des personnes différentes.

Il me reste une solution assez bidouille qui consisterait, lors de l'intégration en OLE Object (faite en VBA) de d'abord copier le fichier PDF en TEMP puis le renommer avec une extension neutre arbitraire (.pdg !), puis lors de l'affichage (toujours lancé en VBA) de copier ce fichier en TEMP, changer .pdg en .pdf puis le lancer en Shell Open.
 
Dernière édition:

Si c’est un PDF intégré dans Word/Excel :​

  1. Ouvre le fichier contenant l’objet.
  2. Clique droit sur l’icône du PDF intégréObjet PDF → Exporter (si possible).
  3. Si cette option n’existe pas :
    • Clique droit → Packager l’objetEnregistrer sous (ou glisse sur le Bureau).
  4. Si tout échoue : renomme ton .docx en .zip, puis :
    • Ouvre le ZIP,
    • Va dans le dossier word/embeddings/,
    • Tu trouveras un fichier du type oleObject1.bin → extrait-le.
    • Convertis ce .bin en PDF avec un extracteur OLE, par exemple avec 7-Zip, 7ttx OLE Extractor, ou un script Python (je peux t’en générer un si tu veux).
et la partie 4 ? il me semble que patricktoulon a déja travaillé pour extraire des fichiers de documents Office ?

[EDIT] les fichiers .bin extraits d’un .docx ou .xlsx ne sont pas des PDF purs, mais des objets OLE encapsulant le PDF. Donc tu ne peux pas juste renommer .bin en .pdf. Il faut décapsuler le PDF de l’OLE.
 
Dernière édition:
Oui j'ai regardé la partie 4 mais je ne comprends pas "Si tout échoue : renomme ton .docx en .zip".
Je ne vois pas ce que je peux renommer. Il n'y a pas d'option renommer sur les Embbeded Objects.

Je n'arrive pas à avoir la réponse que tu as eue de ChatGPT. Quelle question exactement as-tu posée ?

Je pense que l'exclusivité que s'arroge Adobe sur les objets intégrés n'est pas légale.
 
Oui j'ai regardé la partie 4 mais je ne comprends pas "Si tout échoue : renomme ton .docx en .zip".
Je ne vois pas ce que je peux renommer. Il n'y a pas d'option renommer sur les Embbeded Objects.

Je n'arrive pas à avoir la réponse que tu as eue de ChatGPT. Quelle question exactement as-tu posée ?
pas besoin de renommer il faut en fait explorer le fichier qui est ouvert pour extraire les .bin qui correspondent aux PDF intégrés . Ces .bin ils contiennent les PDF mais il faut "décapsuler" les PDF des .bin qui sont en OLE.
Pour la deuxième question c'est bizarre j'ai mis ton message intégral.
 
il faut en fait explorer le fichier qui est ouvert pour extraire les .bin qui correspondent aux PDF intégrés
Je ne comprends pas dans ta phrase "le fichier qui est ouvert".
De quel fichier parles-tu ? Il est ouvert par quoi ?
Je n'ai qu'un Embbeded PDF à ma disposition.
S'il y a Acrobat il est ouvert par Acrobat.
S'il n'y a pas Acrobat il ne peut pas s'ouvrir puiqu'Acrobat s'est arrogé l'exclusivité d'ouverture.
 
Merci @kiki29, mais ce problème Adobe Acrobat et OLEObjects Embbeded est vraiment très particulier.

Mais comme dans ma situation, l'intégration Embbeded des PDF et leur visualisation est entièrement sous le contrôle du code VBA, j'ai choisi de "tromper" Acrobat qui est une pieuvre qui s'arroge abusivement des droits d'exclusivité.

La méthode choisie évoquée au Post #3 consiste à:
En intégration:
- Copier le PDF en répertoire temporaire Environ("TEMP")
- Renommer le PDF en répertoire temporaire en changeant son extension (ex: .pdf -> .xxxpdf)
- Intégrer ce pseudo-PDF en feuille Excel
En affichage:
- Copier le pseudo-PDF en répertoire temporaire Environ("TEMP")
- Renommer le pseudo-PDF en répertoire temporaire en changeant son extension (ex: .xxxpdf -> .pdf)
- Faire un Shell.Open de ce PDF

De cette manière Acrobat n'intervient plus dans le PDF intégré qui reste un Embbeded Object standard comme il devrait toujours l'être.
 
pas besoin de renommer il faut en fait explorer le fichier qui est ouvert pour extraire les .bin qui correspondent aux PDF intégrés . Ces .bin ils contiennent les PDF mais il faut "décapsuler" les PDF des .bin qui sont en OLE.
Pour la deuxième question c'est bizarre j'ai mis ton message intégral.
Je viens d'essayer de "décapsuler" les 2 .bin qui sont dans ton classeur avec Notepad++. Ben apparemment il suffit de chercher la chaine %PDF et de supprimer tout ce qu'il y a avant. En donnant des extensions .pdf alors à ces fichiers , j'arrive à les lire sans problème avec un lecteur PDF.
Voici du code VBA généré par I.A (j'ai seulement suggéré à l'I.A d'utiliser le tar windows et de supprimer ce qu'il y a avant %PDF ) qui :
1 - Choisit le classeur dont on veut extraire les PDF.
2 - Utilise le tar windows pour décompresser les fichiers qui se trouvent dans le classeur, dans un répertoire temporaire.
3 - Lit les .bin , supprime ce qu'il y a avant %PDF et les réécrit en .pdf dans un répertoire de sortie.
VB:
Option Explicit

Sub ExtractPDFsFromXLSX()
    Dim xlsxPath As String
    Dim tempDir As String
    Dim outputDir As String
    Dim fso As Object
    Dim sh As Object
    Dim binFile As Object
    Dim pdfBytes() As Byte
    Dim startPos As Long
    
    ' === Sélection du fichier .xlsx ===
    xlsxPath = Application.GetOpenFilename("Fichiers Excel (*.xlsm),*.xlsm")
    If xlsxPath = "False" Then Exit Sub
    
    Set fso = CreateObject("Scripting.FileSystemObject")
    Set sh = CreateObject("WScript.Shell")
    
    ' Dossiers temporaires et sortie
    tempDir = Environ("TEMP") & "\xlsx_extract"
    outputDir = fso.BuildPath(fso.GetParentFolderName(xlsxPath), "PDF_extraits")
    
    If fso.FolderExists(tempDir) Then fso.DeleteFolder tempDir, True
    fso.CreateFolder tempDir
    
    If Not fso.FolderExists(outputDir) Then fso.CreateFolder outputDir
    
    ' === Extraire le .xlsx (ZIP) avec tar ===
    ' Windows 10+ inclut tar.exe
    sh.Run "cmd /c tar -xf """ & xlsxPath & """ -C """ & tempDir & """", 0, True
    
    ' === Parcourir tous les .bin dans xl/embeddings ===
    Dim embDir As String
    embDir = tempDir & "\xl\embeddings"
    If Not fso.FolderExists(embDir) Then
        MsgBox "Aucun dossier xl\embeddings trouvé", vbExclamation
        Exit Sub
    End If
    
    Dim fileName As String
    Dim pdfCount As Long
    pdfCount = 0
    
    For Each binFile In fso.GetFolder(embDir).Files
        If LCase(fso.GetExtensionName(binFile.Name)) = "bin" Then
            ' Lire le binaire
            pdfBytes = ReadBinaryFile(binFile.path)
            
            ' Chercher la position de %PDF
            startPos = InBinary(pdfBytes, StrConv("%PDF", vbFromUnicode))
            If startPos > 0 Then
                ' Extraire tout depuis %PDF
                pdfBytes = SliceBinary(pdfBytes, startPos, UBound(pdfBytes) + 1)
                
                ' Écrire le PDF
                fileName = fso.BuildPath(outputDir, Replace(binFile.Name, ".bin", ".pdf"))
                WriteBinaryFile fileName, pdfBytes
                pdfCount = pdfCount + 1
            End If
        End If
    Next binFile
    
    MsgBox pdfCount & " PDF extrait(s) dans : " & outputDir, vbInformation
    
    ' Nettoyage
    fso.DeleteFolder tempDir, True
End Sub

' === Fonctions utilitaires ===

Function ReadBinaryFile(path As String) As Byte()
    Dim stream As Object
    Set stream = CreateObject("ADODB.Stream")
    stream.Type = 1 ' adTypeBinary
    stream.Open
    stream.LoadFromFile path
    ReadBinaryFile = stream.Read
    stream.Close
End Function

Sub WriteBinaryFile(path As String, data() As Byte)
    Dim stream As Object
    Set stream = CreateObject("ADODB.Stream")
    stream.Type = 1
    stream.Open
    stream.Write data
    stream.SaveToFile path, 2 ' adSaveCreateOverWrite
    stream.Close
End Sub

Function InBinary(data() As Byte, pattern As String) As Long
    Dim i As Long, plen As Long, dlen As Long
    Dim match As Boolean
    Dim j As Long
    plen = LenB(pattern)
    If UBound(data) < 0 Then InBinary = 0: Exit Function
    dlen = UBound(data) + 1
    For i = 0 To dlen - plen
        match = True
        For j = 1 To plen
            If data(i + j - 1) <> AscB(MidB(pattern, j, 1)) Then
                match = False: Exit For
            End If
        Next j
        If match Then
            InBinary = i
            Exit Function
        End If
    Next i
    InBinary = 0
End Function

Function SliceBinary(data() As Byte, startPos As Long, endPos As Long) As Byte()
    Dim out() As Byte
    Dim size As Long, i As Long
    If endPos <= startPos Then ReDim out(-1): SliceBinary = out: Exit Function
    size = endPos - startPos
    ReDim out(size - 1)
    For i = 0 To size - 1
        out(i) = data(startPos + i)
    Next i
    SliceBinary = out
End Function

Le code a fonctionné du premier coup et avec ton classeur de départ, j'ai bien récupéré les 2 pdf qui était dedans.
 
Dernière édition:
il y avais une parti du moteur du creatorRibbonX aussi
même procédéque la compile customui tout du moins la partie extraction
on converti une copie du classeur en zip
on extrait les bin on les collectionne tous
et on les stream read/write
en prenant que la partie %PDF à %EOF
et on recrée les fichiers pdf avec les data en binnaire
VB:
Sub ExtrairePDFDepuisBinEtNettoyer()
    Dim col As New Collection
    Dim wsh As Object, dossierEmbeddings As Object, items As Object, item As Object, stream As Object
    Dim tempo$, chemin$, binPath$, pdfPath$, bytes() As Byte, pdfBytes() As Byte, i&, startPos&, endPos&
    
    tempo = ThisWorkbook.Path & "\tempo.zip" 'chemin du zip
    ThisWorkbook.SaveCopyAs tempo 'on sauve une copie temporaire du classeur au format zip directement
    Application.Wait Now + TimeValue("0:00:01")
    col.Add tempo ' le premier item ce sera le zip complet
    
    Set wsh = CreateObject("Shell.Application") 'c'rée l'object shel application
    Set dossierEmbeddings = wsh.Namespace(tempo & "\xl\embeddings") 'le path complet du dossier dans le zip du dossier embbedding
    If dossierEmbeddings Is Nothing Then MsgBox "Pas de dossier xl\embeddings": Exit Sub 'on se casse si y a pas
    
    Set items = dossierEmbeddings.items 'collection des items a l'inteieurs du dossier
    For Each item In items
        wsh.Namespace(ThisWorkbook.Path).CopyHere item, 4 'on extrait
        col.Add ThisWorkbook.Path & "\" & item.Name 'on ajoute les path a la collection
    Next item
    DoEvents
    Set wsh = Nothing
    
    ' Étape 2 : Extraction PDF
    For i = 2 To col.Count
        binPath = col(i)
        pdfPath = Replace(binPath, ".bin", ".pdf")
        Set stream = CreateObject("ADODB.Stream")
        stream.Type = 1
        stream.Open
        stream.LoadFromFile binPath
        bytes = stream.Read
        stream.Close
        
        ' Chercher %PDF le debut
        startPos = -1
        For j = 0 To UBound(bytes) - 3
            If Chr(bytes(j)) = "%" And Chr(bytes(j + 1)) = "P" And Chr(bytes(j + 2)) = "D" And Chr(bytes(j + 3)) = "F" Then
                startPos = j
                Exit For
            End If
        Next j
        
        ' Chercher %%EOF la fin
        endPos = -1
        For j = UBound(bytes) - 5 To startPos + 4 Step -1
            If Chr(bytes(j)) = "%" And Chr(bytes(j + 1)) = "%" And Chr(bytes(j + 2)) = "E" And Chr(bytes(j + 3)) = "O" And Chr(bytes(j + 4)) = "F" Then
                endPos = j + 4
                Exit For
            End If
        Next j
        
        ' Extraire et écrire le PDF
        If startPos >= 0 And endPos > startPos Then
            ReDim pdfBytes(endPos - startPos) As Byte
            For j = startPos To endPos
                pdfBytes(j - startPos) = bytes(j)
            Next j
            
            Set stream = CreateObject("ADODB.Stream")
            stream.Type = 1
            stream.Open
            stream.Write pdfBytes
            stream.SaveToFile pdfPath, 2
            stream.Close
        Else
            MsgBox "PDF non trouvé dans " & binPath
        End If
    Next i
    
    ' Étape 3 : Nettoyage des fichiers bin
    For i = 1 To col.Count
        Kill col(i)
    Next i
    
    MsgBox "Extraction terminée et fichiers bin supprimés."
End Sub
 

Pièces jointes

- Navigue sans publicité
- Accède à Cléa, notre assistante IA experte Excel... et pas que...
- Profite de fonctionnalités exclusives
Ton soutien permet à Excel Downloads de rester 100% gratuit et de continuer à rassembler les passionnés d'Excel.
Je deviens Supporter XLD
Retour