Pdf in Excel Bestellnummern auslesen
Guten Abend,
ich bin vorhin ueber Google auf den Beitrag PDF auslesen und per VBA in Excel schreiben gekommen. In dem steht, dass man mit einer Datei pdftotext.exe und einem Makro Daten auslesen kann.
Die Datei habe ich nur unter einem xpdreader gefunden, aber nicht direkt. Das Makro hahe ich wie beschrieben rueber kopiert und den Text geaendert, bekomme aber eine Fehlermeldung auf dem Firmenlatop.
Ist es moeglich auf dem Weg ca. 500 pdf's mit teilweise 90 Seiten auszulesen? Ich habe schon ein altes Makro, dass mir vor Jahren jemand geschrieben hat versucht und Makros gefunden, die pdf's in Excel umwandeln koennen sollen, aber nichts hat funktioniert. Mein Desktop meldet staendig, dass eine dll fehlt, da muss ich vermutlich Excel reparieren. Mit Powerquery habe ich es auch nicht hinbekommen, weil ich nichts gefunden habe wie ich mehr als eine Seite laden kann. Bei dem Makro, dass ich rueberkopiert und probiert habe kam eine Fehlermeldung, hier For i = 1 To colPFiles.Count
WSHShell.Run strCMDLine & """" & colPFiles.Item(i) & """", 0, True
Unten habe ich als Bilder zwei Seiten aus einer pdf angehaengt, dass ich nicht weiss, wie man die pdf einhaengen kann.
Es soll 'nur' die Ordernummer ausgelesen werden. Pro pdf koennen das mehr als 200 sein. Geht das mit dem tool?
Beste Gruesse
Matthias
ich bin vorhin ueber Google auf den Beitrag PDF auslesen und per VBA in Excel schreiben gekommen. In dem steht, dass man mit einer Datei pdftotext.exe und einem Makro Daten auslesen kann.
Die Datei habe ich nur unter einem xpdreader gefunden, aber nicht direkt. Das Makro hahe ich wie beschrieben rueber kopiert und den Text geaendert, bekomme aber eine Fehlermeldung auf dem Firmenlatop.
Ist es moeglich auf dem Weg ca. 500 pdf's mit teilweise 90 Seiten auszulesen? Ich habe schon ein altes Makro, dass mir vor Jahren jemand geschrieben hat versucht und Makros gefunden, die pdf's in Excel umwandeln koennen sollen, aber nichts hat funktioniert. Mein Desktop meldet staendig, dass eine dll fehlt, da muss ich vermutlich Excel reparieren. Mit Powerquery habe ich es auch nicht hinbekommen, weil ich nichts gefunden habe wie ich mehr als eine Seite laden kann. Bei dem Makro, dass ich rueberkopiert und probiert habe kam eine Fehlermeldung, hier For i = 1 To colPFiles.Count
WSHShell.Run strCMDLine & """" & colPFiles.Item(i) & """", 0, True
Unten habe ich als Bilder zwei Seiten aus einer pdf angehaengt, dass ich nicht weiss, wie man die pdf einhaengen kann.
Es soll 'nur' die Ordernummer ausgelesen werden. Pro pdf koennen das mehr als 200 sein. Geht das mit dem tool?
Beste Gruesse
Matthias
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 4289509530
Url: https://administrator.de/contentid/4289509530
Ausgedruckt am: 18.11.2024 um 19:11 Uhr
15 Kommentare
Neuester Kommentar
Servus.
das oben genannte Tutorial hat @aqui ja schon genannt. Dein gewünschter Text lässt sich aber auch schön abgrenzen und per Regular Expressions auslesen.
Sowas macht man heute eher gleich über die Powershell als mit VBA. Hierfür kannst du folgende Powershell-Funktion nehmen:
Wichtiger Hinweis: Da ich hier natürlich keines deiner PDFs im Original vorliegen habe musste ich den Regular Expression-Pattern anhand deiner Bilder "raten" es kann also sein das er nicht ganz passt, in dem Fall kannst du mir aber gerne eine (geschwärzte) Datei zur Verfügung stellen => PN , dann kann ich dir bei der Definition des Pattern behilflich sein. Des weiteren muss das PDF maschinenlesbaren Text enthalten, das Skript macht keine OCR!
Anzugeben in den Variablen im Kopf des Skriptes sind der Ordner mit den PDF-Dateien, und die Zieldatei in der die extrahierten Nummer landen.
Grüße Uwe
das oben genannte Tutorial hat @aqui ja schon genannt. Dein gewünschter Text lässt sich aber auch schön abgrenzen und per Regular Expressions auslesen.
Sowas macht man heute eher gleich über die Powershell als mit VBA. Hierfür kannst du folgende Powershell-Funktion nehmen:
Wichtiger Hinweis: Da ich hier natürlich keines deiner PDFs im Original vorliegen habe musste ich den Regular Expression-Pattern anhand deiner Bilder "raten" es kann also sein das er nicht ganz passt, in dem Fall kannst du mir aber gerne eine (geschwärzte) Datei zur Verfügung stellen => PN , dann kann ich dir bei der Definition des Pattern behilflich sein. Des weiteren muss das PDF maschinenlesbaren Text enthalten, das Skript macht keine OCR!
Anzugeben in den Variablen im Kopf des Skriptes sind der Ordner mit den PDF-Dateien, und die Zieldatei in der die extrahierten Nummer landen.
# Ordner mit den auszulesenden PDF Dateien
$SOURCEFOLDER = "D:\Orders"
# Ausgabedatei mit den Nummern
$OUTFILE = "D:\ordernummern.csv"
# Extrahierungs-Muster
$REGEXPATTERN = '(?is)(?<=Order\s+)\d{7} ?[\d-]{8}\b'
# ---------------------------------------
# function to get pdf page content
function Get-PDFContent {
param(
# absolute pdf file path
[Parameter(mandatory=$true,ValueFromPipelineByPropertyName=$true)][Alias('Fullname')][string[]]$path,
# array of page indices from wich to extract page content
[Parameter(mandatory=$false)][int[]]$page = -1,
# optional regular expression pattern for string extraction
[Parameter(mandatory=$false)][string]$pattern,
# optional regex subgroup definition
[Parameter(mandatory=$false)][int]$patterngroup = 0
)
begin {
if (!('iTextSharp.text.pdf.PdfReader' -as [type])){
# 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
# enable reading protected documents
[iTextSharp.text.pdf.PdfReader]::unethicalreading = $true
}
}
process{
foreach($file in $path){
$reader = $null
try{
$reader = New-Object iTextSharp.text.pdf.PdfReader $file
if ($page -eq -1){
# Get content of all pages
$content = 1..($reader.NumberOfPages) | %{
[iTextSharp.text.pdf.parser.PdfTextExtractor]::GetTextFromPage($reader,$_)
}
}else{
# Get content of specific pages
$content = $page | ?{$_ -in (1..$reader.NumberOfPages)} | %{
[iTextSharp.text.pdf.parser.PdfTextExtractor]::GetTextFromPage($reader,$_)
}
}
if($pattern -ne ''){
[regex]::matches([string]$content,$pattern) | %{$_.Groups[$patterngroup].Value}
}else{
$content
}
}catch{
write-error "ERROR processing file '$file' : $($_.Exception.Message)"
}finally{
if ($reader){$reader.Dispose()}
}
}
}
}
# Extrahiere Daten aus allen gefundenen PDF-Dateien und schreibe das Ergebnis von Eindeutigen Werten inklusive Dateiname als CSV in die Ausgabedatei
$result = foreach($file in Get-ChildItem $SOURCEFOLDER -File -Filter *.pdf){
Get-PDFContent $file.Fullname -pattern $REGEXPATTERN | select @{n='Filename';e={$file.Name}},@{n='Ordernumber';e={$_ -replace '\s'}} -Unique
}
if ($result){
$result | export-csv -LiteralPath $OUTFILE -Delimiter ";" -NoType -Encoding UTF8
}else{
write-host "Keine passenden Daten für Export gefunden!" -F Yellow
}
Grüße Uwe
Code wurde auf die tatsächlichen Daten die per PN geliefert wurden angepasst. #edit# Die zusätzliche Ausgabe des Dateinamens wurde noch hinzugefügt!
Wenns das dann war, den Beitrag bitte noch auf gelöst setzen. Merci.
Wenns das dann war, den Beitrag bitte noch auf gelöst setzen. Merci.
Powershell Leitfaden für Anfänger
Liegt das Script im selben Verzeichnis in dem man sich gerade befindet, kann man es auch so abkürzen:
Der einfachste Aufruf sieht hier so aus:
Wenn man dem Script Parameter übergeben möchte:
Wenn man "benannte" Parameter übergeben möchte (die einfachen Hochkommas um den Scriptpfad werden benötigt wenn er Leerzeichen beinhaltet):
Man kann auch mehrere Scripte hintereinander ausführen lassen:
Weitere Parameter zeigt einem ein
Anleitung: Wie starte ich Powershell-Scripte
- Zuerst speichert man den Code in einer Textdatei mit der Endung .ps1 mit UTF-8 Encoding.
- Wenn man zum ersten mal Powershell-Scripte ausführt, musst man einmalig vorher noch das Ausführen von Scripten im User-Account freischalten. Dazu öffnet man eineadministrative Powershell-Konsole und gibt dort den Befehl
Set-ExecutionPolicy RemoteSigned -Force
ein. Um diese Policy für alle User auf dem Rechner zu setzen muss man diesen Befehl in einer Powershell-Konsole mit Admin-Rechten starten. Noch ein Hinweis für 64-Bit-Systeme: Hier sollte sowohl für die 32bit und 64Bit Variante der Powershell die Policy in einer Admin-Konsole gesetzt werden:Set-ExecutionPolicy RemoteSigned -Force; start-job { Set-ExecutionPolicy RemoteSigned -Force } -RunAs32
- Jetzt kann das Powershell-Script wie weiter unten erläutert in einer Powershell-Konsole oder aus einer CMD-Fenster heraus ausgeführt werden. Wer lieber mit der Maus arbeitet macht einen Rechtsklick auf die Script-Datei und wählt: Mit Powershell ausführen.
- Alternativ lässt sich ein Script auch ohne das globale Ändern der ExecutionPolicy ausführen indem man die Policy als Parameter auf der Kommandozeile mitgibt:
powershell.exe -ExecutionPolicy ByPass -File "C:\Pfad\Script.ps1"
Starten eines Scriptes in einer Powershell-Konsole
Immer den kompletten Pfad zum Script angeben, und wenn er Leerzeichen beinhaltet in Anführungszeichen einschließen:"C:\Pfad\script.ps1"
.\script.ps1
Starten von PS-Scripten aus Batch und Kommandozeilen heraus:
Hier gibt es unterschiedliche Methoden, je nach Anforderungen gibt es hier einige Besonderheiten vor allem bei Leerzeichen in Pfaden zu beachten!Der einfachste Aufruf sieht hier so aus:
powershell.exe -File "C:\Pfad\Script.ps1"
powershell.exe -File "C:\Pfad\Script.ps1" "Parameter 1" "Parameter 2"
powershell.exe -command "&'C:\Pfad\Script.ps1' -par1 'Wert1' -par2 'Wert2'"
powershell.exe -command "&'C:\Pfad\Script1.ps1';&'C:\Pfad\Script2.ps1'"
powershell -?
in einer Konsole an.Starten von PS-Scripten in der Aufgabenplanung (Taskplaner)
In der jeweiligen Aktion unter "Programm/Script" trägt man powershell.exe ein und unter "Argumente hinzufügen (optional)" trägt man wie oben geschrieben alles was hinter powershell.exe kommt ein - also z.B. -File "C:\Pfad\Script.ps1" "Parameter 1" "Parameter 2"
Rechtsklick auf die DLL > Eigenschaften und das Mark-of-the-web entfernen sollte hier helfen sofern noch vorhanden. Eventuelle Security Tools temporär abschalten und an obige Anleitung halten.
Wenn die Skriptdatei selbst von einem anderen Rechner kopiert wurde bitte auch per rechtsklick > Eigenschaften prüfen ob das Skript mit einem Mark Of The Web versehen ist und wenn ja entfernen!
Wenn die Skriptdatei selbst von einem anderen Rechner kopiert wurde bitte auch per rechtsklick > Eigenschaften prüfen ob das Skript mit einem Mark Of The Web versehen ist und wenn ja entfernen!
Wo muesste ich da schauen im Skript?
Wenn ich den Pfad ohne die Nummer eingebe wird eine Datei runtergeladen mit 5.5.13.3. Soll ich die vielleicht probieren?
Nein, Nein, Nein nirgendwo, du muss hier rein garnichts anpassen das läuft out of the box mit der Version! Die neueren DLL-Versionen haben zusätzlich weitere Abhängigkeiten mit denen geht das obige Skript in der Form nicht!Wenn ich den Pfad ohne die Nummer eingebe wird eine Datei runtergeladen mit 5.5.13.3. Soll ich die vielleicht probieren?
Ich meinte das Markt of the Web in den Skript-Datei-Eigenschaften nicht der Inhalt.
Works as designed, ansonsten grätscht dir sehr wahrscheinlich deine verwendete Security Suite dazwischen und du musst die DLL als Ausnahme definieren!
allerdings nur 5 Bestellungen und nicht 19.
Du sagst ja kein Wort welche Zeichen die Nummern enthalten dürfen, ich war davon ausgegangen das nur Zahlen und Bindestrich enthalten sein dürfen, die "xxx" habe ich als Schwärzung deinerseits interpretiert. Des weiteren gibt es nach 7 Ziffern ein Leerzeichen im Fließtext so das ich immer 7 Zeichen vor dem Leerzeichen erwarte. Du kannst den Regex ja selbst an deine Bedürfnisse anpassen, musst dich halt etwas damit beschäftigen: Regular Expressions TutorialZur Info: Doppelte Nummern in der selben Datei werden ausgefiltert und immer nur eine davon beibehalten, auch darüber verlierst du kein Wort und ich muss raten!
Mit den anderen noch nicht, kommen ein paar kryptische Zeichen, siehe unten.
Da kommt vor wenn es keinen extrahierten Inhalt aus der Datei gibt, dass habe ich noch korrigiert.Viel Erfolg
Grüße Uwe