[C#, iTextSharp] Generieren / Erstellen von PDF 's

Drucken
( 7 Votes )
Hauptkategorie: Programmieren Kategorie: C#
Erstellt am 03.05.2012 Zuletzt aktualisiert am 06.06.2012 Geschrieben von Jonny132
In diesem Tutorial biete ich euch einen Einstieg in die PDF-Generierung mittels C# und iTextSharp. Die aktuelle Version der iTextSharp-Bibliothek könnt ihr euch unter http://sourceforge.net/projects/itextsharp/ herunterladen.

Diese müsst ihr nun nurnoch in euer Projekt referenzieren und folgende usings einfügen:
using iTextSharp.text;
using iTextSharp.text.pdf;

Initialisierung des Grundgerüsts für die erstellung von PDF's:
     float margin = Utilities.MillimetersToPoints(Convert.ToSingle(20));
     Document doc = new Document(iTextSharp.text.PageSize.A4, margin, margin, margin, margin);

     PdfWriter writer = PdfWriter.GetInstance(doc, new FileStream("C:\\Temp\\Test.pdf", FileMode.Create));
     writer.SetFullCompression();
     writer.CloseStream = true;

     doc.Open();
     doc.NewPage();
Mittels der Hilfsfunktion MillimetersToPoints rechnen wir uns das Margin (Abstand zwischen Seitenrand und Inhalt) aus, welches wir dem PDF-Dokument im Konstruktor zuweisen können. Die PageSize-Klasse bietet uns eine Auswahl an Darstellungsgrößen.
Die Document Klasse dient als 'Vaterelement', das heisst alle Elemente die wir Darstellen wollen (Text, Bilder, Listen, Tabellen), werden in dieses Document eingefügt.

Der PdfWriter gibt uns die Möglichkeit das Document physikalisch in eine PDF-Datei zu schreiben. Indem wir die Methode SetFullCompression aufrufen wird die Datei maximal komprimiert und somit Platzsparender. Alternativ könnte man auch das CompressionLevel des PdfWriter setzen. 0 wäre dabei garkeine Komprimierung.

Indem wir die Methoden Open und NewPage des Documents aufrufen, machen wir das Document zugänglich für weitere Elemente.

Hinzufügen von Text:
     doc.Add(new Chunk("Hallo, dies ist ein einfacher Text :)"));
Wie ihr seht ist es nicht besonders Schwer, einen einfachen Text im PDF darstellen zu lassen. Chunks sind die kleinste Texteinheit die es in der iTextSharp-Bibliothek. Gebräuchlich und mit mehr Funktionalität sind zB Phrase oder Paragraph.


Hinzufügen eines Bildes:
     doc.Add(Image.GetInstance("C:\\Temp\\tuts4youlogo.png"));
Auch das erscheint nicht schwer. Die GetInstance Methode der Image-Klasse gibt uns die Möglichkeit ein PDF-Image auf viele weisen zu erstellen. Beispielsweise aus einem Byte-Array, aus einem Stream oder wie hier einfach aus einer Pfadangabe.


Hinzufügen einer Liste:   
     List pdfList = new List(List.UNORDERED, 10f);
     pdfList.SetListSymbol("\u2022");
     pdfList.IndentationLeft = 10f;
     foreach (string item in new List<string>() {"ListItem1", "ListItem2", "ListItem3" })
     {
       ListItem lItem = new ListItem(item);
       pdfList.Add(lItem);
     }
     doc.Add(pdfList);
Bei den Listen wird es schon etwas kniffliger. Zuerst muss eine neue List-Klasse der iTextSharp-Bibliothek erstellt werden, welche als Parameter die Sortierung und die Zeichengröße entgegennimmt. Mittels SetListSymbol können wir festlegen welches Symbol für die Aufzählung bzw. Liste genommen wird. '\u2022' stellt einen einfachen Punkt dar. Das IndentationLeft-Property setzt den Einzug von Links.
Für jeden Eintrag in der Auzählung müssen wir ein neues ListItem erstellen welches wir wiederrum der List hinzufügen können.


Hinzufügen einer DataTable/Tabelle: 
     DataTable tableToAdd = GetFilledDataTable();
     PdfPTable pdfTable = new PdfPTable(tableToAdd.Columns.Count);
     pdfTable.WidthPercentage = 100;

     foreach (DataColumn col in tableToAdd.Columns)
     {
       PdfPCell pdfcell = new PdfPCell();
       pdfcell.BackgroundColor =  BaseColor.LIGHT_GRAY;
       pdfcell.Phrase = new Phrase(col.ColumnName, new Font(iTextSharp.text.Font.FontFamily.TIMES_ROMAN, 12, iTextSharp.text.Font.BOLD));
       pdfTable.AddCell(pdfcell);
     }

     foreach (DataRow row in tableToAdd.Rows)
     {
       foreach (DataColumn col in tableToAdd.Columns)
       {
         PdfPCell pdfcell = new PdfPCell();
         pdfcell.Phrase = new Phrase(row[col.ColumnName].ToString());
         pdfTable.AddCell(pdfcell);
       }
     }

     doc.Add(pdfTable);
In diesem Beispiel will ich eine einfache DataTable, die ich mittels einer Hilfsfunktion befülle, im PDF darstellen lassen. Dazu muss man eine Instanz der Klasse PdfPTable erstellen. Die Eigenschaft WidthPercentage gibt an wie Breit die Tabelle in Prozent sein soll.
Für die Spaltenüberschriften iterieren wir über die vorhandenen Spalten und erstellen für jede eine neue PdfPCell welche wir mit einem Hellgrauen Hintergrund formatieren. Desweiteren geben wir der Phrase der Zelle ein neues Font mit der Definition Bold (Fett) mit.
Somit haben wir den Tabellenkopf.

Danach wird nurnoch über jede Reihe + Zelle iteriert und jeweils eine PdfPCell erstellt welche der Table hinzugefügt wird.

Hilfsfunktion zur befüllung einer Datatable:
    private DataTable GetFilledDataTable()
    {
      DataTable result = new DataTable();
      result.Columns.Add("ID", typeof(int));
      result.Columns.Add("Spalte1");
      result.Columns.Add("Spalte2");

      for (int i = 0; i < 20; i++)
      {
        DataRow row = result.NewRow();
        row["ID"] = i;
        row["Spalte1"] = "Zelle 2 in Reihe " + i.ToString();
        row["Spalte2"] = "Zelle 3 in Reihe " + i.ToString();
        result.Rows.Add(row);
      }
      return result;
    }
Diese Funktion bedarf keiner Speziellen erklärung.

Abschliessen der PDF-Erstellung:
     if (doc != null)
     {
       doc.Close();
     }
     doc = null;
     Process.Start("C:\\Temp\\Test.pdf");
Zu Schluss müssen wir nurnoch das Close des Documents aufrufen um die Ressourcen wieder freizugeben. Das Close schliesst automatisch auch den PdfWriter.
Um das Ergebnis zu betrachten rufen wir die Datei noch mittels Process.Start auf.

  • whitewoolve

    schrieb am 2013-04-15 12:39:09

    Das Problem in der Verwendung von iText ist doch ein lizenzrechtliches Problem oder sehe ich das falsch? Da es laut dem Worttext so heißt, daß man das eigene Artefakt (Exe/DLL) mit AGPL Lizenz weitergeben muss, sofern man die kostenfreie Variante nutzt oder irre ich mich?

    Auf Kommentar antworten

    • Jonny132

      schrieb am 2013-04-15 14:43:26

      Hallo whitewoolve,

      ja leider ist das seit der Version 5.14 glaube ich so...

      Auf Kommentar antworten

  • Julius

    schrieb am 2012-08-15 08:03:57

    Hey,
    ein schönes Tutorial was mir allerdings bisher nicht richtig helfen kann.
    Hast du eine Antwort darauf, warum Methoden wie "SetFullCompression" und "CloseStream" bei mir nicht enthalten sind? Ich arbeite mit der Version 5.3.0 und kann leider einige deiner Schritte gar nicht nachvollziehen.

    Leider kann ich nun das erstellte PDF gar nicht erst öffnen (vermute wegen der fehlenden "SetFullCompression"-Methode?)

    Viele Grüße
    Julius

    Auf Kommentar antworten

    • Jonny132

      schrieb am 2012-08-16 09:17:50

      Hallo Julius,
      ich habe mir gerade auch die 5.3 heruntergeladen von http://sourceforge.net/projects/itextsharp/ und ausprobiert.

      Bei mir funktioniert alles, wie im Tutorial beschrieben.

      Hast du auch die richtige (itextsharp-dll-core-5.3.0) DLL referenziert und die usings eingefügt?

      Falls das Problem weiterhin besteht wäre es vll besser im Forum (http://tuts4you.de/forum/c) darüber zu schreiben ;)

      sg

      Auf Kommentar antworten

  • Christian

    schrieb am 2012-05-19 09:51:16

    Hi

    Schönes Tutorial aber muß da nicht noch was mit using eingetragen werden?

    Gruß Christiam

    Auf Kommentar antworten

    • Jonny132

      schrieb am 2012-05-21 09:09:46

      Hallo Christian,

      vielen Dank für den Hinweis. Tutorial wurde angepasst ;)

      sg,
      Jonny132

      Auf Kommentar antworten

Veröffentlichen Sie ihre Kommentare ...