PDFs zusammenführen mit iTextSharp

Wenn Sie ein Abonnement des Magazins 'DATENBANKENTWICKLER' besitzen, können Sie sich anmelden und den kompletten Artikel lesen.
Anderenfalls können Sie das Abonnement hier im Shop erwerben.

PDFs zusammenführen mit iTextSharp

Im Rahmen unserer Lösung zum Erstellen von DHL-Versandetiketten benötigen wir eine Lösung, mit der wir mehrere PDF-Dokumente zu einem zusammenführen können, um dieses dann in einem Rutsch auszudrucken. Mit Bordmitteln kommen wir nicht weiter, aber es gibt ja eine Reihe von Bibliotheken, die man sich etwa als NuGet-Paket ins Projekt holen kann. In diesem Fall nutzen wir die Bibliothek iTextSharp. Diese kann noch einiges mehr, aber wir wollen erst einmal nur PDF-Dokumente zusammenführen.

iTextSharp

iTextSharp ist eine C#-Portierung des Projekts iText 5, für das Sie unter dem folgenden Link eine Reihe von Beispielen in der Programmiersprache Java finden: http://developers.itextpdf.com/examples-itext5. Mit iText 5 können Sie eine ganze Menge Aufgaben rund um die Erstellung und Bearbeitung von PDF-Dokumenten erledigen. Aktuell wollen wir jedoch nur zwei oder mehrere PDF-Dokumente zusammenführen.

Beispielanwendung

Um die Bibliothek iTextSharp in ein Projekt zu integrieren, nutzen Sie den NuGet-Manager. Ausgehend von einem geöffneten Projekt klicken Sie dann mit der rechten Maustaste auf das Projekt im Projektmappen-Explorer. Aus dem Kontextmenü wählen Sie dann den Eintrag NuGet-Pakete verwalten ... aus. Im nun erscheinenden NuGet-Paket-Manager wechseln Sie zum Bereich Durchsuchen und geben als Suchbegriff iTextSharp ein. Ganz oben in der Liste erscheint nun der Eintrag iTextSharp, den Sie auswählen. Klicken Sie dann auf Installieren, um das Paket zum Projekt hinzuzufügen (siehe Bild 1).

Installieren des NuGet-Pakets iTextSharp

Bild 1: Installieren des NuGet-Pakets iTextSharp

Unserem WPF-Beispielprojekt fügen wir nun auf der Seite MainWindow.xaml eine einfache Schaltfläche hinzu, mit der wir einen ersten Test starten wollen.

Wir gehen vereinfachend davon aus, dass wir einfach zwei Dokumente namens 1.pdf und 2.pdf zusammenführen wollen.

Dazu fügen wir diese zum Projekt hinzu und stellen in den Eigenschaften dieser beiden Elemente den Wert Immer kopieren für die Eigenschaft In Ausgabeverzeichnis kopieren ein. So können wir das Verzeichnis für diese beiden Dokumente gleich direkt über die Funktion AppDomain.CurrentDomain.BaseDirectory ermitteln (dies liefert das Verzeichnis, in dem sich auch die .exe-Datei der Lösung befindet).

Dokumente zusammenführen

Wir wollen nun eine Methode programmieren, welche diese beiden Dokumente zusammenführt und als neues PDF-Dokument abspeichert. Das geht mit der iTextSharp-Bibliothek wirklich sehr einfach. Für die Schaltfläche hinterlegen wir die folgende Methode, die zunächst drei Pfade in den Variablen document1, document2 und target hinterlegt – jeweils mit dem aktuelle Anwendungsverzeichnis und den Namen 1.pdf, 2.pdf und 12.pdf:

private void btnTestZweiDokumente_Click(object sender, RoutedEventArgs e) {
     string document1 = AppDomain.CurrentDomain.BaseDirectory + "1.pdf";
     string document2 = AppDomain.CurrentDomain.BaseDirectory + "2.pdf";
     string target = AppDomain.CurrentDomain.BaseDirectory + "12.pdf";

Dann erstellt die Methode ein neues Objekt des Typs Document und eines vom Typ FileStream. Letzteres wird auf Basis des Pfades zur Zieldatei als neue Datei angelegt:

     Document document = new Document();
     FileStream stream = new FileStream(target, FileMode.Create);

Das Objekt pdf mit dem Typ PdfCopy führt das Document- und das FileStream-Objekt zusammen. Ein Objekt des Typs PdfReader, das später die Ausgangsdokumente aufnimmt, wird mit dem Wert null initialisiert. Dann wird das Document-Objekt mit der open-Methode geöffnet:

     PdfCopy pdf = new PdfCopy(document, stream);
     PdfReader reader = null;
     document.Open();

Nun folgen die beiden Einlesevorgänge der zusammenzuführenden Dokumente. Dabei wird reader jeweils mit einem neuen PdfReader-Objekt mit dem Dokumentpfad als Konstruktor-Parameter initialisiert und für die Anwendung innerhalb des using-Konstrukts vorbereitet. Darin wird das Dokument aus der Objektvariablen reader zum pdfCopy-Objekt hinzugefügt:

     using (reader = new PdfReader(document1)) {
         pdf.AddDocument(reader);
     }

Das erledigen wir auch noch für das zweite Dokument, also 2.pdf:

     using (reader = new PdfReader(document2)) {
         pdf.AddDocument(reader);
     }

Schließlich schließt die Methode das Objekt document mit der Close-Methode:

     document.Close();
}

Das Ergebnis überzeugt: Beide Dokumente erscheinen im neuen Dokument 12.pdf.

Anwendung bauen

Wenn wir nun schon so eine einfache Möglichkeit haben, PDF-Dokumente zusammenzustellen, wollen wir auch gleich eine praktische Anwendung daraus bauen. Diese soll es ermöglichen, über einen Datei auswählen-Dialog verschiedene PDF-Dokumente auszuwählen und diese so einer Liste hinzuzufügen. Ein Mausklick soll die Dokumente dann unter einem ebenfalls per Dateidialog auszuwählenden Dateinamen zusammenführen und speichern.

Um dies zu realisieren, benötigen wir ein Listenfeld, dass die Dateien anzeigt, sowie eine Schaltfläche zum Hinzufügen der gewünschten Dateien. Außerdem brauchen wir noch eine Schaltfläche, die den Datei speichern-Dialog anzeigt und nach der Eingabe eines entsprechenden Dateinamens die Dateien in der Reihenfolge wie im Listenfeld zusammenzuführen. Interessant wäre es natürlich noch, die Dateien im Listenfeld nach oben oder unten verschieben zu können. Dies wollen wir jedoch hintenanstellen und uns zunächst um die grundlegenden Funktionen kümmern.

Für diese Lösung verlassen wir das Beispielprojekt und erstellen ein neues WPF-Projekt namens PDFMerger. Diesem fügen Sie nun zunächst wieder das NuGet-Paket iTextSharp hinzu. Dann legen wir die benötigten Steuer­elemente im Fenster MainWindow.xaml an. Der dazu verwendete Code sieht wie folgt aus. Der -Teil legt zwei allgemeine Eigenschaften für die enthaltenen Button-Elemente fest:

<Window x:Class="PDFMerger.MainWindow" ... Title="MainWindow" Height="350" Width="525">
     <Window.Resources>
         <Style TargetType="{x:Type Button}">
             <Setter Property="Margin" Value="5"></Setter>
             <Setter Property="Height" Value="25"></Setter>
         </Style>
     </Window.Resources>

Das Grid besteht aus zwei Zeilen, von denen die obere das ListView-Element und das untere ein horizontal orientiertes StackPanel enthält, welches wiederum die fünf Schaltflächen aufnimmt:

     <Grid>
         <Grid.RowDefinitions>
             <RowDefinition></RowDefinition>
             <RowDefinition Height="Auto"></RowDefinition>

Dies war die Leseprobe dieses Artikels.
Melden Sie sich an, um auf den vollständigen Artikel zuzugreifen.

Bitte geben Sie die Zeichenfolge in das nachfolgende Textfeld ein

Die mit einem * markierten Felder sind Pflichtfelder.

Neues aus unseren Magazinen
Listenfeld: Reihenfolge mehrerer Einträge...

Wir haben bereits in mehreren Beiträgen beschrieben, wie Sie die individuelle Reihenfolge von Elementen einer Tabelle über den Inhalt eines Feldes etwa namens »ReihenfolgeID« einstellen können –... [mehr]

Diagramme mit gefilterten Daten

In Ausgabe 2/2019 haben wir in zwei Artikeln die modernen Diagramme von Access vorgestellt. Im vorliegenen Beitrag zeigen wir Ihnen, wie Sie diese abhängig von den in einem Formular angezeigten... [mehr]

Benutzerverwaltung mit verschlüsselten...

Wenn Sie in einer Access-Anwendung Benutzer verwalten wollen, die sich per Benutzername und Kennwort an die Anwendung anmelden, sollten Sie sehr sensibel mit den in der Anwendung gespeicherten... [mehr]

HTML-Tabellen mit fester Kopfzeile

In den vorherigen Ausgaben von Access im Unternehmen und in der aktuellen Ausgabe arbeiten wir in einigen Beiträgen mit dem Webbrowser-Steuerelement und stellen Daten, die wir mit den Bordmitteln... [mehr]

Flexible HTML-Tabellen mit fester Kopfzeile

Im Beitrag »HTML-Tabellen mit fester Kopfzeile« haben wir gezeigt, wie Sie Daten aus einer bestimmten Abfrage in einem Webbrowser-Steuerelement so anzeigen, dass die Spaltenköpfe oben fixiert... [mehr]

Berechtigungen per HTML verwalten

Im Beitrag »Benutzerverwaltung mit verschlüsselten Kennwörtern« stellen wir eine Lösung vor, in der wir die Berechtigungen von Benutzergruppen an Datenbankobjekten definieren. Dort benötigen wir... [mehr]

Benutzer und Berechtigungen ermitteln

In den Beiträgen »Benutzerverwaltung mit verschlüsselten Kennwörtern« und »Berechtigungen per HTML verwalten« haben wir die Voraussetzungen für eine Benutzerverwaltung geschaffen. Im vorliegenden... [mehr]

Zugriffsrechte mit Datenmakros

Es gibt verschiedene Möglichkeiten, auf Basis des aktuell angemeldeten Benutzers sicherzustellen, dass dieser nur die für ihn vorgesehenen Aktionen mit Daten durchführen darf – beispielsweise durch... [mehr]

Kennwörter generieren

Für den einen oder anderen Zweck möchten Sie vielleicht Kennwörter generieren oder in einer Benutzeroberfläche die Möglichkeit zum Generieren von Kennwörtern anbieten. Wenn Sie etwa Benutzer zu... [mehr]

Neuer Datensatz von Frontend zu Backend

Für manche Themen gibt es keine kurze, prägnante Überschrift. In diesem Fall wollen wir zeigen, wie Sie einen neuen Datensatz anlegen, der in einer temporären Tabelle im Frontend gespeichert wird,... [mehr]