springstil
Goto Top

PDF zusammenführen wenn zahl übereinstimmt

Hallo zusammen,

Hat jemand eine idee wie man sowas realisieren kann? Unsere Warenwirtschaft erstellt Rechnungen die dann per PDF abgelegt werden. Nun ist es aber so, das für verschiedene Häuser Rechnungen nach und nach erstellt werden. So kann es also vorkommen das 15 Rechnungen zusammen kommen.

Nun wird in Zukunft das System zwar in der Lage sein diese direkt an Letter express zu versenden wo die direkt automatisch verschickt werden. Allerdings dauert dies noch mindestens 1 Jahr da dass mit einem Großen Update verknüpft ist was wir jetzt noch nicht einspielen wollen.

Nun kam ich auf die Idee das selbst in die Hand zu nehmen und Letter express einfach per FTP zu senden damit die raus gehen. ABER 15 einzelne PDF Dateien wären 15 Briefe. Und da würden die Kunden uns aufs Dach steigen.

Daher suche ich nach einer Möglichkeit PDF Dateien zusammen zu führen. Der Name der PDF ist so aufgebaut: GASPER - 12490301 01.06.2021 10496
die Letzten 5 Zahlen sind die Kundennummer. Nun würde ich gerne Per Skript das ganze so einrichten, das anhand einer "block" Nummer die PDF Dateien zusammen gefügt werden.

Z.b habe ich eine InI Datei und schreibe dort:

-KUNDE123
10496
10458
52148
-Kunde456
98745
41235


nun soll das Skript wenn einer der zahlen zusammen gehören die PDF Datei zusammen fügen, so das nur eine Datei raus geht.

Jemand zeit und Lust mir dabei zu helfen? Am liebsten vielleicht sogar in Powershell

Natürlich kann man auch über ein End Geld sprechen wenn jemand sowas machen kann.

Content-ID: 667250

Url: https://administrator.de/contentid/667250

Ausgedruckt am: 21.11.2024 um 19:11 Uhr

TK1987
TK1987 01.06.2021 aktualisiert um 23:59:30 Uhr
Goto Top
Moin,

Zitat von @Springstil:
Daher suche ich nach einer Möglichkeit PDF Dateien zusammen zu führen.
AFAIK kann Powershell nativ keine PDF's zusammenfügen - lässt sich allerdings leicht als Modul nachinstallieren, z.B. MergePDF
Install-Module -Name MergePDF -Scope CurrentUser -Force
bei einem Mehrbenutzersystem sollte man mit -Scope CurrentUser weglassen, um das Modul für alle Benutzer zu installieren - muss dann aber natürlich mit Adminrechten ausgeführt werden.

Der Name der PDF ist so aufgebaut: GASPER - 12490301 01.06.2021 10496
die Letzten 5 Zahlen sind die Kundennummer. Nun würde ich gerne Per Skript das ganze so einrichten, das anhand einer "block" Nummer die PDF Dateien zusammen gefügt werden.
Sollte mit Group-Object kein Problem sein
$Quelle = 'C:\Test\'  
$Ziel   = 'C:\Output'  

# PDFs nach Kundennummer (letzte 5 Ziffern im Dateinamen) gruppieren
$Kunden = Get-ChildItem "$Quelle\*.pdf" | Where-Object BaseName -Match '\d{5}$' | Group-Object @{e={$Matches.0}}  

# Für jeden Kunden PDFs zusammenfügen
Foreach ($Kunde in $Kunden) {
  Merge-PDF -Path $Kunde.Group -OutputPath ("$Ziel\"+$Kunde.Name+'.pdf')  
}

Gruß Thomas
Springstil
Springstil 02.06.2021 um 08:12:06 Uhr
Goto Top
Das hört sich schon mal gut an. Gibts auch die Möglichkeit zu sagen das er bestimmte Nummern immer zusammenfügt ?
TK1987
TK1987 02.06.2021 um 08:22:05 Uhr
Goto Top
Möglichkeiten gibt es mit Powershell genug 😎

Wenn ich dich richtig verstehe, willst du also Pro Kunde nicht alle PDFs zu einem zusammenfügen, sondern diese jeweils nochmal anhand einer anderen Nummer im Dateinamen gruppieren?

Nach welchem Schema soll das Ganze denn gemacht werden?
Springstil
Springstil 02.06.2021 um 08:46:34 Uhr
Goto Top
Zitat von @TK1987:

Wenn ich dich richtig verstehe, willst du also Pro Kunde nicht alle PDFs zu einem zusammenfügen, sondern diese jeweils nochmal anhand einer anderen Nummer im Dateinamen gruppieren?

Nach welchem Schema soll das Ganze denn gemacht werden?

Genau. Meine Idee wäre in einer "config ini" oder sowas wo ich Gruppen erstelle mit Kundennummern die er zusammen führen soll.
TK1987
TK1987 02.06.2021 um 10:54:05 Uhr
Goto Top
Zitat von @Springstil:
Genau. Meine Idee wäre in einer "config ini" oder sowas wo ich Gruppen erstelle mit Kundennummern die er zusammen führen soll.
Ok, ein bisschen mehr Kontext wäre da schon hilfreich gewesen. Der Erste Entwurf könnte so aussehen:

back-to-topConfig-Datei:
# Anhand dieser Config-Datei werden PDF-Dateien mehrerer Kundennummern gruppiert.
# Der Gruppenname entspricht dem Dateinamen der Ausgabedatei.
#
# Die Datei ist wie folgt aufgebaut:
# <Gruppenname>, <Kundennummer1>, <Kundennummer2>, <Kundennumer3>, ...
GruppeABC, 10496, 12435, 45769, 32456
GruppeXYZ, 49623, 14756, 97856, 45670

back-to-topPowershell Skript:
$Config = 'C:\Test\Kundengruppen.conf'  
$Quelle = 'C:\Test'  
$Ziel   = 'C:\Output'  

# Kundengruppen aus Config-Datei laden
Foreach ($Gruppe in (Get-Content $Config) -NotMatch '^#') {  
  $Gruppe = $Gruppe -Split ',\s?'  
  
  # PDF-Dateien für jede Gruppe sammeln
  [Array]$PDFs = Foreach ($Nummer in $Gruppe[1..($Gruppe.Count-1)]) { Get-ChildItem "$Quelle\*$Nummer.pdf" }  
  
  # PDFs zusammenfügen
  Merge-PDF $PDFs ("$Ziel\"+$Gruppe+'.pdf')  

}

Die Frage die sich mir stellt ist, was soll mit PDF's passieren, die keiner Gruppe zugeordnet sind?
Springstil
Springstil 02.06.2021 um 11:20:32 Uhr
Goto Top
Zitat von @TK1987:

Zitat von @Springstil:
Genau. Meine Idee wäre in einer "config ini" oder sowas wo ich Gruppen erstelle mit Kundennummern die er zusammen führen soll.
Ok, ein bisschen mehr Kontext wäre da schon hilfreich gewesen. Der Erste Entwurf könnte so aussehen:
Sorry hatte es im ersten Post versucht zu erklären was ich damit meine.
++++ Config-Datei:
# Anhand dieser Config-Datei werden PDF-Dateien mehrerer Kundennummern gruppiert.
> # Der Gruppenname entspricht dem Dateinamen der Ausgabedatei.
> #
> # Die Datei ist wie folgt aufgebaut:
> # <Gruppenname>, <Kundennummer1>, <Kundennummer2>, <Kundennumer3>, ...
> GruppeABC, 10496, 12435, 45769, 32456
> GruppeXYZ, 49623, 14756, 97856, 45670

back-to-topPowershell Skript:
$Config = 'C:\Test\Kundengruppen.conf'  
> $Quelle = 'C:\Test'  
> $Ziel   = 'C:\Output'  
> 
> # Kundengruppen aus Config-Datei laden
> Foreach ($Gruppe in (Get-Content $Config) -NotMatch '^#') {  
>   $Gruppe = $Gruppe -Split ',\s?'  
>   
>   # PDF-Dateien für jede Gruppe sammeln
>   [Array]$PDFs = Foreach ($Nummer in $Gruppe[1..($Gruppe.Count-1)]) { Get-ChildItem "$Quelle\*$Nummer.pdf" }  
>   
>   # PDFs zusammenfügen
>   Merge-PDF $PDFs ("$Ziel\"+$Gruppe+'.pdf')  
> 
> }
Danke! Genau so meinte ich es mit der Config. Werde ich gleich mal testen danke face-smile

Die Frage die sich mir stellt ist, was soll mit PDF's passieren, die keiner Gruppe zugeordnet sind?

Nichts :D Die sind dann ja Okay und können so weggeschickt werden.
Springstil
Springstil 02.06.2021 um 11:32:30 Uhr
Goto Top
Resolve-Path : Das Argument kann nicht an den Parameter "Path" gebunden werden, da es NULL ist.  
In C:\Users\USER\Documents\WindowsPowerShell\Modules\MergePdf\1.1\MergePdf.psm1:80 Zeichen:32
+         $files = (Resolve-Path $path).Path
+                                ~~~~~
    + CategoryInfo          : InvalidData: (:) [Resolve-Path], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.ResolvePathCommand
 
WARNUNG: No pages were added. File was not created.

Den Fehler bekomme ich ausgegeben. Das eigenartige an der Sache ist, das er sich Willkürlich eine PDF von meinem Rechner zieht und die dann im Output Ordner ausgibt.
TK1987
Lösung TK1987 02.06.2021 aktualisiert um 12:53:08 Uhr
Goto Top
Zitat von @Springstil:
Resolve-Path : Das Argument kann nicht an den Parameter "Path" gebunden werden, da es NULL ist.  
Den Fehler bekomme ich ausgegeben. Das eigenartige an der Sache ist, das er sich Willkürlich eine PDF von meinem Rechner zieht und die dann im Output Ordner ausgibt.

Ok, dass könnte 2 Ursachen haben:
    • Zu einer Gruppe existieren keine passenden PDF-Dateien - in dem Fall wäre der $PDFs-Array leer und Merge-PDF scheitert natürlich
    • In meinen Tests hat es zwar Funktioniert, die Dateien als [io.fileinfo]-Klasse zu übergeben, Merge-PDF erwartet aber eigentlich einen String-Array.

Im ersten Fall sollte der Befehl zum zusammenfügen natürlich übersprungen werden. Für Punkt 2 könnten wir die Dateien direkt mit vollem Pfad übergeben. Neuer Versuch:
$Config = 'C:\Test\Kundengruppen.conf'  
$Quelle = 'C:\Test'  
$Ziel   = 'C:\Output'  

# Kundengruppen aus Config-Datei laden
Foreach ($Gruppe in (Get-Content $Config) -NotMatch '^#') {  
  $Gruppe = $Gruppe -Split ',[\t\s]*'  
  
  # PDF-Dateien für jede Gruppe sammeln
  [Array]$PDFs = Foreach ($Nummer in $Gruppe[1..($Gruppe.Count-1)]) { Get-ChildItem "$Quelle\*$Nummer.pdf" }  

  # Wenn keine PDF-Dateien vorhanden, melde Fehler und überspringe
  if ( !$PDFs ) { write-host -ForegroundColor 'red' "Keine passenden PDF-Dateien für Gruppe ""$($Gruppe)"" gefunden. " ; Continue }  
  
  # PDFs zusammenfügen
  try {
    write-host -NoNewLine "Erstelle $($Gruppe).PDF... "  
    $Output = Merge-PDF -Force $PDFs.Fullname ("$Ziel\"+$Gruppe+'.pdf') -ErrorAction Stop  
    write-host -ForegroundColor 'green' "erfolgreich. "  
  }
  catch { write-host -ForegroundColor 'red' $_.Exception.Message }  

}
Springstil
Springstil 02.06.2021 um 15:24:27 Uhr
Goto Top
Das hat geklappt face-smile Vielen dank! Ich glaube es lag auch daran das ich in der Conf vergessen habe mit einem "," abzuschließen -.- Sorry
TK1987
TK1987 02.06.2021 um 15:45:15 Uhr
Goto Top
Zitat von @Springstil:
Das hat geklappt face-smile Vielen dank!
Wunderbar, gerne.
Ich glaube es lag auch daran das ich in der Conf vergessen habe mit einem "," abzuschließen -.- Sorry
Du meinst am Zeilenende?
Das braucht man nicht mit einem Komma abzuschließen... oder wenn ich genauer drüber nachdenke, darf man die Zeile derzeit gar nicht mit einem Komma abschließen, da in der Foreach-Schleife das letzte Element sonst leer ist und
Get-ChildItem "$Quelle\*$Nummer.pdf"  
dann quasi nur noch *.pdf steht - somit also alle PDF's ungeachtet der Kundennummern zusammengefügt werden.

Sollte also sogar verhinder werden, Zeile 10 daher bitte wie folgt ändern:
[Array]$PDFs = Foreach ($Nummer in $Gruppe[1..($Gruppe.Count-1)] | Where-Object {$_} ) { Get-ChildItem "$Quelle\*$Nummer.pdf" }