hatl
Goto Top

Mehrere PDF zu PDF mit 1000 Seiten zusammenführen

Hallo!

Ich hab mit der Zusammenführung mehrer PDF – Dateien Probleme, vielleicht könnt ihr mir weiterhelfen.

Eine Applikation erstellt regelmäßig etwa 3000 PDF Dateien, mit jeweils 1 bis 5 Seiten.
Die Dateinamen beginnen immer entweder mit "A_" oder mit "J_", alle Dateien werden in einem bestimmten Ordner abgelegt.

Ich muss jetzt per Batch alle mit "A_" beginnenden PDF zu PDF- Dateien mit max. 1000 Seiten zusammenführen.
Danach sollen alle mit "J_" beginnenden PDF zu PDF- Dateien mit max. 1000 Seiten zusammengeführt werden.
Die zusammengeführten Dateien sollen dann wieder in einem bestimmten Ordner abgelegt werden, wobei der Dateiname wieder mit "A_" bzw. "J_" beginnen muss.

Mit Ghostscript können *.ps – Files zusammengefügt werden, aber kann man auch gleich direkt *.pdf - Dateien zusammenfügen? Bei rund 3000 Dateien dauert sonst die Umwandlung in *.ps schon einige Zeit.

Wichtiger ist aber wie ich die Seitenahmzahl prüfen kann.
Gibt es irgendeine Möglichkeit zu prüfen wie viele Seiten ein PDF schon hat und nur dann ein zusätzlich zuzufügen wenn es weniger als 1000 Seiten hat. Oder kann man sonst irgendwie dafür sorgen das die Dateien max. 1000 Seiten haben?

Wenn man die Anzahl der Seiten nicht feststellen kann, wie kann ich überhaupt per Batch dafür sorgen, dass nur die Dateien deren Name mit einem bestimmten Zeichen beginnt zusammengeführt werden?

Ich steh da im Moment ziemlich am Schlauch, hoffentlich könnt ihr mir ein paar Tipps geben!

Danke!!

lg

Content-ID: 47300

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

Ausgedruckt am: 22.11.2024 um 21:11 Uhr

ketchup
ketchup 08.01.2007 um 16:44:36 Uhr
Goto Top
AxelHahn
AxelHahn 08.01.2007 um 16:44:47 Uhr
Goto Top
Hallo lg,


ich kan nur Schnipselchen liefern ... habe gerade keine Zeit, ein funktionierendes Etwas zusammenzubasteln.

--- Zusammenfügen:
Suche nach einem Tool pdftk.
Zum Zusammenfügen gibt es:

pdftk *.pdf cat output combined.pdf

--- Seitenahnzahl
http://www.foolabs.com/xpdf/
Das dortige tool "pdfinfo" liefert Infos zu einem PDF ... u.a. auch die Seitenanzahl.

pdfinfo [Dateiname]


Viele Grüsse
-= Axel =-
Viele Grüsse
-= Axel =-
bastla
bastla 08.01.2007 um 19:28:00 Uhr
Goto Top
Hallo Hatl!

Ich muss jetzt per Batch alle mit "A_" beginnenden PDF zu PDF- Dateien mit max. 1000 Seiten zusammenführen.
In welcher Reihenfolge sollen die Dateien zusammengefügt werden - gibt es eine laufende Nummer, kann man chronologisch vorgehen, ist es egal?

Die zusammengeführten Dateien sollen dann wieder in einem bestimmten Ordner abgelegt werden, wobei der Dateiname wieder mit "A_" bzw. "J_" beginnen muss.
Wie sollen die Ergebnis-pdf-Files genau heißen? Gibt es für die Ergebnisse einen immer gleich bleibenden Zielordner?

Wurden die Einzeldateien vor der Bearbeitung gesichert und dürfen daher verschoben bzw auch gelöscht werden?
@AxelHahn

pdftk Test.pdf dump_data 
liefert auch die Seitenzahl - ein Tool weniger erforderlich. face-smile

Grüße
bastla
bastla
bastla 09.01.2007 um 02:06:23 Uhr
Goto Top
Hallo Hatl!

Ich habe einmal vorweg meine oben gestellten Fragen wie folgt selbst beantwortet face-wink:

Die pdf-Dateien werden in chronologischer Reihenfolge zunächst aus dem Quell-Ordner ("SourceDir") in temporäre Ordner "A_2007-01-09_#" bzw "J_2007-01-09_#" (im Pfad "TempDir") verschoben (# ist eine laufende Nummer, beginnend bei 1), wobei die Gesamtseitenzahl aller Dateien eines Ordners max 1000 beträgt (falls es keine Ausgangsdatei mit mehr als 1000 Seiten gibt face-wink).
Vor der Verarbeitung der einzelnen Dateien wird der gesamte Temp-Ordner gelöscht (und damit die Einzel-pdf-Dateien des letzten Durchlaufes).
Da das verwendete pdf-Tool "pdftk-1.12" anscheinend keine unter Anführungszeichen stehenden Dateinamen mit Platzhalterzeichen ("*") verarbeiten kann, dürfen weder der "TempDir"-Pfad noch die Namen der einzelnen pdf-Dateien Leerstellen aufweisen!
Für die Erstellung des Datums wurde angenommen, dass ein echo %date% an der Kommandozeile eine Datumsanzeige der Form 09.01.2007 (also ohne Wochentag) ergibt - anderenfalls wäre eine Anpassung erforderlich.

In einem zweiten Arbeitsschritt werden alle Dateien jedes temporären Ordners zu einer einzigen pdf-Datei zusammengefasst. Der Name dieser Datei entspricht dem Namen des temporären Ordners. So entstehen also die Dateien "A_2007-01-09_1.pdf", "A_2007-01-09_2.pdf", ... (analog für "J_*").

Abgelegt werden diese Dateien in einem vorgegebenen Ziel-Ordner ("TargetDir").

Bis zum nächsten Lauf der Batchdatei bleiben die ursprünglichen pdf-Dateien in den temporären Ordnern gespeichert.

So wie für die oben besprochenen Verzeichnisse ist auch der Pfad des verwendeten Programmes "pdftk-1.12" (Download über die Projektseite; keine Installation, sondern nur Entpacken erforderlich) in der Batchdatei zu hinterlegen (Zeilen 2 bis 5).

@echo off & setlocal
set SourceDir=D:\PDF
set TargetDir=D:\PDFertig
set TempDir=D:\PDFTemp
set Prog=C:\Programme\pdftk-1.12\pdftk.exe
::Download "the pdf toolkit" über: http://www.accesspdf.com/index.php?topic=pdftk 
set NameNeu=%Date:~6,4%-%Date:~3,2%-%Date:~0,2%_
::Bei Bedarf auch Uhrzeit einfügen
::for /f "tokens=1-3 delims=:, " %%a in ('echo %time%') do set NameNeu=%NameNeu%%%a-%%b-%%c_ 
set MaxSeiten=1000
If exist %TempDir% rd /s /q %TempDir%
md %TempDir%
for %%a in (A_ J_) do call :ProcessFiles %%a
for %%a in (A_ J_) do call :ProcessFolders %%a
echo.
echo Bearbeitung abgeschlossen.
goto :eof
:ProcessFiles
If not exist "%SourceDir%\%1*.pdf" (echo Keine %1-Dateien vorhanden.) & goto :eof  
set SammelDir=%1%NameNeu%
set /a Teil=1
set /a Seiten=0
md "%TempDir%\%SammelDir%%Teil%"  
echo Bearbeite Sammelordner %SammelDir%%Teil%
for /f "delims=" %%f in ('dir "%SourceDir%\%1*.pdf" /b /od') do (for /f "tokens=2" %%i in ('%Prog% "%SourceDir%\%%f" dump_data ^| find "NumberOfPages"') do call :Check "%%f" %%i)  
goto :eof
:Check
set /a Seiten=%Seiten%+%2
if %Seiten% leq %MaxSeiten% goto :MoveIt
set /a Teil+=1
md "%TempDir%\%SammelDir%%Teil%"  
echo Bearbeite Sammelordner %SammelDir%%Teil%
set Seiten=%2
:MoveIt
move "%SourceDir%\%~1" "%TempDir%\%SammelDir%%Teil%"  
goto :eof
:ProcessFolders
If not exist "%TempDir%\%1*" (echo Keine %1-Verzeichnisse vorhanden.) & goto :eof  
for /f %%f in ('dir "%TempDir%\%1*" /b /ad') do %Prog% %TempDir%\%%f\*.pdf cat output "%TargetDir%\%%f.pdf"  
Die Batchdatei sollte wie beschrieben funktionieren, ist aber nur oberflächlich getestet.

Grüße
bastla
Hatl
Hatl 09.01.2007 um 16:37:08 Uhr
Goto Top
Hallo!

Vielen Dank für die schnelle Hilfe an euch alle!

@bastla
Der batch macht genau was ich brauche, genial!

Nur eines versteh ich nicht ganz, folgende Zeile:

for %%a in (A_ J_) do call :ProcessFiles %%a

Woran kann ich hier erkennen, dass im definierten SourceDir nach PDF beginnend mit A_ u. J_ gesucht wird? Hier steht ja niergendes ein Pfad, bzw. das das A und J im Dateinamen zu finden sein sollen.

Vielen Dank!

lg
bastla
bastla 09.01.2007 um 17:47:59 Uhr
Goto Top
Hallo Hatl!

Villeicht vorweg ganz allgemein:

Die "for"-Zeile ist nur für die Steuerung des zweimaligen Durchlaufs (für "A_" und für "J_") der eigentlichen Verarbeitung in der Routine ab ":ProcessFiles" zuständig. Beim Aufruf dieses "Unterprogrammes" wird die Kennung mit übergeben ("call :ProcessFiles %%a", wobei %%a beim ersten Mal das "A_" aus der Klammer vorne und beim zweiten Mal das "J_" enthält.

Dir Routine ":ProcessFiles" übernimmt das beim Aufruf mitgegebene Argument (wie jede Batchdatei) als "%1" und arbeitet damit weiter (um zB den Namen des Sammel-Verzeichnisses aus %1 und der am Anfang definierten Variable %NameNeu% zusammenzusetzen -> so entsteht "A_2007-01-09_").

Analog die Vorgangsweise für ":Check" - hier werden beim Aufruf der Dateiname (%%f) und die Seitenanzahl (%%i) übergeben und in der Routine wiederum als %1 und %2 übernommen.

Allfällige Anführungszeichen dienen immer dazu, eventuelle Leerzeichen "einzuschließen", da in Batch eine Leerstelle generell als Trennzeichen gilt (und so zB aus einem Dateinamen mit 2 Leerstellen 3 Argumente würden).

Woran kann ich hier erkennen, dass im definierten SourceDir nach PDF beginnend mit A_ u. J_ gesucht wird? Hier steht ja niergendes ein Pfad, bzw. das das A und J im Dateinamen zu finden sein sollen.
Die Zeile
If not exist "<b>%SourceDir%\%1*.pd</b>f" (echo Keine <b>%1</b>-Dateien vorhanden.) & goto :eof  
wird beispielsweise beim ersten Durchlauf so ausgeführt:
If not exist "<b>D:\PDF\A_*.pdf</b>" (echo Keine <b>A_</b>-Dateien vorhanden.) & goto :eof  
und der Aufruf der einzelnen A_*.pdf erfolgt hier:
for /f "delims=" %%f in ('dir "<b>%SourceDir%\%1*.pdf</b>" /b /od') do ...  

Noch eine Anmerkung: Wenn der Batch nur einmal an einem Tag läuft, sollte die Benennung mit dem Datum genügen, ansonsten kann ich bei Bedarf noch die Uhrzeit als Zusatzinformation in den Dateinamen einbauen.
Im Übrigen ist zu betonen, dass die eigentliche Arbeit ja durch das Tool "pdftk" erledigt wird - schön, dass es solche Software frei verfügbar gibt.

Grüße
bastla
Biber
Biber 10.01.2007 um 13:18:52 Uhr
Goto Top
Nachfrage:
Gelöst?
Darf der Beitrag geschlossen werden?

Grüße
Biber
Hatl
Hatl 10.01.2007 um 14:16:56 Uhr
Goto Top
Nachfrage:
Gelöst?
Darf der Beitrag geschlossen werden?

Grüße
Biber

Bitte noch nicht.

lg
Hatl
Hatl 10.01.2007 um 17:06:58 Uhr
Goto Top
Hallo!

Danke für die ausführliche Erklärung, dachte dass mir jetzt alles klar ist, aber ein Problem hab ich damit noch.

Wenn der Batch erfolgreich gelaufen ist sollte das SourceDir leer sein. Es kommt aber immer wieder vor (aber eben nicht immer), dass 1 oder 2 Dateien im SourceDir überbleiben, diese wurden auch definitiv nicht an ein 1000 Seitiges PDF angefügt. Also wurden sie definitiv nicht verarbeitet.

Um sicherzustellen, dass der Prozess welcher die PDF – Erstellt (inputdaten) nicht noch eine Datei im Zugriff hat und sie deshalb nicht verschoben werden kann, kopiert der Batch zuerst die Inputdaten in ein neues „SourceDir“.
Aber das hat nichts verändert.

Dachte dann dass der Fehler passiert wenn einen Datei nicht mehr in den Sammelordner passt, da schon 1000 Seiten drin sind.
Es hätte für mich den Eindruck gemacht, dass eben die Datei die nicht mehr in den Ordner passt, vergessen wird, aber im Batch könnte ich hier das Problem nicht erkennen.

Hat vielleicht noch jemand eine Idee wo der Fehler liegen könnte, bzw was ich dagegen unternehmen könnte?

In Zuge dessen ist mir noch was aufgefallen:

In folgender „For - Zeile“ werden ja praktisch die einzelnen Dateien verarbeitet und die Seitenanzahl ermittelt:

for /f "delims=" %%f in ('dir "%temp%\%1*.pdf" /b /od') ……

Die „dir – Ausgabe“ wird nach Datum/Zeit sortiert ausgegeben, also werden beginnen bei der ältesten Datei und dann eine nach der anderen gecheckt und verschoben.
Wenn es nun im Sammelordner schon 998 Seiten gibt, und das nächste PDF 4 Seiten hat, passt es nicht mehr in den Ordner, also wird ein neuer begonnen. Somit wird aus dem Ordner in welchen 998 Seiten liegen ein PDF mit 998 Seiten erstellt.
Wenn das so stimmt, kann eine Outputdatei schlussendlich 996-1000 Seiten haben (da ein Input PDF max. 5 Seiten hat).
Meine Dateien haben aber immer 1000 Seiten (außer der Letzten, da es da ja nicht mehr genug Inputdaten gibt).
Das versteh ich nicht, ist das Zufall?


Vielen Dank für eure Mühe!

lg
bastla
bastla 10.01.2007 um 17:39:56 Uhr
Goto Top
Hallo Hatl!

Zumindest was die "zufälligen" 1000 Seiten angeht, hätte ich einen Vorschlag:
Füge die folgende Zeile zwischen dem Label ":MoveIt" und der "move ..."-Zeile ein:
echo %SammelDir%%Teil%;%Seiten%;%1;%2 >> D:\Log.txt
Damit wird vor jedem Verschiebevorgang der TeileOrdner, die akkumulierte Seitenzahl (nach dem Hinzufügen der aktuellen Datei), der Dateiname und die Seitenanzahl protokolliert. Wenn Du ein ";" als Trennzeichen verwendest, könntest Du die Logdatei zB in Excel importieren und damit etwas übersichtlicher darstellen.

Leider bin ich momentan etwas unter Zeitdruck ...

Grüße
bastla

[Edit] Trennzeichen auf ";" geändert [/Edit]
Hatl
Hatl 11.01.2007 um 16:43:38 Uhr
Goto Top
Hallo!

Ich hab das logfile eingebaut. Es ist wirklich Zufall das es immer 1000 Seiten sind, also das passt so.

Das Problem mit den Dateien die nicht verschoben werden, konnte ich noch nicht lösen.
Wenn ich mir den Batch anschaue kann es eigentlich nicht sein, dass Dateien nicht verschoben werden, es passieret aber dennoch.

Ich erzeuge jetzt ja ein logfile mit den Daten der verschobenen Dateien, auch hier sind die übergebliebenen Dateien nicht zu finden. Also werden sie offenbar einfach ignoreirt.

Ich umgehe das Problem jetzt, indem ich am Schluss Prüfe ob das SourceDir leer ist, wenn nicht werden alle Daten gelöscht und die Verarbeitung neu gestartet.
Ist zwar nicht schön aber muss fürs erste reichen.

Hat vielleicht noch jemand eine Idee wo das Problem liegen könnte?

Vielen Dank!!!

lg
bastla
bastla 11.01.2007 um 18:20:26 Uhr
Goto Top
Hallo Hatl!

Um zu klären, wo diese Rest-Dateien auf der Strecke bleiben, könntest Du eine weitere Logzeile gleich am Anfang des ":Check"-Teiles einbauen - so siehst Du wenigstens, ob sie bis dort hin gekommen sind.

Die heftigste Variante des Loggens wäre übrigens der Verzicht auf das "Echo off" in Zeile 1 und der Aufruf der Batch-Datei mit "Batch-Datei > LogFull.txt".

Ich gehe davon aus, dass Du die fraglichen Dateien schon auf Besonderheiten / Gemeinsamkeiten hin abgeklopft hast, und kann mir leider derzeit nicht vorstellen, was der Grund für die "Nichtbeachtung" sein könnte (noch nicht einmal eine falsch ermittelte Seitenzahl dürfte sich auswirken - wenn sie nicht mehr in den einen Ordner passen, kommen sie ja ohne weitere Prüfung in den nächsten).

Grüße
bastla
Hatl
Hatl 15.01.2007 um 16:59:10 Uhr
Goto Top
Hallo!

Hab beim :check ein Log eingebaut und die LogFull.txt erzeugt, aber ich konnte nichts wirkliches feststellen.
Meiner Meinug nach liegt das Problem eher am FileSystem als am Batch.
Somit reicht meine Lösung mit dem nochmaligen aufruf des Batch.

Hab es jetzt auch auf einen anderen Rechner und da passt alles.

Vielen Dank für die schnelle und umfangreiche Hilfe!!!

lg
Biber
Biber 15.01.2007 um 21:16:15 Uhr
Goto Top
Moin hatl,

dieser Seiteneffekt kann eigentlich nur deshalb auftreten, weil manchmal auch *.pdf's mit "Leerzeichen im Namen oder Pfad" dabei sind.
Denn zumindest in bastla's obiger Skizze ist es nicht durchgängig berücksichtigt, z.B. in der letzten Zeile:
...
If not exist "%TempDir%\%1*" (echo Keine %1-Verzeichnisse vorhanden.) & goto :eof  
for /f <b>"delims="</b> %%f in ('dir "%TempDir%\%1*" /b /ad')  

Ergänze das fett gedruckte bei allen For/F-Anweisungen, dann sollte es auch reproduzierbar auf beliebigen Rechnern klappen.

Aber, wenn ich Dich richtig verstanden habe, könnte von Deiner Seite so oder so ein Haken dran?

Grüße
Biber
der offene Beiträge hasst, wenn sie in Rudeln auftreten...
bastla
bastla 15.01.2007 um 22:09:55 Uhr
Goto Top
@Biber

Danke für die Nachbesserung (auch die %TempDir% weiter oben müssten noch Anführungszeichen bekommen), obwohl es nicht daran liegen sollte - die fragliche "for"-Schleife bearbeitet nur bereits fertig befüllte Verzeichnisse, während das Problem die nicht verschobenen Dateien (Routine ":ProcessFiles" zum Befüllen der Verzeichnisse) sind.

Aber da Hatl sich zu helfen wusste (und mir mangels näherer Kenntnis seiner Dateien die Ideen ausgegangen sind), schließe ich mich Deinem Vorschlag zum "Abhaken" des Themas an ...

Grüße
bastla