Diese Seite kann automatisch übersetzten Text enthalten.
Verbundbehälter
Komplexe Container spielen eine entscheidende Rolle bei der Strukturierung und Organisation von Inhalten. Durch die Verwendung eines geeigneten Containers können Sie Text und Bilder einfach und benutzerfreundlich präsentieren.
Es ist durchaus möglich, ein Dokument nur mit einfachen Text- und Bildcontainern zu erstellen. Allerdings gibt es Anforderungen, die sich nur mit einfachen Containern nur schwer oder gar nicht umsetzen lassen. In solchen Fällen helfen zusammengesetzte Container. Außerdem helfen komplexe Container dabei, Ihre Ziele mit weniger Code zu erreichen.
Verwenden Sie Methoden der Klasse
LayoutContainer, um komplexe Container wie
Row und Column zu
Dokumentseiten hinzuzufügen. Mit diesen Containern können Sie andere Container wie Raster und
Listen implementieren. Es gibt auch die Methoden Inlined
und Layers
für weniger gebräuchliche,
aber dennoch wichtige Fälle.
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.
9.5.17615-dev 9.5.17615-dev14,813 bestanden NuGet-Downloads insgesamt 4,924,084
Row
Row-Container bieten Platz für horizontal in einer Zeile angeordnete Elemente. Jedes Element in einer Zeile ist ein Container. Das bedeutet, dass Sie Inhalte unterschiedlichen Typs in einer Zeile unterbringen können. Sie können den Abstand zwischen den Elementen mit der Methode Spacing festlegen.
Alle Elemente in einer Reihe haben die gleiche Höhe. Die Bibliothek verwendet die Höhe des höchsten Elements als Höhe der Reihe. Es gibt drei Möglichkeiten, die Breite eines Elements anzugeben. Sie müssen beim Erstellen des Elements eine auswählen. Eine Reihe kann Elemente enthalten, die auf unterschiedliche Weise erstellt wurden.
Die Methode Row.AutoItem erstellt ein Element ohne
explizit angegebene Breite. Für solche Elemente berechnet die Bibliothek die tatsächliche Größe
ihres Inhalts. Die berechnete Inhaltsbreite ist die Breite des Elements. Bitte beachten Sie, dass
mit AutoItem
erstellte Elemente lange Zeilen nicht umbrechen.
Verwenden Sie die Methode ConstantItem, um ein Element mit einer Breite zu erstellen, die einer genauen Anzahl von Punkten entspricht.
Das RelativeItem ist praktisch, wenn Sie die
genaue Breite der Elemente in der Zeile nicht kennen und keine intrinsischen Größen verwenden
möchten. Stattdessen können Sie relative Breiten für Elemente in der Zeile angeben. Die Methode
akzeptiert die Anzahl der Teile, die das Element einnehmen soll. Die Gesamtzahl der Teile ist die
Summe aller Zahlen in allen RelativeItem
-Aufrufen in dieser Zeile.
Wenn es beispielsweise einen RelativeItem
-Aufruf gibt, ist die Zahl nicht wichtig. Das Element
nimmt die gesamte verfügbare Breite ein. Bei zwei oder mehr Elementen definieren die Zahlen die
Proportionen.
row.RelativeItem(2)
row.RelativeItem(3)
row.RelativeItem(1)
Alle mit dem obigen Code erstellten Elemente bestehen aus 6 Teilen (2 + 3 + 1 = 6
). Einzelne
Elemente nehmen jeweils 2 von 6, 3 von 6 und 1 von 6 Teilen ein.
Die Layout-API verwendet die folgende Formel, um die Breite eines Teils zu berechnen:
PartWidth = (RowWidth - AutoWidth - ConstantWidth) / TotalParts
wobei:
RowWidth
= Breite des Zeilencontainers,
AutoWidth
= Breite aller mit der Methode AutoItem
erstellten Elemente,
ConstantWidth
= Breite aller mit der Methode ConstantItem
erstellten Elemente.
Hier ist ein Beispiel, das eine Zeile mit Elementen aller drei Arten erstellt.
var monthNames = DateTimeFormatInfo.InvariantInfo.MonthNames;
var groups = new[]
{
string.Join(", ", monthNames.Take(4)),
string.Join(", ", monthNames.Skip(4).Take(4)),
string.Join(", ", monthNames.Skip(8).Take(4)),
};
PdfDocumentBuilder.Create().Generate("compounds-row.pdf", doc => doc.Pages(page =>
{
page.Content()
.Padding(20)
.MinimalBox()
.Row(row =>
{
row.ConstantItem(100)
.Background(new PdfRgbColor(187, 237, 237))
.Text("100 points wide");
for (int i = 0; i < groups.Length; i++)
{
row.AutoItem().LineVertical(0.1);
var numberOfParts = groups.Length - i + 1;
row.RelativeItem(numberOfParts)
.PaddingHorizontal(5)
.Text(t =>
{
t.Line($"{numberOfParts} parts wide");
t.Line();
t.Line(groups[i]);
});
}
});
}));
Das Ergebnis des Codes können Sie in compounds-row.pdf sehen.
Column
Um Elemente vertikal hintereinander anzuordnen, verwenden Sie einen Column-Container. Jedes Element in einer Spalte ist ein Container. Dadurch können Sie Inhalte unterschiedlichen Typs in einer Spalte platzieren.
Die Breite jedes Elements entspricht der Spaltenbreite. Die Höhe jedes Elements hängt vom Inhalt
und den Eigenschaften des Elements ab. Column
-Container unterstützen die Seitennummerierung,
sodass das Layout-Add-on Elemente einer Spalte auf mehreren Seiten darstellen kann.
Standardmäßig hat ein Column
-Container keinen Kopf- oder Fußzeileninhalt. Verwenden Sie die
Methoden Header und
Footer, um auf die entsprechenden Container
zuzugreifen und sie einzurichten. Wenn Spaltenelemente mehr als eine Seite einnehmen, wiederholt
die Bibliothek sowohl Kopf- als auch Fußzeilen auf jeder Seite.
Verwenden Sie die Methode Spacing, um einen vertikalen Abstand zwischen den Spaltenelementen hinzuzufügen. Bitte beachten Sie, dass die Bibliothek keinen Abstand zwischen der Kopfzeile und dem ersten Element anwendet. Die Bibliothek fügt auch keinen Abstand vor der Fußzeile hinzu.
PdfDocumentBuilder.Create().Generate("compounds-column.pdf", doc => doc.Pages(page =>
{
page.Size(PdfPaperSize.A6);
page.Content()
.Padding(20)
.Column(column =>
{
column.Header()
.Background(new PdfRgbColor(187, 237, 237))
.Padding(5)
.Text("Month names");
for (int i = 0; i < 12; i++)
{
column.Item().Background(
new PdfGrayColor(i % 2 == 0 ? 90 : 100))
.Padding(5)
.Text(DateTimeFormatInfo.InvariantInfo.MonthNames[i]);
}
column.Footer().LineHorizontal(1);
});
}));
Das Ergebnis des Codes können Sie in compounds-column.pdf sehen.
Raster
Rasterlayouts organisieren Elemente in Spalten und Zeilen. Raster sind in dieser Hinsicht Tabellen ähnlich. Die Layout-API bietet keinen speziellen Containertyp für Raster. Sie können ein Rasterlayout mit den Containern Column und Row implementieren.
Es ist hilfreich, sich ein Raster als eine Spalte vorzustellen, wobei jedes seiner Elemente eine
Zeile darstellt. Sowohl die Container Column
als auch Row
bieten die Möglichkeit, den Abstand
zwischen den Elementen festzulegen. Sie können eine Kopf- und eine Fußzeile haben, wenn Sie
möchten.
Jede Zeile kann ein unabhängiges Layout haben. Jede Zeile kann eine unterschiedliche Anzahl von Elementen enthalten. Elemente können unterschiedliche Breiten und Höhen haben. Es ist möglich, vor, nach oder zwischen Elementen in einer Zeile zusätzlichen Platz einzufügen. Verwenden Sie hierfür Elemente ohne Inhalt und Dekoration.
var blue = new PdfRgbColor(187, 237, 237);
var darkerBlue = blue.Darken(50);
PdfDocumentBuilder.Create().Generate("compounds-grid.pdf", doc => doc.Pages(page =>
{
page.Size(300, 200);
page.Content().Padding(15).Column(column =>
{
column.Spacing(10);
column.Item().Row(row =>
{
row.Spacing(10);
row.ConstantItem(100).Background(darkerBlue).Height(40);
row.RelativeItem(4).Background(blue);
});
column.Item().Row(row =>
{
row.Spacing(10);
row.RelativeItem(2).Background(blue).Height(60);
row.RelativeItem(1);
row.RelativeItem(2).Background(blue);
});
column.Item().Row(row =>
{
row.Spacing(10);
row.RelativeItem(1).Background(blue).Height(50);
row.RelativeItem(3).Background(blue);
row.ConstantItem(50).Background(darkerBlue);
});
});
}));
Das Ergebnis des Codes können Sie in compounds-grid.pdf sehen.
Listen
Listen verbessern die Lesbarkeit, indem sie Informationen in prägnante Punkte aufteilen. Listenelemente können Zahlen, Aufzählungszeichen und andere Symbole neben dem darin enthaltenen Text enthalten. Sie können ein Listenlayout problemlos mit den Containern Column und Row implementieren. Die Layout-API bietet keinen speziellen Containertyp für Listen.
Sehen Sie sich den Beispielcode an, der eine Liste von Monaten nach Jahreszeiten erstellt. Bitte beachten Sie, dass die Liste eine Kopfzeile hat. Wenn Elemente Text enthalten, der in die nächste Zeile umbrochen werden kann, verwenden Sie für den Textteil des Elements entweder die Methode RelativeItem oder die Methode ConstantItem.
var monthNames = DateTimeFormatInfo.InvariantInfo.MonthNames.ToList();
monthNames.Insert(0, monthNames[11]);
PdfDocumentBuilder.Create().Generate("compounds-list.pdf", doc => doc.Pages(page =>
{
page.Size(150, 200);
page.Content().Padding(5).Column(column =>
{
column.Header()
.Text("Months by seasons:")
.Style(TextStyle.Parent.Underline());
for (int i = 0; i < 4; i++)
{
var season = string.Join(", ", monthNames.Skip(i * 3).Take(3));
column.Item().Row(row =>
{
row.Spacing(2);
row.AutoItem().Text("•");
row.RelativeItem().Text(season);
});
}
});
}));
Das Ergebnis des Codes können Sie in compounds-list.pdf sehen.
Table
Tabellenlayouts organisieren Elemente in Spalten und Zeilen. Der Containertyp Table bietet eine umfangreiche Reihe von Funktionen und kann Ihnen bei den anspruchsvollsten Fällen helfen. Lesen Sie mehr über alle Funktionen im Artikel Table-Container.
InlineContainer
Sie können einen Container mit einer Sammlung anderer Container füllen. Beginnen Sie mit dem Aufruf
der Methode LayoutContainer.Inlined
. Rufen Sie dann die Methode
Item des bereitgestellten
InlineContainer auf, um untergeordnete Container
hinzuzufügen.
Das Layout-Add-on platziert Container in einer Reihe hintereinander. Wenn kein Platz für ein
Element vorhanden ist, beginnt die Bibliothek eine neue Reihe. Verwenden Sie die Methoden
Spacing/HorizontalSpacing/VerticalSpacing
, um etwas Abstand zwischen den Elementen hinzuzufügen.
Sie können die Position von Elementen im Container mithilfe von Ausrichtungsmethoden beeinflussen.
Die Methoden AlignTop/AlignMiddle/AlignBottom
richten Elemente vertikal aus. Für die horizontale
Richtung verwenden Sie die Methoden AlignLeft/AlignCenter/AlignRight/AlignJustify
.
Es gibt einen Sonderfall. Die Methode AlignSpaceAround richtet Elemente horizontal aus. Sie fügt außerdem zusätzlichen Abstand vor dem ersten und nach dem letzten Element hinzu.
var orange = new PdfRgbColor(250, 123, 5);
var brown = orange.Darken(50);
var itemProps = new (int Width, PdfColor Color)[] {
(20, orange), (30, orange), (50, brown), (50, orange), (50, orange),
(30, orange), (20, brown), (30, orange), (50, brown), (10, brown)
};
PdfDocumentBuilder.Create().Generate("compounds-inlined.pdf", doc => doc.Pages(page =>
{
page.Size(150, 120);
page.Content().Inlined(c =>
{
c.Spacing(5);
foreach (var (Width, Color) in itemProps)
c.Item().Height(30).Width(Width).Background(Color);
});
}));
Das Ergebnis des Codes können Sie in compounds-inlined.pdf sehen.
LayerContainer
Möglicherweise müssen Sie Inhalt unter und/oder über den Inhalt der Hauptseite setzen. Der offensichtlichste Anwendungsfall ist das Hinzufügen eines Wasserzeichens über PDF-Seiten.
Holen Sie sich zunächst ein LayerContainer-Objekt, indem Sie die Methode LayoutContainer.Layers aufrufen. Wenn das Objekt vorhanden ist, können Sie mit dem Hinzufügen von Ebenen beginnen. Durch Aufrufen der Methode Layer wird eine sekundäre Ebene hinzugefügt. Rufen Sie die Methode PrimaryLayer auf, um die Hauptinhaltsebene hinzuzufügen. Sie müssen genau eine primäre Ebene hinzufügen.
Die Layout-API erstellt die Ebenen in derselben Reihenfolge, in der Sie sie erstellen. Ebenen, die vor der primären Ebene hinzugefügt werden, werden in den Hintergrund verschoben. Alle Ebenen, die nach der primären Ebene hinzugefügt werden, werden über den Hauptinhalt verschoben. Der Container wiederholt die sekundären Ebenen auf allen Seiten, die vom Hauptinhalt belegt werden.
Hier ist ein Beispielcode zum Hinzufügen von Wasserzeichen zu PDF-Seiten.
PdfDocumentBuilder.Create().Generate("compounds-layers.pdf", doc => doc.Pages(page =>
{
var largeRedText = TextStyle.Parent.FontSize(48)
.FontColor(new PdfRgbColor(235, 64, 52));
page.Size(400, 250);
page.Content()
.Padding(25)
.Layers(layers =>
{
layers.Layer()
.AlignCenter()
.Text(text => text.CurrentPageNumber().Style(largeRedText));
layers.PrimaryLayer()
.Background(new PdfGrayColor(85), 65)
.Padding(25)
.Text(new string('_', 790));
layers.Layer()
.AlignCenter()
.AlignMiddle()
.Text("Watermark")
.Style(largeRedText);
});
}));
Das Ergebnis des Codes können Sie in compounds-layers.pdf sehen.
Wasserzeichen
Eine der häufigsten Anforderungen besteht darin, PDFs mit Wasserzeichen zu versehen. Diese Anforderung kann aus verschiedenen Gründen bestehen. Sie können PDFs mit Wasserzeichen versehen, um den Eigentümer zu identifizieren oder auf die Vertraulichkeit oder Sensibilität der Informationen in der PDF hinzuweisen.
Eine Möglichkeit, PDFs mit Wasserzeichen zu versehen, besteht in der Verwendung von Ebenen. Siehe das Beispiel im vorherigen Abschnitt. Ich zeige Ihnen eine andere Möglichkeit.
Ich werde Seitenhintergrund- und Vordergrundcontainer verwenden, um PDFs mit Wasserzeichen zu versehen. Das Layout-Add-on wiederholt diese Container auf den nächsten Seiten. Jede Seite mit primärem Dokumentinhalt wird auch Hintergrund- und Vordergrundcontainer enthalten. Dadurch sind sie für die Aufgabe geeignet.
Ich beginne damit, dem Hintergrundcontainer ein Bild hinzuzufügen. Sie können Ihr Logo auf die gleiche Weise zu PDF hinzufügen. Das Bild wird hinter dem Seiteninhalt angezeigt. Es spielt keine Rolle, wie viele Seiten Ihres Dokuments das Hintergrundbild verwenden. Die API fügt dem generierten PDF nur eine Kopie der Bildbytes hinzu.
Der primäre Dokumentinhalt kann alles sein. Für diesen Beispielcode verwende ich den berühmten Lorem Ipsum-Text.
Das Textwasserzeichen wird in den Vordergrundcontainer eingefügt. Der Text selbst kann beliebig sein und Sie können jede beliebige Farbe oder Schriftart verwenden. Ich habe gedrehten Text verwendet, der mit halbtransparenten roten Buchstaben in größerer Größe gezeichnet wurde.
Der Beispielcode lädt sowohl das Bild als auch den Text asynchron aus unserem Beispielcode-Repository herunter. Natürlich können Sie ein lokales Bild verwenden und/oder den Text aus einer Datei lesen.
var urlPrefix =
"https://raw.githubusercontent.com/BitMiracle/Docotic.Pdf.Samples/master/Samples/Sample%20Data/";
using var client = new HttpClient();
using var imageResponse = await client.GetAsync(urlPrefix + "watermark-background.png");
using var imageStream = await imageResponse.Content.ReadAsStreamAsync().ConfigureAwait(false);
var loremIpsum = string.Empty;
using (var textResponse = await client.GetAsync(urlPrefix + "lorem-ipsum.txt"))
loremIpsum = await textResponse.Content.ReadAsStringAsync().ConfigureAwait(false);
PdfDocumentBuilder.Create().Generate("compounds-watermarks.pdf", doc =>
{
var image = doc.Image(imageStream);
doc.Pages(page =>
{
page.Size(400, 250);
page.Background()
.AlignMiddle()
.Image(image);
page.Content()
.Padding(25)
.Text(loremIpsum);
var largeRedText = TextStyle.Parent.FontSize(48)
.FontColor(new PdfRgbColor(235, 64, 52), 50);
page.Foreground()
.Rotate(-30)
.Translate(-50, 180)
.Text("DO NOT COPY")
.Style(largeRedText);
});
});
Das Ergebnis des Codes können Sie in compounds-watermarks.pdf sehen.
Beispielcode
Wir haben einige Beispiel-Apps, die die oben genannten Funktionen ausführlicher behandeln. Bitte nehmen Sie sich etwas Zeit und sehen Sie sie sich an.