PDF-Dokumente in PHP mit FPDI und FPDF zusammenführen
Möchten Sie in Ihrer PHP-Anwendung mehrere PDFs zu einer einzigen Datei zusammenführen? In diesem DevTip zeigen wir, wie Sie PDF-Dokumente programmatisch mit PHP und den Bibliotheken FPDI und FPDF kombinieren. Diese Werkzeuge bieten einen unkomplizierten Weg, PDFs direkt auf Ihrem Server zu bearbeiten.
Voraussetzungen
Stellen Sie vor dem Start sicher, dass Ihre Umgebung diese Anforderungen erfüllt:
- Eine unterstützte PHP-8-Version
- Composer zur Verwaltung von PHP-Abhängigkeiten
- Grundlegendes Verständnis von PHP-Programmierkonzepten
- Die PHP-Erweiterung Zlib muss aktiviert sein (von FPDI vorausgesetzt)
FPDI und FPDF installieren
Sie können beide Bibliotheken mit Composer installieren. Wechseln Sie im Terminal in Ihr Projektverzeichnis und führen Sie aus:
composer require setasign/fpdf:1.8.* setasign/fpdi:^2.0
Composer übernimmt das Autoloading, sodass die Klassen in Ihren PHP-Skripten sofort verfügbar sind.
Ein PDF mit FPDF erzeugen
FPDF ist eine Bibliothek, um PDF-Dokumente mit PHP von Grund auf zu erzeugen. Hier ein einfaches
Beispiel, das eine einseitige PDF-Datei namens hello_world.pdf mit dem Text
„Hello World!“ erstellt:
<?php
require 'vendor/autoload.php';
// Use the global namespace for FPDF
$pdf = new \FPDF();
$pdf->AddPage();
$pdf->SetFont('Arial', 'B', 16);
$pdf->Cell(40, 10, 'Hello World!');
$pdf->Output('F', 'hello_world.pdf'); // 'F' saves to a local file
Bestehende PDFs mit FPDI importieren
FPDI erweitert FPDF um die Fähigkeit, Seiten aus bestehenden PDF-Dokumenten zu importieren. Diese
importierten Seiten können Sie anschließend in das PDF einfügen, das Sie mit FPDF erzeugen. Dieses
Beispiel importiert die erste Seite aus existing.pdf und speichert sie als
imported.pdf:
<?php
require 'vendor/autoload.php';
use setasign\Fpdi\Fpdi;
$pdf = new Fpdi();
// Specify the source PDF file
$pdf->setSourceFile('existing.pdf');
// Import the first page
$pageId = $pdf->importPage(1);
// Add a page to the new PDF
$pdf->AddPage();
// Use the imported page as a template
$pdf->useTemplate($pageId);
// Save the resulting PDF
$pdf->Output('F', 'imported.pdf');
Zwei PDFs zusammenführen
Wenn wir beide Konzepte kombinieren, lässt sich eine Funktion erstellen, die zwei PDF-Dateien Seite
für Seite zusammenführt. Diese Hilfsfunktion nimmt zwei Eingabepfade ($a, $b) und einen Ausgabepfad ($out) entgegen, liest alle Seiten aus beiden
Eingabedateien und schreibt sie nacheinander in die Ausgabedatei merged.pdf. Sie
enthält eine einfache Fehlerbehandlung.
<?php
require 'vendor/autoload.php';
use setasign\Fpdi\Fpdi;
use setasign\Fpdi\PdfParser\PdfParserException;
function mergeTwo(string $a, string $b, string $out): bool {
try {
$pdf = new Fpdi();
foreach ([$a, $b] as $file) {
if (!is_readable($file)) {
error_log("Cannot read file: $file");
return false; // Or throw an exception
}
$pageCount = $pdf->setSourceFile($file);
for ($i = 1; $i <= $pageCount; $i++) {
$tpl = $pdf->importPage($i);
$size = $pdf->getTemplateSize($tpl);
// Add a page with the same size and orientation
$pdf->AddPage($size['orientation'], [$size['width'], $size['height']]);
$pdf->useTemplate($tpl);
}
}
$pdf->Output('F', $out);
return true;
} catch (PdfParserException $e) {
error_log('PDF Parser Error during merge: ' . $e->getMessage());
return false;
} catch (\Exception $e) { // Catch other potential exceptions
error_log('General error during PDF merge: ' . $e->getMessage());
return false;
}
}
// Example usage:
// Ensure a.pdf and b.pdf exist
// mergeTwo('a.pdf', 'b.pdf', 'merged.pdf');
Beliebig viele PDFs zusammenführen
Häufig müssen Sie eine dynamische Liste von PDF-Dateien zusammenführen. Diese Funktion nimmt ein Array von Dateipfaden entgegen und führt sie zu einer einzigen Ausgabedatei zusammen. Sie prüft, ob die Dateien lesbar sind, und behandelt mögliche Parsing-Fehler.
<?php
require 'vendor/autoload.php';
use setasign\Fpdi\Fpdi;
use setasign\Fpdi\PdfParser\PdfParserException;
function mergeMany(array $files, string $out): bool {
try {
$pdf = new Fpdi();
foreach ($files as $file) {
if (!is_readable($file)) {
error_log("Cannot read file, skipping: $file");
continue; // Skip this file
}
$pageCount = $pdf->setSourceFile($file);
for ($p = 1; $p <= $pageCount; $p++) {
$tpl = $pdf->importPage($p);
$size = $pdf->getTemplateSize($tpl);
$pdf->AddPage($size['orientation'], [$size['width'], $size['height']]);
$pdf->useTemplate($tpl);
}
}
// Only output if at least one page was added
if ($pdf->PageNo() > 0) {
$pdf->Output('F', $out);
return true;
} else {
error_log("No pages were successfully merged.");
return false;
}
} catch (PdfParserException $e) {
error_log("PDF Parser Error during mergeMany: " . $e->getMessage());
return false;
} catch (\Exception $e) {
error_log("General error during mergeMany: " . $e->getMessage());
return false;
}
}
// Example usage:
// $pdfFiles = ['doc1.pdf', 'doc2.pdf', 'doc3.pdf'];
// mergeMany($pdfFiles, 'combined_document.pdf');
Speicher bei großen Dateien verwalten
Die PDF-Verarbeitung kann speicherintensiv sein, insbesondere beim Zusammenführen mehrerer oder großer Dokumente. Hier einige Tipps:
- PHP-Limits erhöhen: Wenn Fehler wegen erschöpftem Speicher auftreten, erwägen Sie, das
Speicherlimit und die Ausführungszeit von PHP in Ihrer Datei
php.inizu erhöhen oderini_set()am Anfang Ihres Skripts zu verwenden (auf Shared Hosting mit Vorsicht einsetzen):ini_set('memory_limit', '256M'); // Adjust as needed, e.g., '512M', '1G' ini_set('max_execution_time', '300'); // 5 minutes, adjust as needed - Ressourcen freigeben: Heben Sie nach dem Erzeugen des Ausgabe-PDFs die Zuweisung des
FPDI-Objekts explizit auf und stoßen Sie die Garbage Collection an, um Speicher freizugeben,
besonders in lang laufenden Skripten oder Schleifen:
// Assuming $pdf is your FPDI object after Output() unset($pdf); if (function_exists('gc_collect_cycles')) { gc_collect_cycles(); } - Alternativen prüfen: Bei sehr großen Dateien oder beim Zusammenführen in hohem Volumen, wo die serverseitige Verarbeitung an Ressourcengrenzen stoßen kann, ist es robuster und skalierbarer, die Aufgabe an einen spezialisierten Dienst auszulagern.
Die Dokumentenverarbeitung von Transloadit nutzen
Bei Produktions-Workloads – insbesondere beim Umgang mit großen Dateien, beim häufigen
Zusammenführen vieler Dokumente oder bei Bedarf an fortgeschritteneren Funktionen – kann das
Auslagern der Aufgabe effizienter und skalierbarer sein. Der
Robot /document/merge von Transloadit ist genau dafür gemacht:
- Führt mehrere PDFs zuverlässig zusammen.
- Kann passwortgeschützte PDFs verarbeiten (sofern die Passwörter angegeben werden).
- Lässt sich in automatisierte Workflows einbinden, mit Funktionen wie Queuing und Skalierung für rechenintensive Jobs.
- Verarbeitet Dateien, ohne die Speicher- oder Ausführungszeitlimits Ihres Servers zu belasten.
Sie können dies bei unserem Robot 🤖 /document/merge näher erkunden.
Fazit
FPDI und FPDF bilden eine leistungsstarke Kombination, um Dokumente in PHP direkt auf Ihrem Server zu einem einzigen Dokument zusammenzuführen, und benötigen für einfache Aufgaben nur wenige Codezeilen. Für schnelle Umsetzungen und moderate Workloads sind sie eine ausgezeichnete Wahl. Wenn Sie es jedoch mit umfangreicher PDF-Bearbeitung, hohen Durchsatzanforderungen oder komplexen Workflows mit potenziell großen Dateien zu tun haben, sollten Sie einen cloudbasierten Dienst wie Transloadit für die schwere Arbeit in Betracht ziehen, damit Ihre Anwendung performant und skalierbar bleibt.
