Diese Seite kann automatisch übersetzten Text enthalten.

Table-Container

Verwenden Sie Table-Container, um Ihre komplexesten Daten zu layouten. Tabellen spielen in PDF-Dokumenten eine entscheidende Rolle, da sie deren Übersichtlichkeit und Effektivität verbessern.

Tabellen bieten ein strukturiertes Format für die Präsentation Ihrer Daten. Sie ermöglichen Ihnen die Darstellung komplexer Details auf prägnante und optisch ansprechende Weise. Anstelle langer Absätze können Sie Tabellen verwenden, um Fakten, Zahlen und Trends prägnant darzustellen.

Eine gut gestaltete Tabelle verbessert die Lesbarkeit. Durch die Ausrichtung von Spalten und Zeilen erstellen Sie eine Struktur, die den Blick des Lesers lenkt. Sie können Hintergründe, Rahmen und Schriftarten verwenden, um bestimmte Zellen oder Überschriften hervorzuheben.

Table-Container

Holen Sie sich einen Tabellencontainer, indem Sie die Methode LayoutContainer.Table aufrufen. Anschließend müssen Sie mindestens eine Spalte im Container definieren. Im einfachsten Fall können Sie alle Spalten und Zeilen füllen, indem Sie die Methode Cell mehrfach aufrufen.

Lesen Sie weiter, um zu erfahren, wie Sie Spalten definieren und einer Tabelle eine Kopf- und/oder Fußzeile hinzufügen. Der Text beschreibt auch alle anderen Funktionen des Containers Table.

Dieser Artikel ist Teil einer Serie über die Layout-API für die PDF-Generierung. Wenn Sie mit der API noch nicht vertraut sind, lesen Sie zuerst den Teil Erste Schritte mit der Layout-API.

Docotic.Pdf-Bibliothek 9.4.17469-dev Layout-Add-on 9.4.17469-dev
Regressionstests 14,760 bestanden NuGet-Downloads insgesamt 4,447,259

Spalten und Zeilen

Jede Tabelle muss mindestens eine Spalte definieren. Verwenden Sie die Methode Table.Columns, um Spalten zu definieren. Die Methode akzeptiert einen Delegaten vom Typ Action<TableColumnContainer>. Fügen Sie im Delegatencode der Tabelle Spalten hinzu, indem Sie Methoden des bereitgestellten Objekts aufrufen.

Die Methode ConstantColumn fügt eine Spalte mit einer Breite hinzu, die einer genauen Anzahl von Punkten entspricht.

Die Methode RelativeColumn fügt eine Spalte mit relativer Breite hinzu. Die Methode akzeptiert die Anzahl der Teile, die die Spalte einnehmen soll. Die Gesamtzahl der Teile ist die Summe aller Zahlen in allen RelativeColumn-Aufrufen in dieser Tabelle. Meistens funktioniert diese Methode genauso wie das RelativeItem des Row-Containers. Bitte lesen Sie den Link für die ausführliche Erklärung.

Es ist nicht notwendig, Zeilen explizit zu definieren. Die Anzahl der Zeilen hängt von den Spalten- und Zelleneigenschaften ab. Die Anzahl der Zellen kann sich auch auf die Anzahl der Zeilen auswirken. Die Höhe einer Tabelle kann größer sein als die Summe aller Zeilenhöhen. Zeilen können weniger Zellen als Spalten haben. Und es ist möglich, dass Spalten weniger Zellen als Zeilen haben.

PdfDocumentBuilder.Create().Generate("table-basic.pdf", doc =>
{
    doc.Pages(page =>
    {
        page.Size(300, 100);
        page.Content()
            .Padding(10)

            //.MinimalBox()

            .Border(b => b.Thickness(1).Color(new PdfRgbColor(250, 123, 5)))
            .Table(table =>
            {
                table.Columns(columns =>
                {
                    columns.ConstantColumn(100);
                    columns.RelativeColumn(1);
                    columns.RelativeColumn(3);
                });

                for (int i = 0; i < 10; i++)
                {
                    table.Cell()
                        .Border(b => b.Thickness(0.1))
                        .AlignCenter()
                        .Text($"Cell {i + 1}");
                }
            });
    });
});

Das Ergebnis des Codes können Sie in table-basic.pdf sehen.

Im resultierenden PDF nimmt die Tabelle den gesamten Platz des übergeordneten Containers ein. Auch wenn nicht genügend Zellen vorhanden sind, um den Bereich abzudecken. Entfernen Sie die Kommentarzeichen aus dem Aufruf MinimalBox, um die Tabellenhöhe auf die Summe der Zeilenhöhen zu begrenzen.

Der Code definiert drei Spalten und fügt der Tabelle 10 Zellen hinzu. Table fügt die Zellen nacheinander ein und fügt bei Bedarf eine neue Zeile hinzu. Es ist völlig in Ordnung, eine Zeile mit nur einer Zelle zu haben.

Die Tabelle platziert Zellen auf der nächsten Seite, wenn auf der aktuellen Seite nicht genügend Platz vorhanden ist. Sie können dies beobachten, indem Sie die Anzahl der hinzugefügten Zellen erhöhen.

Zellen

Lassen Sie mich erklären, was die Layout-API für die Arbeit mit Tabellenzellen bereitstellt.

Position

Es gibt zwei Möglichkeiten, eine Tabellenzelle zu erstellen:

  • ohne explizite Positionsangabe
  • mit zumindest teilweise angegebener Position

Ich habe im Code des vorherigen Abschnitts die erste Methode verwendet. Sie rufen die Überladung der Methode Cell auf, die keine Parameter akzeptiert. Die Methode fügt der Spalte nach der letzten hinzugefügten Zelle eine neue Zelle hinzu. Wenn rechts kein Platz ist, wird die Zelle in die nächste Zeile verschoben. Im RTL-Modus prüft die Methode, ob links von der letzten hinzugefügten Zelle Platz ist.

Wenn Sie die genaue Position der neuen Zelle kennen, verwenden Sie die andere Überladung der Methode Cell. Diejenige, die einen Delegaten vom Typ Action<TableCell> akzeptiert. Geben Sie im Delegatencode die Zellenzeile und den Index an, indem Sie die Methoden RowIndex und ColumnIndex des bereitgestellten Objekts aufrufen.

Es ist möglich, nur einen Zeilen- oder Spaltenindex für die neue Zelle anzugeben. Der Spaltenindex ist 0, wenn Sie nur einen Zeilenindex angeben. Und umgekehrt.

Beim Erstellen von Zellen können Sie Aufrufe beider Cell-Überladungen in beliebiger Reihenfolge mischen.

Ich werde in den nächsten Codebeispielen in diesem Artikel die folgende Erweiterungsmethode verwenden. Dies sollte die Beispiele prägnanter und leichter lesbar machen.

static class LayoutHelpers
{
    public static TextSpan BoxWithText(this LayoutContainer cell, string caption)
        => cell.Border(b => b.Thickness(0.5))
            .Background(new PdfGrayColor(75))
            .ShowOnce()
            .MinWidth(50)
            .MinHeight(50)
            .Padding(10)
            .AlignCenter()
            .AlignMiddle()
            .Text(caption);
}

Hier ist ein Beispiel, das eine Tabelle mit explizit und implizit platzierten Zellen erstellt. Ich habe die Erweiterungsmethode verwendet, um Stil und Text auf Zellen anzuwenden. Zahlen in Zellen spiegeln die Erstellungsreihenfolge der Zellen wider.

PdfDocumentBuilder.Create().Generate("table-cells.pdf", doc =>
{
    doc.Pages(page =>
    {
        page.Size(300, 200);
        page.Content()
            .Padding(10)
            .MinimalBox()
            .Border(b => b.Thickness(0.1))
            .Table(table =>
            {
                table.Columns(columns =>
                {
                    for (int i = 0; i < 4; i++)
                        columns.RelativeColumn();
                });

                table.Cell().BoxWithText("1");
                table.Cell(c => c.RowIndex(1).ColumnIndex(1)).BoxWithText("2");
                table.Cell().BoxWithText("3");
                table.Cell(c => c.RowIndex(2).ColumnIndex(2)).BoxWithText("4");
                table.Cell(c => c.RowIndex(0).ColumnIndex(3)).BoxWithText("5");
            });
    });
});

Das Ergebnis des Codes können Sie in table-cells.pdf sehen.

Zeilen- und Spaltenbereiche

Zellen können sich über mehrere Zeilen und/oder mehrere Spalten erstrecken. Verwenden Sie die Überladung Cell, die einen Delegaten akzeptiert, um die Anzahl der Zeilen und Spalten anzugeben, über die sich die Zelle erstreckt.

PdfDocumentBuilder.Create().Generate("table-cellspans.pdf", doc =>
{
    doc.Pages(page =>
    {
        page.Size(300, 150);
        page.Content()
            .Padding(10)
            .MinimalBox()
            .Border(b => b.Thickness(0.1))
            .Table(table =>
            {
                table.Columns(columns =>
                {
                    for (int i = 0; i < 4; i++)
                        columns.RelativeColumn();
                });

                table.Cell(c => c.RowSpan(2).ColumnSpan(2)).BoxWithText("1");
                table.Cell(c => c.ColumnSpan(2)).BoxWithText("2");
                table.Cell().BoxWithText("3");
                table.Cell().BoxWithText("4");
            });
    });
});

Das Ergebnis des Codes können Sie in table-cellspans.pdf sehen.

Überlappung

Es ist möglich, dass sich Zellen gegenseitig überdecken. Wenn das passiert, bestimmt die Reihenfolge der Erstellung, welche Zelle über der anderen liegt.

Wenn sich Ihre Zellen über mehr als eine Spalte oder Zeile erstrecken, kann es zu überlappenden Zellen kommen. Oder wenn Sie Zellen sowohl explizit als auch implizit positionieren.

PdfDocumentBuilder.Create().Generate("table-overlapping.pdf", doc =>
{
    doc.Pages(page =>
    {
        page.Size(300, 300);
        page.Content()
            .Padding(10)
            .MinimalBox()
            .Border(b => b.Thickness(0.1))
            .Table(table =>
            {
                table.Columns(columns =>
                {
                    for (int i = 0; i < 4; i++)
                        columns.RelativeColumn();
                });

                for (int i = 0; i < 16; i++)
                    table.Cell().BoxWithText($"{i + 1}");

                table.Cell(c => c.RowIndex(2).ColumnIndex(1).ColumnSpan(3))
                    .Background(new PdfRgbColor(250, 123, 5), 50);
            });
    });
});

Das Ergebnis des Codes können Sie in table-overlapping.pdf sehen.

Nach unten erweitern

Wenn das Layout Ihrer Tabelle komplex ist, kann der Seitenmechanismus einen leeren Bereich am unteren Ende einiger Spalten verursachen. Verwenden Sie die Methode ExtendCellsToBottom, wenn Sie den leeren Bereich entfernen möchten. Die Methode erweitert die letzte Zelle in jeder Spalte, sodass die Zellen am unteren Ende der Tabelle enden.

Im folgenden Beispiel wird auf der ersten Seite das Standardverhalten gezeigt. Auf der zweiten Seite wird gezeigt, wie sich der Aufruf ExtendCellsToBottom auf die Spalten auswirkt.

PdfDocumentBuilder.Create().Generate("table-extendcells.pdf", doc =>
{
    for (int take = 0; take < 2; take++)
    {
        doc.Pages(page =>
        {
            page.Size(300, 200);
            page.Content()
                .Padding(10)
                .MinimalBox()
                .Border(b => b.Thickness(0.1))
                .Table(table =>
                {
                    if (take != 0)
                        table.ExtendCellsToBottom();

                    table.Columns(columns =>
                    {
                        for (int i = 0; i < 4; i++)
                            columns.RelativeColumn();
                    });

                    table.Cell(c => c.RowIndex(0).ColumnIndex(0)).BoxWithText("1");
                    table.Cell(c => c.RowIndex(2).ColumnIndex(0)).BoxWithText("2");
                    table.Cell(c => c.RowIndex(1).ColumnIndex(1)).BoxWithText("3");
                    table.Cell(c => c.RowIndex(2).ColumnIndex(2)).BoxWithText("4");
                    table.Cell(c => c.RowIndex(1).ColumnIndex(3)).BoxWithText("5");
                });
        });
    }
});

Das Ergebnis des Codes können Sie in table-extendcells.pdf sehen.

Tabellen können eine Kopf- und eine Fußzeile haben. Verwenden Sie die Methoden Header und Footer, um auf den entsprechenden TableCellContainer zuzugreifen und ihn einzurichten. Der Container stellt die Cell-Methoden zum Erstellen von Zellen bereit. Diese Methoden funktionieren genauso wie die Methoden für den Hauptinhalt der Tabelle.

Kopf-, Fuß- und Haupttabellenzellen verwenden dieselbe Spaltendefinition. Alle drei Zellsammlungen sind jedoch unabhängig und beeinflussen sich nicht gegenseitig.

Wenn die Tabelle nicht auf eine Seite passt, werden Kopf- und Fußzeile auf jeder von der Tabelle belegten Seite wiederholt.

Ich habe in den vorherigen Beispielen die Erweiterungsmethode BoxWithText verwendet. Für den nächsten Code verwende ich auch die Erweiterungsmethode WhiteBoxWithText.

static class LayoutHelpers
{
    public static TextSpan WhiteBoxWithText(
        this LayoutContainer cell, string caption, bool center = true)
    {
        return cell.Border(b => b.Thickness(0.5))
            .ShowOnce()
            .MinWidth(50)
            .MinHeight(50)
            .Padding(10)
            .Container(l => center ? l.AlignCenter() : l)
            .AlignMiddle()
            .Text(caption);
    }
}

Das folgende Beispiel zeigt, wie man eine Tabelle mit einer Überschrift erstellt. Ich verwende eine Tabelle mit fünf wesentlichen chemischen Elementen. Für jedes Element sind der Name und der Schmelzpunkt in Celsius und Kelvin angegeben.

var elements = new (string Name, double Celsius, double Kelvin)[] {
    ("Oxygen", -218.79, 54.36),
    ("Carbon", double.NaN, double.NaN),
    ("Hydrogen", -259.16, 13.99),
    ("Nitrogen", -209.86, 63.23),
    ("Sulfur", 115.21, 388.36),
};

static string formatDouble(double val)
{
    return double.IsNaN(val)
        ? string.Empty
        : val.ToString(CultureInfo.InvariantCulture);
}

PdfDocumentBuilder.Create().Generate("table-header.pdf", doc =>
{
    doc.Pages(page =>
    {
        page.Size(400, 500);
        page.Content()
            .Padding(10)
            .MinimalBox()
            .Border(b => b.Thickness(0.1))
            .Table(table =>
            {
                table.Columns(columns =>
                {
                    columns.RelativeColumn();
                    columns.ConstantColumn(100);
                    columns.ConstantColumn(100);
                });

                table.Header(header =>
                {
                    header.Cell(c => c.RowSpan(2)).BoxWithText("Chemical element");
                    header.Cell(c => c.ColumnSpan(2)).BoxWithText("Melting point");

                    header.Cell().BoxWithText("Celsius");
                    header.Cell().BoxWithText("Kelvin");
                });

                foreach (var (Name, Celsius, Kelvin) in elements)
                {
                    table.Cell().WhiteBoxWithText(Name, false);

                    table.Cell().WhiteBoxWithText(formatDouble(Celsius));
                    table.Cell().WhiteBoxWithText(formatDouble(Kelvin));
                }
            });
    });
});

Das Ergebnis des Codes können Sie in table-header.pdf sehen.

Beispielcode

Nehmen Sie sich bitte etwas Zeit, um das Beispiel Fügen Sie Tabellen zu PDF-Dokumenten hinzu zu prüfen. Es zeigt auch, wie man Tabellen mit Überschriften erstellt, verwendet aber keine Erweiterungsmethoden. Und es gibt auch eine VB.NET-Version.