Cette page peut contenir du texte traduit automatiquement.
Conteneur de tableau
Utilisez des conteneurs Table pour mettre en page vos données les plus complexes. Les tableaux jouent un rôle crucial dans les documents PDF, en améliorant leur clarté et leur efficacité.
Les tableaux offrent un format structuré pour présenter vos données. Ils vous permettent de présenter des détails complexes de manière concise et visuellement attrayante. Au lieu de longs paragraphes, vous pouvez utiliser des tableaux pour présenter des faits, des chiffres et des tendances de façon synthétique.
Un tableau bien conçu améliore la lisibilité. En alignant les colonnes et les lignes, vous créez une structure qui guide le regard du lecteur. Vous pouvez utiliser des arrière-plans, des bordures et des styles de police pour mettre en valeur des cellules ou des titres spécifiques.

Obtenez un conteneur de tableau en appelant la méthode LayoutContainer.Table. Vous devez ensuite définir au moins une colonne dans le conteneur. Dans le cas le plus simple, vous pouvez remplir toutes les colonnes et toutes les lignes en appelant plusieurs fois la méthode Cell.
Poursuivez la lecture pour savoir comment définir des colonnes, ajouter un en-tête et/ou un pied de page à un tableau. Ce texte décrit aussi toutes les autres fonctionnalités du conteneur Table.
Cet article fait partie d’une série sur Layout API pour la génération de PDF. Si vous découvrez l’API, lisez d’abord la partie Premiers pas avec Layout API.
Colonnes et lignes
Chaque tableau doit définir au moins une colonne. Utilisez la méthode Table.Columns pour définir des colonnes. La méthode accepte un délégué de type Action<TableColumnContainer>. Dans le code du délégué, ajoutez des colonnes au tableau en appelant des méthodes de l’objet fourni.
La méthode ConstantColumn ajoute une colonne dont la largeur est égale à un nombre exact de points.
La méthode RelativeColumn ajoute une colonne avec une largeur relative. La méthode accepte le nombre de parts que la colonne doit occuper. Le nombre total de parts correspond à la somme de tous les nombres passés dans tous les appels RelativeColumn de ce tableau. Dans la plupart des cas, cette méthode fonctionne comme RelativeItem du Row container. Veuillez consulter le lien pour une explication détaillée.
Il n’est pas nécessaire de définir explicitement les lignes. Le nombre de lignes dépend des propriétés des colonnes et des cellules. Le nombre de cellules peut aussi influer sur le nombre de lignes. Un tableau peut avoir une hauteur supérieure à la somme de la hauteur de toutes ses lignes. Les lignes peuvent avoir moins de cellules que le nombre de colonnes. Et les colonnes peuvent avoir moins de cellules que le nombre de lignes.
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}");
}
});
});
});
Vous pouvez voir le résultat du code dans table-basic.pdf.
Dans le PDF résultant, le tableau occupe tout l’espace du conteneur parent, même s’il n’y a pas assez de cellules pour couvrir la zone. Décommentez l’appel MinimalBox pour limiter la hauteur du tableau à la somme des hauteurs de ses lignes.
Le code définit trois colonnes et ajoute 10 cellules au tableau. Le tableau place les cellules les unes après les autres, en ajoutant une nouvelle ligne si nécessaire. Il est tout à fait acceptable qu’une ligne ne contienne qu’une seule cellule.
Le tableau placera des cellules sur la page suivante si la page courante n’a pas assez d’espace. Vous pouvez l’observer en augmentant le nombre de cellules ajoutées.
Cellules
Laissez-moi expliquer ce que Layout API fournit pour travailler avec des cellules de tableau.
Position
Il existe deux façons de créer une cellule de tableau :
- sans information de position explicite
- avec une position au moins partiellement spécifiée
J’ai utilisé la première méthode dans le code de la section précédente. Vous appelez la surcharge de la méthode Cell qui n’accepte aucun paramètre. La méthode ajoute une nouvelle cellule dans la colonne située après la dernière cellule ajoutée. S’il n’y a pas de place à droite, la cellule passe à la ligne suivante. En mode RTL, la méthode vérifie l’espace à gauche de la dernière cellule ajoutée.
Si vous connaissez la position exacte de la nouvelle cellule, utilisez l’autre surcharge de la méthode Cell. Celle qui accepte un délégué de type Action<TableCell>. Dans le code du délégué, spécifiez la ligne et l’index de la cellule en appelant les méthodes RowIndex et ColumnIndex de l’objet fourni.
Il est possible de spécifier uniquement un indice de ligne ou de colonne pour la nouvelle cellule. L’indice de colonne vaut 0 lorsque vous ne spécifiez qu’un indice de ligne. Et inversement.
Lors de la création des cellules, vous pouvez mélanger les appels aux deux surcharges de Cell dans n’importe quel ordre.
J’utiliserai la méthode d’extension suivante extension method dans les prochains exemples de code de cet article. Cela devrait rendre les exemples plus concis et plus faciles à lire.
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);
}
Voici un exemple qui crée un tableau avec des cellules placées à la fois explicitement et implicitement. J’ai utilisé la méthode d’extension pour appliquer un style et du texte aux cellules. Les nombres dans les cellules reflètent l’ordre de création des cellules.
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");
});
});
});
Vous pouvez voir le résultat du code dans table-cells.pdf.
Étendues sur plusieurs lignes et colonnes
Les cellules peuvent s’étendre sur plusieurs lignes et/ou plusieurs colonnes. Utilisez la surcharge de Cell qui accepte un délégué pour spécifier le nombre de lignes et de colonnes couvertes par la cellule.
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");
});
});
});
Vous pouvez voir le résultat du code dans table-cellspans.pdf.
Chevauchement
Il est possible que des cellules se recouvrent. Quand cela se produit, l’ordre de création détermine quelle cellule sera affichée au-dessus de l’autre.
Vous pouvez obtenir des cellules qui se chevauchent lorsque vos cellules s’étendent sur plusieurs colonnes ou lignes. Ou lorsque vous positionnez des cellules à la fois explicitement et implicitement.
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);
});
});
});
Vous pouvez voir le résultat du code dans table-overlapping.pdf.
Extension jusqu’en bas
Si la mise en page de votre tableau est complexe, le mécanisme de pagination peut laisser un espace vide en bas de certaines colonnes. Utilisez la méthode ExtendCellsToBottom si vous voulez supprimer cet espace vide. La méthode étend la dernière cellule de chaque colonne afin que les cellules se terminent en bas du tableau.
Dans l’exemple suivant, la première page montre le comportement par défaut. La deuxième page montre comment l’appel à ExtendCellsToBottom affecte les colonnes.
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");
});
});
}
});
Vous pouvez voir le résultat du code dans table-extendcells.pdf.
En-tête et pied de page
Les tableaux peuvent avoir un en-tête et un pied de page. Utilisez les méthodes Header et Footer pour accéder au TableCellContainer correspondant et le configurer. Le conteneur fournit les méthodes Cell pour créer des cellules. Ces méthodes fonctionnent exactement comme celles du contenu principal du tableau.
L’en-tête, le pied de page et les cellules principales du tableau utilisent la même définition de colonnes. Mais les trois collections de cellules sont indépendantes et n’ont pas d’effet les unes sur les autres.
Lorsque le tableau ne tient pas sur une page, l’en-tête et le pied de page sont répétés sur chaque page occupée par le tableau.
J’ai utilisé la méthode d’extension BoxWithText dans les exemples précédents. J’utilise aussi la méthode d’extension WhiteBoxWithText pour le code suivant.
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);
}
}
L’exemple suivant montre comment créer un tableau avec un en-tête. J’utilise un tableau avec cinq éléments chimiques essentiels. Pour chaque élément, il y a le nom et le point de fusion en degrés Celsius et Kelvin.
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));
}
});
});
});
Vous pouvez voir le résultat du code dans table-header.pdf.
Exemple de code
Prenez le temps de consulter l’exemple Ajouter des tableaux aux documents PDF. Il montre aussi comment créer des tableaux avec des en-têtes, mais n’utilise aucune méthode d’extension. Il existe aussi une version VB.NET.