Diese Seite kann automatisch übersetzten Text enthalten.

.NET PDF-Generator

Mit Hilfe von Docotic.Pdf können Sie PDF-Dokumente erzeugen, indem Sie sie aus strukturellen Elementen wie Seiten, Containern, Textabschnitten, Bildern, Links, Kopf- und Fußzeilen, Tabellen, Listen und mehr zusammensetzen. Diese Elemente sind über die hochrangige Layout API verfügbar, die vom kostenlosen Layout-Add-on für Docotic.Pdf bereitgestellt wird. Die API unterstützt außerdem wiederverwendbare benutzerdefinierte Komponenten.

Illustration, wie Docotic.Pdf PDFs erzeugt: Sie ordnen Elemente wie Bilder, Tabellen und Text an, und die Bibliothek erzeugt daraus ein PDF

Die Layout API ermöglicht es Ihnen, Dokumente vollständig in C#- oder VB.NET-Code mit einem flüssigen Ansatz zu definieren. Auf Basis dieser Beschreibung kann der vom Add-on bereitgestellte PDF-Generator Dokumente mit beliebig komplexen Layouts erzeugen, von einfachen Seiten bis hin zu hochstrukturierten PDF-Berichten.

Grundlagen der PDF-Erzeugung

Um PDF-Dokumente mit der Layout API zu erzeugen, benötigen Sie das kostenlose Layout-Add-on. Für die Nutzung der Kernbibliothek und der Add-ons ist außerdem ein Lizenzschlüssel erforderlich. Sie können entweder einen kostenlosen Testschlüssel oder einen gekauften Schlüssel verwenden.

Add-on installieren

Der empfohlene Weg ist, das Add-on über NuGet zu installieren.

Install-Package BitMiracle.Docotic.Pdf.Layout

Der Paketmanager kümmert sich automatisch um Abhängigkeiten.

Wenn Sie das Add-on lieber manuell installieren möchten, laden Sie zuerst das ZIP-Archiv mit den Docotic.Pdf-Binaries herunter. Entpacken Sie das Archiv und fügen Sie Verweise auf die folgenden DLLs hinzu:

  • BitMiracle.Docotic.Pdf.dll
  • BitMiracle.Docotic.Pdf.Layout.dll aus dem Unterordner Layout add-on.

Einen Lizenzschlüssel erhalten

Um die Bibliothek auszuprobieren, fordern Sie einen kostenlosen, zeitlich begrenzten Lizenzschlüssel an, indem Sie das Formular auf der Docotic.Pdf-Download-Seite ausfüllen. Wenn Sie bereits eine Lizenz erworben haben, verwenden Sie den Ihnen nach dem Kauf bereitgestellten Code.

Das Layout-Add-on ist kostenlos und erfordert keine zusätzliche Lizenz. Sie können die Layout API mit der Docotic.Pdf-Lizenz verwenden, die Sie bereits besitzen.

„Hello, world!“ mit der Layout API

Hier ist Beispielcode, der die API verwendet, um ein PDF mit der klassischen Phrase "Hello, world!" zu erzeugen:

BitMiracle.Docotic.LicenseManager.AddLicenseData("PUT-LICENSE-HERE");

PdfDocumentBuilder.Create().Generate("hello.pdf", doc => doc.Pages(pages =>
{
    pages.Content().Text("Hello, world!");
}));

Dieses Codebeispiel erzeugt ein einseitiges PDF mit dem Text in der oberen linken Ecke.

Das Codebeispiel verstehen

Das Beispiel beginnt mit dem Hinzufügen eines Lizenzschlüssels. Ohne Lizenz erzeugt die Docotic.Pdf-Bibliothek nichts. Der PDF-erzeugende Code beginnt in der nächsten Zeile.

Der Code erstellt eine Instanz des Dokumenterstellers durch Aufruf der statischen Methode PdfDocumentBuilder.Create(). Der Aufruf der Methode Generate startet den PDF-Erzeugungsprozess. Diese Methode akzeptiert zwei Parameter: den Namen der zu erzeugenden Datei und einen Delegate vom Typ Action<Document>. Das Add-on erzeugt hello.pdf als Ergebnis des Generate-Aufrufs.

Damit der Dokumentersteller weiß, welches Layout das PDF haben soll, ruft er den Delegate mit einer Document-Instanz auf. Der Code des Delegates setzt den Dokumentinhalt zusammen. In diesem Beispiel verwendet der Delegate die Methode Pages, um dem Ersteller einen weiteren Delegate zu übergeben, der das Layout der Dokumentseiten definiert.

Der Ersteller ruft den der Methode Pages übergebenen Delegate mit einer PageLayout-Instanz auf. Diese Instanz repräsentiert eine oder mehrere Seiten im Dokument. Die genaue Anzahl der Seiten hängt vom hinzugefügten Inhalt ab.

Der Seiten-Delegate ruft die Methode Content auf, um auf den Layout-Container für den primären Inhalt der Seite(n) zuzugreifen. Ein verketteter Aufruf der Methode Text des Containers fügt den Beispiel-Textabschnitt zur Seite hinzu. Siehe den Leitfaden zu Layout-Containern für eine detaillierte Erklärung ihrer Funktionsweise.

Der Dokumentersteller verteilt Inhalte automatisch über Seiten und erstellt genau so viele Seiten, wie erforderlich sind, um alle zum primären Inhalts-Layout-Container hinzugefügten Daten aufzunehmen. In diesem Beispiel reicht eine einzelne Seite aus, daher enthält die Ausgabe genau eine Seite.

Häufige Aufgaben jenseits des Grundbeispiels

Der Beispielcode erstellt zuerst eine PdfDocumentBuilder-Instanz und ruft dann die Methode Generate auf, um ein PDF zu erzeugen. Sie können den Ersteller konfigurieren, bevor er mit der PDF-Erzeugung beginnt.

Beispielsweise können Sie ein verschlüsseltes PDF erzeugen, indem Sie dem Ersteller einen Verschlüsselungshandler übergeben. Sie können außerdem Metadaten angeben, die der Ersteller in das erzeugte Dokument aufnehmen soll. Weitere Details dazu, wie Sie den Ersteller anpassen, finden Sie im separaten Artikel.

Der Beispielcode verwendet nur den Layout-Container des primären Inhaltsbereichs, aber es stehen auch andere Inhaltsbereiche zur Verfügung. Hier ist die vollständige Liste der PageLayout-Methoden für den Zugriff auf Inhaltsbereiche:

  • Background() - gibt die Hintergrundebene zurück, die von anderem Inhalt überdeckt wird.
  • Header() - gibt die gemeinsame Kopfzeile für alle Seiten zurück.
  • Content() - gibt den Hauptinhaltsbereich der Seite zurück.
  • Footer() - gibt die gemeinsame Fußzeile für alle Seiten zurück.
  • Foreground() - gibt die Vordergrundebene zurück, die über anderem Inhalt erscheint.

Nur der Inhalt im Hauptinhaltsbereich beeinflusst die Anzahl der Seiten im erzeugten PDF. Der Dokumentersteller wiederholt alle Bereiche außer dem von Content() bereitgestellten auf jeder Seite. Weitere Informationen zu Inhaltsbereichen finden Sie im Artikel über Seitenlayout.

Viele Dokumente verwenden auf verschiedenen Seiten unterschiedliche Layouts. Beispielsweise kann die erste Seite ein Titelseiten-Design haben, während nachfolgende Seiten ein einfacheres Layout verwenden. Manche Dokumente enthalten spezielle Seiten für Tabellen oder verwenden je nach Abschnitt unterschiedliche Hintergründe. Um solche Dokumente mit Docotic.Pdf und dem Layout-Add-on zu erzeugen, rufen Sie die Methode Document.Pages mehrmals auf. Ein funktionierendes Beispiel finden Sie in unserem Beispiel-Repository.

Den Code organisieren

Für kurzen Code, wie im Beispiel, ist es in Ordnung, Aufrufe zu verketten und verschachtelte Lambdas zu verwenden. Wenn Sie etwas Größeres erstellen, kann es praktischer sein, den Code in separate Methoden aufzuteilen. Das macht den Code leichter lesbar und wartbar.

So sieht das Hello, world!-Beispiel aus, wenn sein Code in Methoden aufgeteilt ist.

public void GeneratePdf()
{
    BitMiracle.Docotic.LicenseManager.AddLicenseData("PUT-LICENSE-HERE");

    PdfDocumentBuilder.Create().Generate("hello.pdf", BuildDocument);
}

private void BuildDocument(Document doc)
{
    doc.Pages(BuildPages);
}

private void BuildPages(PageLayout pages)
{
    pages.Content().Text("Hello, world!");
}

Warum PDFs mit der Docotic.Pdf Layout API erzeugen

Die Layout API ist eine entwicklerfreundliche, moderne Möglichkeit, PDFs aus zusammensetzbaren Bausteinen zu erzeugen, ohne die Interna des PDF-Formats verstehen zu müssen. Sie erzeugt PDFs mit hoher Leistung und deterministischem, vorhersagbarem Verhalten. Sie können die API in Szenarien zur Dokumenterzeugung mit hohem Durchsatz einsetzen.

Die API ist verfügbar, wenn Sie Docotic.Pdf zusammen mit dem kostenlosen Layout-Add-on verwenden. Sowohl Docotic.Pdf als auch das Layout-Add-on sind zu 100 % verwaltete DLLs ohne Unsafe-Code-Blöcke. Die Layout API wird ohne externe Drittanbieterabhängigkeiten wie einen Browser oder Skia-Binaries implementiert, was zu einer leichten, ressourcenschonenden Lösung führt, die sich einfach bereitstellen und warten lässt.

API-Überblick

Die Layout API ist eine flüssige, angenehm zu verwendende API. Sie beschreiben das Layout Ihres Dokuments vollständig im Code mit flexiblen Layout-Elementen, und der Generator fließt durch Ihren Inhalt, paginiert ihn automatisch und rendert das Ergebnis als PDF.

Das Layout-Add-on verwendet ein deklaratives, flussbasiertes Layoutsystem. Zu seinen Layout-Elementen gehören Listen, Spalten, Zeilen, Tabellen, Bilder, Textabschnitte, Kopf- und Fußzeilen, Container und mehr. Anstatt Elemente manuell an exakten Koordinaten zu platzieren, beschreiben Sie, wie sich die Elemente verhalten sollen. Der Dokumentersteller berechnet dann das endgültige Layout und erstellt das PDF.

Das flussbasierte Layoutsystem stellt sicher, dass sich das Layout an Seitengröße und Inhalt anpasst. Dank dieses Systems eignet sich das Add-on besonders für komplexe, strukturierte und regelbasierte Layouts. Sie können verschiedene Containertypen verschachteln und anspruchsvolle Strukturen aufbauen, ohne die Lesbarkeit zu beeinträchtigen.

Bei der Arbeit mit der Layout API können Sie die meisten Aufrufe miteinander verketten. Dadurch entsteht kompakterer und ausdrucksstärkerer Code als bei traditionellen APIs. Die Reihenfolge der Aufrufe in einer Kette ist wichtig. Alles ist stark typisiert, was Compile-Time-Sicherheit bietet und Refactoring erleichtert. Sie können den Code, der die Layout API verwendet, auch unit-testen.

Um Ihre Layout-Implementierung noch knapper zu machen, können Sie die API mit eigenen Methoden erweitern und darauf ein sauberes, ausdrucksstarkes DSL aufbauen.

Weitere Informationen zu Positionierung und DSL-Erstellung finden Sie im Artikel, der erklärt, wie Sie Größe, Position, Ausrichtung und Renderverhalten von Containern steuern.

.NET-Versionen und Plattformunterstützung

Sie können die Layout API in Projekten verwenden, die auf .NET Standard 2.1 und neuere Frameworks abzielen. Anders ausgedrückt ist das Layout-Add-on mit .NET 5 bis .NET 10 kompatibel. Zusätzlich wird .NET Core 3.0+ unterstützt.

Sie können PDFs mit der Layout API in ASP.NET Core, MAUI-Apps, Unity, Xamarin und Konsolenanwendungen erzeugen. Docotic.Pdf mit dem Layout-Add-on kann PDFs unter Windows, macOS und Linux erzeugen.

Cloud-Plattformen und Docker-Images

Docotic.Pdf mit dem Layout-Add-on kann in Azure- und AWS-Cloudumgebungen ausgeführt werden, einschließlich serverloser Setups. Die Bibliothek und das Add-on unterstützen dynamische Hardwareänderungen, automatisches Skalieren und andere cloud-native Laufzeitfunktionen vollständig.

In den meisten Cloud-Szenarien ist eine ungebundene Lizenz erforderlich. Die Lizenz-FAQ erklärt, wie Sie die geeignete Lizenz für Cloud-Anwendungen auswählen.

Die Layout API funktioniert in Docker-Containern ohne Weiteres. Sie benötigen keine spezielle Konfiguration, um PDFs zu erzeugen, wenn Sie die Bibliothek und das Layout-Add-on in einem Container ausführen.

Text zu PDF-Dateien hinzufügen

Text ist ein grundlegender Bestandteil jedes PDF-Dokuments. Sie können die Text-Methoden der Klasse LayoutContainer verwenden, um Text zu einem Inhaltsbereich hinzuzufügen.

Illustration von Dokumentseiten, umgeben von Beispielen für Textstile wie Titel, Beschriftung, Standard, Hyperlink, Fett und Fußnote

Textabschnitte

Im Hello, world-Beispiel habe ich die Überladung LayoutContainer.Text(string) verwendet, um Text zur primären Seiteninhalts hinzuzufügen. Sehen wir uns jetzt eine andere Überladung der Methode Text an.

public static void GenerateTextPdf()
{
    PdfDocumentBuilder.Create().Generate("text-spans.pdf", doc => doc.Pages(pages =>
    {
        pages.Content().Text(AddTextSpans);
    }));
}

private static void AddTextSpans(TextContainer text)
{
    text.Line("About VB.NET")
        .Style(t => t.Strong);

    text.Span("VB.NET is a multi-paradigm, object-oriented language ");
    text.Span("that runs on .NET, Mono, and the ");
    text.Hyperlink(
        ".NET Framework",
        new Uri("https://dotnet.microsoft.com/download/dotnet-framework"));
    text.Line(".");

    text.Span("Released by Microsoft in 2002, ");
    text.Line("it continues the lineage of the original Visual Basic language.");
}

Dieser Code verwendet die Methoden Span und Line der Klasse TextContainer, um Text zur aktuellen Zeile hinzuzufügen. Die Methode Line schließt zusätzlich die aktuelle Zeile ab. Der Beispielcode verwendet außerdem die Methode Hyperlink, um einen Link zu einer externen Ressource an einen bestimmten Textabschnitt anzuhängen.

Beachten Sie, wie der Beispielcode mit der Methode Style die erste Zeile fett formatiert. Betrachten wir das Konzept der Textstile genauer.

Textstile

Textstile ermöglichen es Ihnen, das Erscheinungsbild von Text anzupassen. Die Klasse TextStyle stellt Methoden bereit, um Schriftgröße, Zeichenabstand, Farben und andere Texteigenschaften zu ändern. TextStyle-Objekte sind unveränderlich, daher erzeugt jeder Methodenaufruf eine neue Stilinstanz. Sie können Textstile auf verschiedenen Layout-Ebenen anwenden.

PdfDocumentBuilder.Create().Generate("text-styles.pdf", doc =>
{
    doc.Pages(pages =>
    {
        pages.TextStyle(TextStyle.Parent.FontSize(30));

        pages.Content()
            .TextStyle(TextStyle.Parent.FontColor(new PdfRgbColor(0, 0, 255)))
            .Text(text =>
            {
                text.Span("Hello,");

                text.Span("World!")
                    .Style(TextStyle.Parent.Underline());
            });
    });
});

Die Eigenschaft TextStyle.Parent gibt einen speziellen Stil zurück, bei dem alle Texteigenschaften undefiniert sind. Im obigen Beispiel zeichnet der Code „Hello, World!“ in Blau, wobei das zweite Wort unterstrichen ist und eine Schriftgröße von 30 Punkt verwendet wird.

Das geschieht, weil der Code:

  • die Schriftgröße auf Seitenebene auf 30 Punkt setzt,
  • dann die Textfarbe für den primären Inhaltsbereich auf Blau setzt,
  • dann auf den letzten Textabschnitt den Unterstreichungsstil anwendet.

Jeder nachfolgende Stil erbt die vorherigen über die Eigenschaft TextStyle.Parent.

Mit den Methoden der Klasse TextStyle können Sie unter anderem die Textrichtung auf rechts nach links ändern. Sehen Sie sich ein weiteres Beispiel für die Verwendung von Vererbung von Textstilen in unserem Beispiel-Repository an.

Typografie

Die Klasse TextStyle unterstützt die Anpassung aller Texteigenschaften außer der zugehörigen Schriftart. Um die Standardschriftart zu ändern, verwenden Sie die Methoden Document.TextStyleWithFont, um einen Textstil auf Basis einer bestimmten Schriftart zu erstellen. Sie können eine im Betriebssystem installierte Schriftart verwenden oder eine aus einer Datei oder einem Stream laden.

Nachdem Sie einen schriftbasierten Stil erstellt haben, können Sie zusätzliche optionale Eigenschaften anwenden und den resultierenden Stil anschließend auf einen Textabschnitt verwenden. Dieses C#-Beispiel zeigt, wie Sie eine Systemschriftart verwenden.

PdfDocumentBuilder.Create().Generate("text-style-with-font.pdf", doc =>
{
    var font = SystemFont.Family("Calibri");
    var style = doc.TextStyleWithFont(font).FontSize(30);

    doc.Pages(pages =>
    {
        pages.Content().Text(text =>
        {
            text.Span("Hello,");

            text.Span("World!")
                .Style(style);
        });
    });
});

Die Methode TextStyleWithFont enthält einen optionalen Parameter, der angibt, wie die Schriftart im erzeugten Dokument eingebettet werden soll. Standardmäßig gilt in der Bibliothek:

  • bei TrueType-/OpenType-Schriften werden nur die verwendeten Glyphen eingebettet,
  • bei Type1- und CFF-Schriften werden alle Glyphen eingebettet,
  • bei integrierten PDF-Schriften (Base14-Schriften) werden keine Glyphen eingebettet.

Aufgrund dieser Standardwerte können Dokumente, die TrueType- und OpenType-Schriften verwenden, auch bei großen Schriftarten klein bleiben. Sie können außerdem einen benutzerdefinierten Schriftlader, Ersatzschriften und einen Handler für fehlende Glyphen angeben. Siehe den Beispielcode in unserem Beispiele-Repository für Details zum Verwalten von Schriftarten in PDF-Dokumenten.

Die Layout API stellt eine Sammlung vordefinierter Stile bereit, auf die Sie über die Klasse Typography zugreifen und die Sie ändern können.

PdfDocumentBuilder.Create().Generate("typography.pdf", doc =>
{
    doc.Typography(t =>
    {
        var fontsPath = Environment.GetFolderPath(Environment.SpecialFolder.Fonts);
        var arialFont = new FileInfo(Path.Combine(fontsPath, "arial.ttf"));

        t.Document = doc.TextStyleWithFont(arialFont);
        t.Header = t.Parent.FontSize(20).FontColor(new PdfGrayColor(20));
        t.Footer = t.Footnote;
    });

    doc.Pages(pages =>
    {
        pages.Header().AlignCenter().Text("Header");

        pages.Content().Text(t =>
        {
            t.Line("Title").Style(t => t.Title);
            t.Line("Heading 1").Style(t => t.Heading1);
            t.Line("Regular");
        });

        pages.Footer()
            .Height(20)
            .AlignCenter()
            .Text(t => t.CurrentPageNumber());
    });
});

Ich empfehle, die vordefinierten Stile zu überschreiben, indem Sie die Typografie für das gesamte Dokument konfigurieren, obwohl dies nicht erforderlich ist und Sie Textstile weiterhin auf Textabschnittsebene anwenden können.

Mit der Klasse Typography müssen Sie Textstil-Referenzen nicht in Variablen speichern. Stattdessen registrieren Sie die benötigten Stile mit den Methoden Document.Typography und greifen später über die Eigenschaften des Typography-Objekts darauf zu. Im Typography-Beispiel sehen Sie, wie Sie beim Erzeugen von PDF-Dokumenten vordefinierte und benutzerdefinierte Textstile verwenden.

Viele reale PDF-Dokumente, etwa Berichte oder Rechnungen, enthalten Kopf- und Fußzeilen. Dieser Abschnitt zeigt, wie Sie beides zu einem PDF hinzufügen.

public static void GeneratePdfWithHeaderAndFooter()
{
    PdfDocumentBuilder.Create()
        .Generate("header-footer.pdf", doc => doc.Pages(pages =>
    {
        pages.Size(PdfPaperSize.A6).Margin(10);

        BuildPagesHeader(pages.Header());
        BuildPagesFooter(pages.Footer());

        pages.Content().Text("Hello, world!");
    }));
}

public static void BuildPagesHeader(LayoutContainer header)
{
    header.TextStyle(TextStyle.Parent.FontSize(8))
        .AlignRight()
        .Text(t =>
        {
            t.Line($"Created by: {Environment.UserName}");
            t.Line($"Date: {DateTime.Now}");
        });
}

public static void BuildPagesFooter(LayoutContainer footer)
{
    footer.AlignRight().Text(text =>
    {
        text.Style(t => t.Parent.FontColor(new PdfRgbColor(255, 0, 0)));

        text.CurrentPageNumber();
        text.Span(" / ");
        text.PageCount();
    });
}

Die Methode BuildPagesHeader setzt eine kleinere Schriftgröße für den Kopfzeilentext. Sie verwendet zwei Zeilen für den Kopfzeileninhalt: eine mit dem Namen des aktuellen Benutzers und eine mit dem aktuellen Datum. Der Text ist rechtsbündig.

Beachten Sie, dass der Code für die Kopfzeile keine explizite Größe angibt. Sie nimmt die volle Seitenbreite abzüglich der linken und rechten Ränder ein, und ihre Höhe hängt von der Höhe der Textzeilen ab.

Die Methode BuildPagesFooter zeigt, wie Sie die aktuelle Seitenzahl in der Fußzeile des PDFs platzieren. Die Bibliothek berechnet die aktuelle Seitenzahl und die Gesamtseitenzahl automatisch. Sie können auf diese Werte mit den Methoden CurrentPageNumber und PageCount eines Objekts vom Typ TextContainer zugreifen.

Die Layout API bietet außerdem eine Möglichkeit, Seitenzahlen zu formatieren. Beispielsweise können Sie hexadezimale Seitenzahlen so ausgeben:

text.CurrentPageNumber().Format(p => "0x" + p?.ToString("x2"));

Unser Beispiel-Repository enthält ein weiteres Beispiel zum Hinzufügen einer Kopf- und Fußzeile zu einem PDF. Dieses Beispiel formatiert Seitenzahlen als römische Zahlen.

Bilder einfügen

Wie das Sprichwort sagt, kann ein einziges Bild viele Worte ersetzen. In Angeboten oder Quittungen fügen Sie oft das Logo Ihres Unternehmens oder ein anderes wichtiges Bild ein. Für dieses Beispiel verwende ich ein einfaches, ansprechend aussehendes Bild.

Um ein Bild zu verwenden, müssen Sie es zuerst dem Dokument hinzufügen. Die Bibliothek kann Bilder aus einer Datei oder einem Stream laden. Unterstützt werden nur Rasterformate: PNG, JPEG, JPEG 2000, BMP, GIF und TIFF.

Sobald Sie ein Image-Objekt haben, können Sie es als Inhalt von einem oder mehreren Layout-Containern festlegen, indem Sie die Image-Methode des Containers aufrufen. Sie können das Bild skalieren, drehen, mit Abständen versehen und anordnen, genau wie jeden anderen Inhalt.

PdfDocumentBuilder.Create().Generate("image-with-text.pdf", doc =>
{
    var imageFile = new FileInfo("red-flowers-at-butterfly-world.jpg");
    var image = doc.Image(imageFile);

    doc.Pages(pages =>
    {
        pages.Size(PdfPaperSize.A6);
        pages.Content().Column(c =>
        {
            c.Spacing(20);

            c.Item()
                .AlignCenter()
                .Text("Hello, world!")
                .FontSize(20);

            c.Item()
                .AlignCenter()
                .MaxWidth(200)
                .Image(image);
        });
    });
});

Der Beispielcode verwendet sowohl Text als auch ein Bild im primären Inhaltsbereich. Ein Layout-Container kann jedoch nur Text oder nur ein Bild enthalten. Um beides im primären Inhaltsbereich der Seite zu verwenden, benötigen Sie einen zusammengesetzten Container.

Ich verwende einen Column-Container, um den Text und das Bild vertikal nacheinander anzuordnen. Die Methode Item des Spalten-Containers stellt einen Untercontainer bereit. Ein Aufruf von Item erstellt einen Container für den Text, ein weiterer einen Container für das Bild. Der zusammengesetzte Container mit all seinen Untercontainern wird zum Hauptinhalt.

Um den Beispielcode auszuführen, laden Sie das Blumenbild aus unserem Beispiel-Repository herunter und legen Sie es in das Arbeitsverzeichnis Ihrer App.

Online-Bilder

Wenn Sie nur eine Bild-URL statt einer Datei haben, laden Sie das Bild in einen Speicherstream herunter und erstellen Sie daraus ein Image. Das folgende Beispiel zeigt, wie Sie Online-Bilder mit der Layout API verwenden.

public static async Task AddImageWithTextFromUrl()
{
    using var http = new HttpClient();
    using var stream = await http.GetStreamAsync("url/to/image");

    var memoryStream = new MemoryStream();
    await stream.CopyToAsync(memoryStream);
    memoryStream.Position = 0;

    PdfDocumentBuilder.Create().Generate("online-image-with-text.pdf", doc =>
    {
        var image = doc.Image(memoryStream);

        doc.Pages(pages =>
        {
            pages.Size(PdfPaperSize.A6);
            pages.Content().Column(c =>
            {
                c.Spacing(20);

                c.Item()
                    .AlignCenter()
                    .Text("Hello, world!")
                    .FontSize(20);

                c.Item()
                    .AlignCenter()
                    .MaxWidth(200)
                    .Image(image);
            });
        });
    });
}

Da die Methode asynchrone Arbeit ausführt (ein Bild von einer URL herunterladen), ist sie als async Task statt als void deklariert. Aufrufer müssen sie mit await aufrufen, damit die PDF-Erzeugung korrekt abgeschlossen wird. In Ihrem eigenen Code kann eine ähnliche Methode auch einen Wert zurückgeben; in diesem Fall wäre sie als async Task<TResult> deklariert.

Listen erstellen

Was ist eine Liste? Man kann sie sich als Gruppe nummerierter Elemente vorstellen, die untereinander geschrieben werden. Die Layout API stellt keinen speziellen Containertyp für Listen bereit, aber es ist einfach, eine solche mit anderen zusammengesetzten Containern zu implementieren.

var dayNames = DateTimeFormatInfo.InvariantInfo.DayNames;
var dayNamesSpain = DateTimeFormatInfo.GetInstance(new CultureInfo("es-ES")).DayNames;

PdfDocumentBuilder.Create().Generate("list.pdf", doc => doc.Pages(pages =>
{
    pages.Size(PdfPaperSize.A6);
    pages.Content().Column(column =>
    {
        for (int i = 0; i < dayNames.Length; i++)
        {
            column.Item().Row(row =>
            {
                row.Spacing(5);
                row.AutoItem().Text($"{i + 1}.");
                row.RelativeItem().Text(t =>
                {
                    t.Line(dayNames[i]);
                    t.Line($"In Spain they call it {dayNamesSpain[i]}");
                });
            });
        }
    });
}));

Der Beispielcode erstellt die Liste als Spalte von Zeilen. Jede Zeile enthält zwei Elemente: das erste (links) enthält die Nummer des Elements, und das zweite (rechts) den Elementtext. Der Code legt den Abstand zwischen den Elementen in jeder Zeile explizit fest.

Um Elemente anzuordnen, muss der Row-Container entweder die Größe jedes Elements explizit kennen oder sie berechnen. In diesem Beispiel werden die Methoden AutoItem und RelativeItem verwendet. Dadurch berechnet der Zeilen-Container die für das erste Element benötigte Breite und verwendet die verbleibende verfügbare Breite für das zweite Element.

Mit diesem Ansatz und durch Anpassung des Erscheinungsbilds der Zeilen nach Bedarf können Sie eine Liste erstellen, die am besten zum Layout und Stil Ihres Dokuments passt.

Tabellen erstellen

Viele PDF-Dokumente enthalten Tabellen, was nicht überrascht, da Tabellen die Klarheit und Organisation von Daten verbessern. Dieser Abschnitt zeigt, wie Sie mit der Layout API eine Tabelle in einem PDF erstellen.

public static void AddTable()
{
    PdfDocumentBuilder.Create().Generate("table.pdf", doc => doc.Pages(pages =>
    {
        pages.Size(PdfPaperSize.A6);

        var color = new PdfGrayColor(75);
        pages.Content().Padding(20).Table(t =>
        {
            t.Columns(c =>
            {
                c.RelativeColumn(4);
                c.RelativeColumn(1);
                c.RelativeColumn(4);
            });

            t.Header(h =>
            {
                h.Cell().Background(color).Text("Month");
                h.Cell().Background(color).Text("Days");
                h.Cell().Background(color).Text("First Day");
            });

            var year = DateTime.Now.Year;
            for (int yearDiff = 0; yearDiff < 4; yearDiff++)
            {
                for (int i = 11; i >= 0; i--)
                {
                    var stats = GetMonthStats(year - yearDiff, i);

                    t.Cell().Text(stats.Item1);
                    t.Cell().Text(stats.Item2);
                    t.Cell().Text(stats.Item3);
                }
            }
        });
    }));
}

private static (string, string, string) GetMonthStats(int year, int monthIndex)
{
    return (
        $"{DateTimeFormatInfo.InvariantInfo.MonthNames[monthIndex]} {year}",
        DateTime.DaysInMonth(year, monthIndex + 1).ToString(),
        new DateTime(year, monthIndex + 1, 1).DayOfWeek.ToString()
    );
}

Der Beispielcode erstellt eine einfache Tabelle, die grundlegende Informationen über die Monate des aktuellen Jahres und der drei vorangegangenen Jahre anzeigt. Der Code definiert drei Spalten mit relativen Breiten. Die linke und die rechte Spalte sind viermal breiter als die mittlere Spalte.

Der Code definiert außerdem die Tabellenkopfzeile, indem er Kopfzellen hinzufügt und für jede Zelle Text und Hintergrundfarbe angibt. Wenn eine Tabelle nicht auf eine einzelne Seite passt, wird die Kopfzeile auf jeder Seite wiederholt, auf der sich die Tabelle befindet. Dieses Verhalten sehen Sie in dem vom Beispielcode erzeugten PDF.

Zum Erzeugen der Zeilen werden zwei einfache Schleifen verwendet. Die äußere Schleife iteriert über die Jahre, und die innere Schleife iteriert in umgekehrter Reihenfolge über die Monate. Die innere Schleife ruft Informationen zu jedem Monat ab und fügt dann drei Zellen hinzu, um eine Zeile zu bilden.

Weitere Details finden Sie im Artikel, der die Funktionen des Table-Containers ausführlich erläutert.

PDF-Dokumente unterstützen interne Links, die es Lesern ermöglichen, zu einer anderen Stelle innerhalb derselben Datei zu springen. In einem PDF-Viewer erscheinen diese Links als anklickbare Text- oder Bildelemente. Sie funktionieren wie Hyperlinks, verweisen aber nicht auf eine externe Website, sondern navigieren innerhalb des Dokuments selbst.

Illustration interner Links in einem PDF, die verbundene Dokumentabschnitte mit Link- und Zielsymbolen zeigt

Viele PDF-Dokumente verwenden interne Links für Lesezeichen oder ein Inhaltsverzeichnis, um Lesern zu helfen, schnell zwischen Abschnitten zu wechseln. So können Sie mit der Layout API einen Link zu einem Dokumentabschnitt hinzufügen:

PdfDocumentBuilder.Create().Generate("link.pdf", doc =>
{
    doc.Pages(pages =>
    {
        pages.Content().Column(c =>
        {
            const string SectionName = "Chapter 1";
            c.Item().SectionLink(SectionName).Text("Link");

            c.Item().PageBreak();

            c.Item().Section(SectionName).Text("Target");
        });
    });
});

Der Beispielcode macht den Text auf der ersten Seite zu einem Link auf den Abschnitt mit dem angegebenen Namen. Dazu ruft er die Methode SectionLink auf dem Layout-Container auf, der den Text enthält. Der Abschnitt muss zu diesem Zeitpunkt noch nicht existieren. Der Text wird in einem PDF-Viewer anklickbar.

Der Code markiert dann den Text auf der zweiten Seite als Beginn des Abschnitts mit demselben Namen. Darstellung und Verhalten ändern sich nicht, aber er wird zum Ziel des Links auf der ersten Seite. Dazu wird die Methode Section auf dem entsprechenden Layout-Container aufgerufen.

In diesem Beispiel sind sowohl der Link als auch sein Ziel Textabschnitte, aber Sie können Abschnitte und Links auf jedem Layout-Container erstellen. Das kann ein Container mit einem Bild sein, ein Tabellen-Container oder ein von Ihnen selbst erstellter Container.

Sehen Sie sich in unserem Beispiel-Repository ein Beispiel an, wie Sie ein PDF-Inhaltsverzeichnis erstellen.

Komplexe PDF-Layouts entwerfen

Die Layout API bietet eine Vielzahl von Layout-Containern, die Sie kombinieren können, um beliebig komplexe PDF-Dokumente zu erzeugen. Sie können die API auch mit eigenen benutzerdefinierten Komponenten erweitern.

Die Beispiele auf dieser Seite sind absichtlich einfach gehalten und darauf ausgelegt, übersichtliche Dokumente zu erzeugen, damit Sie sich auf die Kernideen konzentrieren können, ohne sich in Details zu verlieren. Wenn Sie sehen möchten, wie verschiedene Container kombiniert werden können, um ein komplexeres PDF zu erzeugen, werfen Sie einen Blick auf das entsprechende Beispiel in unserem Beispiel-Repository auf GitHub.

Zusätzlich zur Verwendung integrierter Container können Sie eigene Layout-Komponenten definieren und verwenden. Diese Komponenten sind besonders nützlich, wenn eine einzelne Klasse sowohl Daten als auch Layoutlogik kapseln soll. Wenn alles an einem Ort bleibt, ist die Komponente leichter zu verstehen, zu ändern und wiederzuverwenden, und Sie erhalten gleichzeitig eine flexible Möglichkeit, mit komplexen Layouts umzugehen.

Um eine benutzerdefinierte Layout-Komponente zu erstellen, implementieren Sie in Ihrer Klasse die Schnittstelle ILayoutComponent. Beim Erzeugen eines PDFs ruft die Bibliothek die Methode Compose der Schnittstelle auf und stellt ein LayoutContext-Objekt bereit. Ihr Code kann dieses Objekt verwenden, um Layout-Elemente zu erstellen und Informationen über das erzeugte Dokument abzurufen.

Um eine benutzerdefinierte Layout-Komponente zu Ihrem Layout hinzuzufügen, rufen Sie die Methode Component der Klasse LayoutContainer auf. In Bezug auf Größe und Position verhält sich eine benutzerdefinierte Komponente genau wie Text oder Bilder.

Ein Beispiel für die Implementierung einer benutzerdefinierten Komponente mit der Schnittstelle ILayoutComponent finden Sie im Beispiel Layout-Komponenten.

Andere Wege zur PDF-Erzeugung

Docotic.Pdf bietet mehrere Möglichkeiten zur PDF-Erzeugung, die jeweils für unterschiedliche Szenarien geeignet sind. Dieser Abschnitt erklärt, wann Sie sich auf die Layout API verlassen sollten und wann andere Ansätze für Sie besser geeignet sein können.

Wann man die Layout API bevorzugen sollte

Die Docotic.Pdf Layout API ist ein leistungsstarker Weg, PDFs aus strukturierten Layouts zu erzeugen. Sie ermöglicht es Ihnen, Dokumente zu erstellen, indem Sie Text, Bilder, Container und Tabellen zu beliebig komplexen, verschachtelten Strukturen zusammensetzen. Der Erzeugungsprozess ist schnell, benötigt eine angemessene Menge an Speicher und verhält sich vorhersehbar.

Docotic.Pdf und das Layout-Add-on bilden zusammen einen leichten, vollständig eigenständigen Satz. Die API benötigt keine externen Bibliotheken oder Browser, um PDFs zu erzeugen. Das macht sie zu einer soliden Wahl für .NET-Microservices, Cloud-Anwendungen, insbesondere serverlose, und andere Umgebungen, in denen die Größe des Footprints wichtig ist.

Da das Dokumentlayout im Code definiert ist, können Sie jeden Teil davon unit-testen. Layoutlogik kann wie jeder andere Code wiederverwendet werden, und Sie können Daten und Layoutverhalten in benutzerdefinierten Komponenten kapseln.

Alternativen zur Layout API

Ein eigener Artikel bietet einen detaillierten Vergleich aller Wege zur PDF-Erzeugung mit Docotic.Pdf. Nachfolgend sind einige der am häufigsten verwendeten Alternativen aufgeführt.

  • HTML-zu-PDF-Konvertierung
    Verwendet vorhandene HTML/CSS-Vorlagen wieder. Wählen Sie den HTML-zu-PDF-Ansatz, wenn Ihr Team Dokumente bereits in HTML/CSS erstellt und Sie PDF-Versionen dieser Dokumente benötigen.

  • PDF-Erzeugung auf niedriger Ebene
    Bietet die maximale Kontrolle, die die Bibliothek über PDF-Struktur und Inhalt bereitstellt. Wählen Sie dies, wenn Sie Positionierung auf Pixelebene oder komplexe Vektorgrafiken benötigen. Dieser Ansatz wird für leistungskritische Szenarien oder wenn der kleinstmögliche Footprint erforderlich ist, empfohlen.

  • Vorlagenbasierte PDF-Erzeugung
    Bietet eine schnelle, vorhersagbare Möglichkeit, Dokumente zu füllen, ohne ihre Elemente zu entwerfen oder anzuordnen. Wählen Sie dies, wenn Sie eine vordefinierte PDF-Struktur haben, etwa freigegebene oder compliance-gesteuerte Vorlagen, und nur Textfelder ändern, Platzhalter ersetzen, zugehörige Dokumente anhängen und ähnliche Aufgaben ausführen müssen.

  • Zusammenführen und Komponieren von PDFs
    Ermöglicht es Ihnen, ein PDF aus vorhandenen Bestandteilen zu erstellen, statt es von Grund auf neu zu bauen. Wählen Sie dies, wenn Sie Bilder, gescannte Seiten oder andere PDFs haben, die zu einer einzigen Datei zusammengeführt werden müssen.

Vergleich mit anderen Lösungen zur PDF-Erzeugung

Dieser Abschnitt enthält zwei Vergleichstabellen: eine mit den wichtigsten Erkenntnissen und eine weitere mit detaillierten, strukturierten Informationen dazu, wie sich Docotic.Pdf mit dem Layout-Add-on im Vergleich zu anderen populären Lösungen zur PDF-Erzeugung schlägt.

Wichtige Erkenntnisse des Vergleichs

Es gibt starke Optionen zur PDF-Erzeugung, darunter auch kostenlose. Allerdings unterscheiden sich Funktionen wie Signieren, Verschlüsseln oder Zusammenführen von Dokumenten, was einschränken kann, welche Werkzeuge wirklich zu Ihren Anforderungen passen.

Lösung Wann verwenden? Am besten geeignet für
Docotic.Pdf mit dem Layout-Add-on Wenn Sie eine hochwertige, performante Layout-Engine möchten, die optimierte PDFs erzeugen kann und fortschrittliche Unterstützung für Signaturen, Verschlüsselung und PDF-Bearbeitung plattformübergreifend bietet Hochwertige Erzeugung von Rechnungen, Berichten, Abrechnungen und ähnlichen Dokumenten mit hervorragender Entwicklererfahrung. Ideal, wenn Sie PDF-Verarbeitung auf Enterprise-Niveau und professionellen Support benötigen
PDFsharp + MigraDoc Wenn Sie eine kostenlose, MIT-lizenzierte Bibliothek für die einfache PDF-Erzeugung möchten und keine digitalen Signaturen oder modernen Verschlüsselungsalgorithmen benötigen Einfache Dokumenterstellung in Open-Source- oder budgetbeschränkten Projekten
QuestPDF Wenn Sie eine moderne Layout-Engine möchten, die ausschließlich der PDF-Erzeugung dient, und keine Bearbeitung, Signaturen oder Verschlüsselung benötigen Hochwertige PDF-Erzeugung mit einer MIT- oder kostengünstigen kommerziellen Lizenz, sofern alle Nicht-Erzeugungsfunktionen anderweitig gehandhabt werden
iText Wenn Sie ein ausgereiftes, funktionsreiches PDF-Toolkit sowohl zum Erzeugen als auch zum Verarbeiten von PDFs benötigen und bereit sind, Ihre Lösung entweder unter der AGPL/GPLv3-Lizenz als Open Source freizugeben oder eine teure kommerzielle Lizenz zu erwerben Teams, die die iText API bereits kennen und daher von ihrer steilen Lernkurve nicht betroffen sind

Detaillierter Vergleich

Sehen Sie sich die Tabelle an, um den breiteren Kontext zu verstehen und Ihre eigenen Schlussfolgerungen zu ziehen.

  Docotic.Pdf mit Layout PDFsharp + MigraDoc QuestPDF iText
PDF-Funktionen Voll ausgestattete PDF-Bibliothek PDF-Erzeugung und eingeschränkte Bearbeitung Nur PDF-Erzeugung Umfangreiche PDF-Funktionalität
Rendering-Modell Moderne, deklarative Layout-Engine im Retained-Mode Kastenbasierte Layout-Engine Moderne, deklarative Layout-Engine im Retained-Mode Kastenbasierte Layout-Engine + Renderer-Baum
API-Typ Fluent API Imperative API Fluent API Imperative API
Entwicklererfahrung Hervorragend. Die API ist sauber, modern und intuitiv Gut. Das API-Design ist konventionell Hervorragend. Die API ist sauber, modern und intuitiv Befriedigend. Die API ist ausführlich und übermäßig komplex
Font-Subsetting Unterstützt; standardmäßig werden nur verwendete Glyphen eingebettet Nicht unterstützt; kann zu unnötig großen PDFs führen Unterstützt; standardmäßig werden nur verwendete Glyphen eingebettet Unterstützt; standardmäßig werden nur verwendete Glyphen eingebettet
Inhaltsrichtung von rechts nach links (RTL) Unterstützt Nicht unterstützt Unterstützt Unterstützt
Digitale Signaturen Unterstützt, einschließlich LTV und externer Signaturen Nicht unterstützt Nicht unterstützt Unterstützt, einschließlich LTV und externer Signaturen
Verschlüsselung / Berechtigungen Vollständig unterstützt Nur RC4-Verschlüsselung, keine Unterstützung für AES oder Zertifikate Nicht unterstützt Vollständig unterstützt
Externe Abhängigkeiten Keine Keine SkiaSharp-/Skia-basierte Komponenten Keine
Support Professioneller Support für Interessenten und Kunden; Priority-Support mit Top-Tier-Lizenzen Community-Support; professioneller Support kann separat erworben werden Community-Support über GitHub Community-Support für die AGPL-Version; professioneller Support für Inhaber kommerzieller Lizenzen
Lizenz Kommerziell, mit kostenlosen Lizenzen für geeignete Anwendungsfälle MIT MIT für Einzelpersonen und kleine Unternehmen; für größere Unternehmen ist eine kommerzielle Lizenz erforderlich AGPL für Open-Source-Nutzung, teure kommerzielle Lizenz für proprietäre Projekte
Entwicklerlizenzierung Unbegrenzte Entwickler mit allen Lizenzen Unbegrenzte Entwickler mit allen Lizenzen Unbegrenzte Entwickler mit MIT; 10 Entwickler mit Professional; unbegrenzte Entwickler mit Enterprise Unbegrenzte Entwickler mit AGPL-Version; Entwicklerlizenzierung pro Entwickler mit kommerzieller Lizenz

Abschluss

Docotic.Pdf mit dem Layout-Add-on bietet eine moderne, performante und hochwertige Möglichkeit, PDFs in C# und VB.NET zu erzeugen. Die Bibliothek erzeugt Berichte, Abrechnungen, Rechnungen und ähnliche Dokumente. Ihre gut gestaltete, flüssige API bietet eine hervorragende Entwicklererfahrung. Sie können sich auf den professionellen Support verlassen, den Bit Miracle für Docotic.Pdf und seine Add-ons bietet.

Im Gegensatz zu einigen anderen Lösungen zur PDF-Erzeugung ist Docotic.Pdf eine voll ausgestattete PDF API. Die Bibliothek kann generierte PDFs signieren mit digitalen Signaturen, einschließlich LTV-fähiger Signaturen. Docotic.Pdf kann Zertifikate verwenden, die auf sicherer Hardware gespeichert sind, etwa USB-Token und Smartcards. Auch cloudbasierte Hardware-Sicherheitsmodule (HSMs) wie Microsoft Azure Key Vault und AWS Key Management Service (KMS) werden unterstützt.

Mit Docotic.Pdf können Sie Begleitdokumente anhängen, etwa Tabellenkalkulationen oder Sprachnotizen, an die erzeugten PDFs. Um Dokumente auf einer Webseite oder in einer ähnlichen Oberfläche anzuzeigen, können Sie aus einer oder mehreren ihrer Seiten Miniaturbilder erstellen.

Nächste Schritte: