[PHP] PDF Dateien zusammenführen

nchristoph

Erfahrenes Mitglied
Hallo zusammen,

ich versuche gerade mehrere PDF Dateien nach dem Upload zu einer Datei zusammenzufügen.

Ich verwende FPDF und FPDI.

Mein aktueller Ansatz ist folgender:

PHP:
class concat_pdf extends fpdi {

  var $files = array();

  function concat_pdf($orientation='P',$unit='mm',$format='A4') {
  parent::fpdi($orientation,$unit,$format);
  }

  function setFiles($files) {
  $this->files = $files;
  }
  function concat() {
  foreach($this->files AS $file) {
  $pagecount = $this->setSourceFile($file);
  for ($i = 1; $i <= $pagecount; $i++) {
  $tplidx = $this->ImportPage($i);
  $this->AddPage();
  $this->useTemplate($tplidx);
  }
  }
  }
}
  $liste = new concat_pdf();
   //var_dump($_FILES);
   if(isset($_FILES['massliste']['tmp_name']) && isset($_FILES['massliste_1']['tmp_name']) && isset($_FILES['massliste_2']['tmp_name']) && isset($_FILES['massliste_3']['tmp_name'])){
     $liste->setFiles(array($_FILES['massliste']['tmp_name'],$_FILES['massliste_1']['tmp_name'],$_FILES['massliste_2']['tmp_name'],$_FILES['massliste_3']['tmp_name']));
   }else if(isset($_FILES['massliste']['tmp_name']) && isset($_FILES['massliste_1']['tmp_name']) && isset($_FILES['massliste_2']['tmp_name'])){
     $liste->setFiles(array($_FILES['massliste']['tmp_name'],$_FILES['massliste_1']['tmp_name'],$_FILES['massliste_2']['tmp_name']));
   }else if(isset($_FILES['massliste']['tmp_name']) && isset($_FILES['massliste_1']['tmp_name'])){
     $liste->setFiles(array($_FILES['massliste']['tmp_name'],$_FILES['massliste_1']['tmp_name']));
   }else{
     $liste->setFiles(array($_FILES['massliste']['tmp_name']));
   }
   $liste->concat();
   $liste->Output("./pdfmerge/mergedpdf.pdf","D");

Als Ausgabe erhalte ich lediglich das:
Code:
FPDF error: Some data has already been output, can't send PDF file

Habe jetzt schon ne Zeitlang gegoogled, aber keine Lösung die ich gefunden habe, hat mir geholfen.

Hat von euch wer eine Idee? Eventuell auch, wie ich die if Abfrage für die 4 Felder vereinfachen könnte.

Grüsse
 
Zuletzt bearbeitet:
Das wird wohl daran liegen das FPDF versucht irgendwelche header zu senden, die den Browser dann veranlassen, die PDF Datei korrekt zu interpretieren. Lösung: Du darfst vor dieser Zeile "$liste->Output("./pdfmerge/mergedpdf.pdf","D");" keinerlei Ausgaben haben. Also KEINE echos, KEIN HTML, KEINE Lerrzeichen und auch KEIN BOM (Byte Order Mark). Sihe dazu http://php-de.github.io/jumpto/headers-already-sent/
 
Ok das der Fehler dergleiche ist, wie bei der normale Headers already sent hätte ich nicht gedacht.

Allerdings hat auch das hinzufügen von ob_start() und ob_end_flush() bzw. das entfernen von ?> nichts an der Fehlermeldung geändert.
 
Also ich hab es jetzt hinbekommen indem ich einen 2ten Schritt eingebaut habe.

Jetzt haperts noch bei der Überprüfung:

PHP:
    if(isset($_FILES['massliste_1']) AND "" != $_FILES['massliste_1']['tmp_name']){   
       $merge->addPDF('./copy/1.pdf');
     }else if((isset($_FILES['massliste_1']) AND "" != $_FILES['massliste_1']['tmp_name'])AND (isset($_FILES['massliste_2']) AND "" != $_FILES['massliste_2']['tmp_name'])){     
       $merge->addPDF('./copy/1.pdf');
       $merge->addPDF('./copy/2.pdf');
     }

Mein Ziel ist es, je nachdem, welche und wieviele $_FILES Einträge existieren, dementsprechend die Dateien in den merge array einzufügen.

Leider wird immer nur die Massliste_1 eingefügt, in der 2ten if kommt er leider nicht an.

Gibt es eine elegantere Lösung? Soll ich in diesem Fall das Pferd von hinten aufzäumen?
 
Das ist ein Logikfehler.
Die erste IF-Bedingung trifft, der Block wird also ausgeführt. Das ELSE IF wird gar nicht mehr in Betracht gezogen. Das "else" impliziert ja schon, dass etwas anderes eintreten muss (also nur wenn die vorherigen IFs und ELSE IFs nicht zutrafen).

Eine Liste von allen hochgeladenen Dateien bekommst du so:
PHP:
$files = array_keys($_FILES);
Dann kannst du dieses iterieren:
PHP:
foreach ($files as $file) {
  // ...
}
 
Also wenn ich jetzt als erstes mit der IF prüfe ob beide Felder gefüllt sind dann müsste der Code eigentlich funktionieren oder?

PHP:
if((isset($_FILES['massliste_1']) AND "" != $_FILES['massliste_1']['tmp_name']) AND (isset($_FILES['massliste_2']) AND "" != $_FILES['massliste_2']['tmp_name'])){
       $merge->addPDF('./copy/1.pdf');
       $merge->addPDF('./copy/2.pdf');
     }else if(isset($_FILES['massliste_1']) AND "" != $_FILES['massliste_1']['tmp_name']){
       $merge->addPDF('./copy/1.pdf');
     }
 
Ja, unter der Annahme, dass du massliste_1 und _2 auch wirklich gesetzt sind.

Ich würde mal folgende Funktion erstellen, damit deine IF-Bedingungen überschaubarer werden:
PHP:
function fileUploaded($name) {
  return isset($_FILES($name)) && $_FILES[$name]['tmpname'] !== '';
}

if (fileUploaded('massliste_1') && fileUploaded('massliste_2')) {
  $merge->addPDF('./copy/1.pdf');
  $merge->addPDF('./copy/2.pdf');
}
 
Zurück