bn2023
Goto Top

Zellen aus PDF-Dokument auslesen und in Excel-Datei übertragen

Hallo liebe Forenuser,

ich habe ein ausfüllbares PDF-Dokument erstellt.
Dort können in einem Bereich verschiedene Einträge gemacht werden (Zahlen und Euro-Werte).

Hier der Screenshot dazu:

tabelle

Die Daten aus diesen Feldern (der Screenshot ist nur ein Ausschnitt - es geht nach unten noch weiter) sollen dann in eine Excel-Datei übernommen werden. Dort haben die jeweiligen Spalten die gleiche Überschrift, wie im PDF-Dokument.

Beispielsweise könnte man die jeweilige PDF-Datei dann auf dem Desktop speichern... immer unter dem gleichen Namen.
Dann könnte es vielleicht einen Script-Button ebenfalls auf dem Desktop geben, mit dem man die Daten dann überträgt.

Wäre es möglich, diese Daten irgendwie automatisiert (z.B. per Script etc.) in die Excel-Datei zu übernehmen?
Und wenn ja... könnt Ihr mir bei der Erstellung eines solchen Scripts helfen?

Freue mich auf Eure Antwort.

Grüße,
BN

Content-ID: 668689

Url: https://administrator.de/forum/zellen-aus-pdf-dokument-auslesen-und-in-excel-datei-uebertragen-668689.html

Ausgedruckt am: 30.12.2024 um 14:12 Uhr

150704
150704 10.10.2024 um 15:21:24 Uhr
Goto Top
godlie
godlie 11.10.2024 um 11:54:35 Uhr
Goto Top
Hallo,

eine einfache Suche nach pdf parse excel

https://administrator.de/?search=pdf+parse+excel

grüße
BN2023
BN2023 16.10.2024 um 13:39:19 Uhr
Goto Top
Hallo Ihr Lieben...

Leider lag dieses Thema jetzt eine zeitlang brach...

Es wird aber jetzt wieder interessant, da wir nun entspr. PDF-Dokumente erhalten, aus denen wir bestimmte Angaben in vorgegebene Zellen einer Excel-Datei übernehmen müssen.

Danke für die Links, die ich mir durchgesehen habe.
Leider geht es da oft um den umgekehrten Weg - also Exceldaten nach PDF.
Und viele der verlinkten Threads passen auch nicht so recht zu meiner Situation hier.

Ich kenne mich auch nicht wirklich mit VBA aus sowie mit weiterer Programmierung od. Linux.
Ich bin eher "normaler Anwender". Daher bräuchte ich etwas Hilfe von Euch.

Vielleicht könnt Ihr mir ja ein entspr. Tool direkt empfehlen, welches das kann, was ich suche...?

Ich habe mal 2 Testdateien hochgeladen (eine PDF und eine Excel). Vielleicht mögt Ihr ja mal schauen, was genau ich machen will.

Hier die Links:

Link zur Excel-Datei
Link zur PDF-Datei

Wäre toll, wenn Ihr mir weiterhelfen könntet.

Danke und Grüße,
BN
150704
150704 16.10.2024 aktualisiert um 13:41:44 Uhr
Goto Top
Leider geht es da oft um den umgekehrten Weg - also Exceldaten nach PDF.
Öhm, nö, hier steht es doch auch in der Richtung die du willst
Das ganze auch in die andere Richtung PDF-Formularfelder => CSV
colinardo
Lösung colinardo 16.10.2024, aktualisiert am 17.10.2024 um 11:00:23 Uhr
Goto Top
Servus,
Schau mal ob die folgenden PowerShell Skripte passen. Die erste Variante arbeitet mit dem Excel Com-Object und setzt ein installiertes Office mit Excel voraus, die zweite Variante weiter unten nutzt das "ImportExcel" Powershell Modul was kein installiertes Office benötigt.
Die iTextSharp.dll wird wenn das Skript gespeichert wurde einmalig in den Ordner des Skripts heruntergeladen und von dort geladen. Das lässt sich aber nach belieben anpassen.

Beide Versionen basieren auf den Inhalten deiner bereitgestellten Testdateien.
# Variablen bitte anpassen ---------------------------
# Pfad zur PDF Datei
$sourcefile = "C:\data\quelle.pdf"  
# Pfad zum Excel-Template
$templatefile = "c:\data\template.xlsx"  
# ------------------------------------------------------
$ErrorActionPreference = 'Stop'  

# Funktion zum Laden des iTextSharp Assemblies
function Load-iTextLibrary {
    if($psscriptroot -ne ''){  
        $localpath = join-path $psscriptroot 'itextsharp.dll'  
    }else{
        $localpath = join-path $env:TEMP 'itextsharp.dll'  
    }
    $zip = $null;$tmp = ''  
    try{
        if(!(Test-Path $localpath)){
            Add-Type -A System.IO.Compression.FileSystem
            $tmp = "$env:TEMP\$([IO.Path]::GetRandomFileName())"  
            write-host "Downloading and extracting required 'iTextSharp.dll' ... " -F Green -NoNewline  

            (New-Object System.Net.WebClient).DownloadFile('https://www.nuget.org/api/v2/package/iTextSharp/5.5.13.1', $tmp)  
            $zip = [System.IO.Compression.ZipFile]::OpenRead($tmp)
            $zip.Entries | ?{$_.Fullname -eq 'lib/itextsharp.dll'} | %{  
                [System.IO.Compression.ZipFileExtensions]::ExtractToFile($_,$localpath)
            }
            write-host "OK" -F Green   
        }
        if (Get-Item $localpath -Stream zone.identifier -ea SilentlyContinue){
            Unblock-File -Path $localpath
        }
        Add-Type -Path $localpath
    }catch{
        throw "Error: $($_.Exception.Message)"  
    }finally{
        if ($zip){$zip.Dispose()}
        if ($tmp -ne ''){del $tmp -Force -EA SilentlyContinue}  
    }
}
# iText Library laden
Load-iTextLibrary

# auch geschütze PDFs öffnen aktivieren
[iTextSharp.text.pdf.PdfReader]::unethicalreading = $true

$reader = $null; $xl = $null
try {
    # Excel Object erstellen
    $xl = New-Object -Com Excel.Application -P @{Visible = $false}
    # workbook öffnen
    $wb = $xl.Workbooks.Open($templatefile)
    # wir arbeiten auf dem ersten Arbeitsblatt
    $ws = $wb.Sheets.Item(1)
    write-host "Exportiere Daten aus '$($sourcefile)' ... " -F Green -NoNewline  
    # PDF Reader Object erstellen
    $reader = New-Object iTextSharp.text.pdf.PdfReader $sourcefile
    # Gesamtergebnisse aus dem PDF in die entsprechenden Felder der Exceldatei übertragen
    $ws.Range("E7").Value = $reader.AcroFields.GetField("GESAMT")  
    $ws.Range("I4").Value = $reader.AcroFields.GetField("GESAMT_2")  
    $ws.Range("B10").Value = $reader.AcroFields.GetField("GESAMT_3")  
    $ws.Range("K7").Value = $reader.AcroFields.GetField("GESAMT_4")  
    # Arbeitsmappe speichern und schließen
    $wb.Save();$wb.Close($true)
    # reader schließen und ressourcen freigeben
    $reader.Close(); $reader.Dispose()
}catch{
    write-host $_.Exception.Message -F Red
}finally{
    # cleanup
    if($reader){$reader.Dispose()}
    # Excel schließen
    $xl.Quit()
    # release com resources
    [void][System.Runtime.InteropServices.Marshal]::ReleaseComObject($xl)
}

back-to-topVariante mit "ImportExcel" Modul (Powershell-Modul wird für den aktuellen User installiert, falls es noch nicht vorhanden ist)


# Variablen bitte anpassen ---------------------------
# Pfad zur PDF Datei
$sourcefile = "C:\data\quelle.pdf"  
# Pfad zum Excel-Template
$templatefile = "c:\data\template.xlsx"  
# ------------------------------------------------------
$ErrorActionPreference = 'Stop'  

# install ImportExcel module
If(!(Get-Module -ListAvailable -Name ImportExcel)){
    write-host "Installing 'ImportExcel' module ..." -F Green  
    Install-Module -Name ImportExcel -Scope CurrentUser -Force
}

# Funktion zum Laden des iTextSharp Assemblies
function Load-iTextLibrary {
    if($psscriptroot -ne ''){  
        $localpath = join-path $psscriptroot 'itextsharp.dll'  
    }else{
        $localpath = join-path $env:TEMP 'itextsharp.dll'  
    }
    $zip = $null;$tmp = ''  
    try{
        if(!(Test-Path $localpath)){
            Add-Type -A System.IO.Compression.FileSystem
            $tmp = "$env:TEMP\$([IO.Path]::GetRandomFileName())"  
            write-host "Downloading and extracting required 'iTextSharp.dll' ... " -F Green -NoNewline  

            (New-Object System.Net.WebClient).DownloadFile('https://www.nuget.org/api/v2/package/iTextSharp/5.5.13.1', $tmp)  
            $zip = [System.IO.Compression.ZipFile]::OpenRead($tmp)
            $zip.Entries | ?{$_.Fullname -eq 'lib/itextsharp.dll'} | %{  
                [System.IO.Compression.ZipFileExtensions]::ExtractToFile($_,$localpath)
            }
            write-host "OK" -F Green   
        }
        if (Get-Item $localpath -Stream zone.identifier -ea SilentlyContinue){
            Unblock-File -Path $localpath
        }
        Add-Type -Path $localpath
    }catch{
        throw "Error: $($_.Exception.Message)"  
    }finally{
        if ($zip){$zip.Dispose()}
        if ($tmp -ne ''){del $tmp -Force -EA SilentlyContinue}  
    }
}
# iText Library laden
Load-iTextLibrary

# auch geschütze PDFs öffnen aktivieren
[iTextSharp.text.pdf.PdfReader]::unethicalreading = $true

$reader = $null; $xl = $null
try {
    # Excelmappe öffnen
    $xl = Open-ExcelPackage -Path $templatefile
    # Benutze das erste Arbeitsblatt für die Ausgabe
    $ws = $xl.Workbook.Worksheets[1]
    write-host "Exportiere Daten aus '$($sourcefile)' ... " -F Green -NoNewline  
    # PDF Reader Object erstellen
    $reader = New-Object iTextSharp.text.pdf.PdfReader $sourcefile

    # Gesamtergebnisse aus dem PDF in die Exceldatei übertragen
    $ws.Cells['E7'].Value  = [int]$reader.AcroFields.GetField("GESAMT")  
    $ws.Cells['I4'].Value  = [int]$reader.AcroFields.GetField("GESAMT_2")  
    $ws.Cells['B10'].Value = [int]$reader.AcroFields.GetField("GESAMT_3")  
    $ws.Cells['K7'].Value  = [int]$reader.AcroFields.GetField("GESAMT_4")  

    # reader schließen und ressourcen freigeben
    $reader.Close(); $reader.Dispose()
}catch{
    write-host $_.Exception.Message -F Red
}finally{
    # cleanup
    if($reader){
        $reader.Dispose()
    }
    # close excel session
    if($xl){
        Close-ExcelPackage -ExcelPackage $xl
    }
}

Zusätzlich kann ich folgenden Beitrag empfehlen wenn es mal nicht um Formularfelder in PDF Dateien geht
Powershell: Text anhand seiner Position aus PDF-Dokumenten auslesen

Viel Spaß damit.
Grüße Uwe
BN2023
BN2023 17.10.2024 aktualisiert um 10:52:45 Uhr
Goto Top
Hallo Uwe,

WOW... das ist ja irre!!

Vielen Dank für die Mühe und für die Erstellung der beiden Scripts.
Ich werde sie gleich mal testen.

Vorab jedoch noch eine kurze (hoffentlich nicht zu dämliche...) Frage:
Sind das VBA-Scripts, die ich in die Excel-Datei einfügen muss oder sind das Powershell-Scripts, die ich dann als Datei abspeichern muss mit der Endung .ps1?

Ich nehme an, dass es Powershell-Scripts sind, da Deine Verlinkung ja auch auf Powershell hinweist face-wink
Müssen die 3 Dateien (PDF, Excel, Powershell) alle im selben Verzeichnis liegen?

Danke und Grüße,
BN
colinardo
colinardo 17.10.2024 aktualisiert um 10:57:35 Uhr
Goto Top
Zitat von @BN2023:
oder sind das Powershell-Scripts,
Korrekt.
Müssen die 3 Dateien (PDF, Excel, Powershell) alle im selben Verzeichnis liegen?
Nein, du kannst die Pfade in den Variablen im Kopf des Skriptes an deine Bedürfnisse anpassen.
BN2023
BN2023 17.10.2024 aktualisiert um 11:09:29 Uhr
Goto Top
OK und danke nochmals...

Habe das PS-Script soeben getestet und es hat hervorragend funktioniert. Alle Felder in der Excel-Datei wurden korrekt ausgefüllt.

Unglaublich, dass sowas tatsächlich funktioniert face-wink

Ich habe mir das Script auch mal näher angeschaut (auch wenn ich fast nix verstehe, was ich da sehe...).
Aber die Angaben zu den Feldern in Excel habe ich dort gefunden.
Nur frage ich mich, wo die Bereiche angegeben wurden, aus denen die PDF-Inhalte genommen werden? Dazu habe ich nichts gefunden. Ggf. würde ich die gerne erweitern können... deshalb frage ich.

Und zur Info:
Da diese Excel-Datei quasi fortgeschrieben werden soll, würde ich es einfach so lösen, dass ich diese Felder einmal ganz oben in der Excel-Datei einsetze. Diese werden dann bei jedem Ausführen des Scripts gefüllt und würden dann jeweils manuell in die nächste freie Zeile in der eigentlichen Auflistung übertragen. Natürlich muss die jeweilige PDF-Datei dann immer den gleichen Namen bekommen, was aber auch kein Problem wäre.

Grüße,
BN
colinardo
colinardo 17.10.2024 aktualisiert um 11:31:14 Uhr
Goto Top
Nur frage ich mich, wo die Bereiche angegeben wurden, aus denen die PDF-Inhalte genommen werden? Dazu habe ich nichts gefunden. Ggf. würde ich die gerne erweitern können... deshalb frage ich.
Da es sich bei deinem PDF Dokument um ein Formular mit richtigen Eingabefeldern handelt sind diese ganz einfach über deren eindeutige Bezeichnung abrufbar. Jedes Formularfeld hat also einen eindeutigen Bezeichner im Dokument und dessen Daten können damit abgefragt werden
$reader.AcroFields.GetField("GESAMT")  
In diesem Beispiel wird also der Wert des Feldes mit der Bezeichnung "GESAMT" abgefragt.

Die Bezeichner der Formular-Felder kannst du dir mit dem Auswahl-Tool in Acrobat&Co. anzeigen lassen, oder in dem du in den Formular Editier-Modus wechselst.

screenshot
BN2023
BN2023 17.10.2024 aktualisiert um 12:18:11 Uhr
Goto Top
aaaah, jetzt hab ich´s kapiert.
Danke für die weitere Erläuterung.

Dann würde ich das Script jetzt nochmal etwas erweitern und dann nochmal testen.

Am Ende ist es nämlich so, dass ich immer mal wieder ein solches ausgefülltes PDF erhalte und dann diese Daten in eine (immer die gleiche) Excel-Liste übernehmen muss. Also quasi für jedes neue PDF eine neue Zeile in Excel.

Daher war meine Idee, einfach oben als erste Zeile in der Excel-Liste einmal die entspr. Felder einzusetzen, die dann jeweils gefüllt werden mit jedem neuen PDF. Diese Zeile muss dann nach der Übertragung der Daten nach weiter unten immer gelöscht werden. Aber ich denke, so würde es funktionieren...

Ich muss im Script dann nur noch die Seitenzahl aus dem PDF hinzufügen, denn das Original hat mehrere Seiten. Aber dazu habe ich etwas in dem von Dir verlinkten Thread gefunden... face-smile

Grüße,
BN
BN2023
BN2023 17.10.2024 aktualisiert um 12:23:14 Uhr
Goto Top
nochmal zu den Seitenzahlen:

In dem von Dir verlinkten Thread habe ich folgendes gefunden:

$locations = @{
    1 = [ordered]@{
        'Geschäftspartnernummer' = 167,223,188,228    
        'Empfänger' = 23,211,73,233    
    }
    3 = [ordered]@{
        'Bankleitzahl' = 10,20,40,30    
    }
}

In meiner Datei sieht das aber etwas anders aus... nämlich so:

$ws.Range("E7").Value = $reader.AcroFields.GetField("GESAMT")    
    $ws.Range("I4").Value = $reader.AcroFields.GetField("GESAMT_2")    
    $ws.Range("B10").Value = $reader.AcroFields.GetField("GESAMT_3")    
    $ws.Range("K7").Value = $reader.AcroFields.GetField("GESAMT_4")    

Wie bzw. wo würde ich da eine Seitenzahl angeben?
Denn in meinem Fall gibt es ja jeweils feste Felder, die Bezeichnungen haben und keine Koordinaten.
Oder muss ich ggf. keine Seitenzahlen angeben, da es ja die klaren Bezeichnungen gibt?

Grüße,
BN
colinardo
colinardo 17.10.2024 aktualisiert um 12:38:27 Uhr
Goto Top
Das sind zwei ganz unterschiedliche Baustellen, der andere Beitrag behandelt PDFs die ohne Formularfelder daher kommen.
In deinem Fall ist es aber einfach da du benannte Formularfelder hast, da brauchst du keine Seitenzahlen, denn sämtliche Formularfelder ein und des selben Dokuments haben eindeutige Namen.

Mehr Support gibt es dazu von meiner Seite nur noch auf PN-Anfrage. Ich kann dir hier ja nicht sämtliche Grundlagen dazu beibringen face-wink.
BN2023
BN2023 17.10.2024 um 13:19:17 Uhr
Goto Top
Danke Dir für Deine weitere Antwort.

Denke ich komme so klar... ansonsten schreibe ich Dir per PN

Danke jedenfalls für Deine Mühe...

Grüße,
BN