Cette page peut contenir du texte traduit automatiquement.

Taille, position et rendu des conteneurs

Le contenu est la partie la plus importante d'un document. Il n'y aucun doute à propos de ça. Un autre élément crucial est le formatage qui crée une communication claire, professionnelle et efficace. Un document correctement formaté est visuellement attrayant, lisible et facile à parcourir.

Vous savez peut-être déjà comment organiser le contenu à l'aide de conteneurs. Et comment leur appliquer une couleur de fond. Cet article explique comment spécifier la taille et la position des conteneurs. Il couvre également des fonctionnalités avancées telles que le rendu conditionnel du contenu. Il existe des informations sur la prise en charge des directions de contenu de droite à gauche.

Positionnement des conteneurs

La classe LayoutContainer fournit tout ce dont vous avez besoin pour organiser vos conteneurs de manière professionnelle. En appliquant un remplissage et un alignement, vous pouvez créer un document qui laisse une impression positive à ses utilisateurs.

Cet article fait partie d'une série sur l'API Layout pour la génération de PDF. Si vous débutez avec l'API, lisez d'abord la partie Mise en route avec l'API Layout.

Bibliothèque Docotic.Pdf 9.5.17615-dev Module complémentaire de mise en page 9.5.17615-dev
Tests de régression 14,813 réussis Téléchargements totaux de NuGet 4,924,084

Taille

Par défaut, les conteneurs occupent la plus petite surface nécessaire à leur contenu. En d’autres termes, la taille du conteneur est égale à la taille intrinsèque de son contenu.

La taille intrinsèque d'une image déterminée par les dimensions du fichier image lui-même. La taille intrinsèque d’une étendue de texte est la taille de la zone qui couvre tous les glyphes de l’étendue.

La taille d'un conteneur composé comme Column ou Table dépend de la taille des parties du conteneur.

Width & Height

Il est possible de spécifier la largeur et la hauteur exactes d'un conteneur en utilisant les méthodes Width et Height. Ceci est très pratique pour les conteneurs fictifs.

Une taille exacte fonctionne également bien pour les images. En effet, l'API Layout les met à l'échelle pour s'adapter ou remplir le conteneur en fonction de leur ImageContentMode.

Vous devez faire attention aux tailles exactes des conteneurs composés et des conteneurs avec texte. Vous obtiendrez une LayoutException lorsqu'il n'est pas possible d'adapter un contenu à la taille fournie.

Il existe des cas où vous souhaitez uniquement définir une contrainte de largeur ou de hauteur. Vous pouvez définir des contraintes en utilisant les méthodes MinWidth, MinHeight, MaxWidth et MaxHeight.

Veuillez noter que la bibliothèque lancera une LayoutException lorsqu'il n'est pas possible de satisfaire les contraintes.

Extend

Un conteneur peut s'étendre pour occuper le maximum d'espace disponible. Cela s'avère pratique lorsque vous ne connaissez pas la taille exacte ou les contraintes de taille.

Utilisez la méthode ExtendHorizontal lorsque vous souhaitez que le conteneur occupe tout l'espace disponible dans la direction horizontale uniquement. ExtendVertical est utile lorsque vous souhaitez étendre le conteneur dans la direction verticale uniquement. La méthode Extend fait que le conteneur occupe tout l'espace disponible dans les deux sens.

var gray = new PdfGrayColor(75);
var text = "Content goes here";
var size = new PdfSize(150, 50);

PdfDocumentBuilder.Create().Generate("positioning-extend.pdf", doc =>
{
    for (int i = 0; i < 4; i++)
    {
        doc.Pages(page =>
        {
            page.Size(size);
            page.Content().Row(r =>
            {
                var container = r.AutoItem().Background(gray);
                switch (i)
                {
                    case 0:
                        container.Text(text);
                        break;

                    case 1:
                        container.ExtendHorizontal().Text(text);
                        break;

                    case 2:
                        container.ExtendVertical().Text(text);
                        break;

                    case 3:
                        container.Extend().Text(text);
                        break;
                }
            });
        });
    }
});

Le résultat du code ci-dessus se trouve dans positioning-extend.pdf. Comme vous pouvez le constater, chacune des quatre pages contient le même texte sur fond gris. Mais la taille du conteneur est différente à chaque page.

MinimalBox

LayoutContainer fournit la méthode MinimalBox. C'est un peu à l'opposé des méthodes Extend. MinimalBox produit des conteneurs imbriqués qui n'utilisent que le minimum d'espace nécessaire pour le contenu.

var gray = new PdfGrayColor(75);
var size = new PdfSize(150, 50);

PdfDocumentBuilder.Create().Generate("positioning-minimalbox.pdf", doc =>
{
    doc.Pages(page =>
    {
        page.Size(size);
        page.Content().MinimalBox().Background(gray).Text("I don't want more space");
    });

    doc.Pages(page =>
    {
        page.Size(size);
        page.Content().Background(gray).Text("I'll take everything");
    });
});

Le résultat du code ci-dessus se trouve dans positioning-minimalbox.pdf. En raison de l'appel à MinimalBox, le texte de la première page occupe uniquement l'espace requis. Sur la deuxième page, le texte couvre toute la page.

Scale

Il est possible de mettre à l'échelle n'importe quel contenu dans un conteneur. La méthode Scale affecte le contenu dans les directions horizontale et verticale. Utilisez la méthode ScaleHorizontal ou ScaleVertical pour modifier le contenu dans une seule direction. Les deux dernières méthodes ne préservent pas les proportions du contenu.

Les valeurs d'échelle inférieures à 1 réduisent la surface occupée par un conteneur. Les valeurs supérieures à 1 augmentent la surface. Pour retourner le contenu d'un conteneur, utilisez une valeur d'échelle négative. Par exemple, ScaleVertical(-1) donne une version inversée du contenu original.

PdfDocumentBuilder.Create().Generate("positioning-scale.pdf", doc =>
{
    doc.Pages(page =>
    {
        page.Content()
            .MinimalBox()
            .Column(column =>
            {
                var scales = new[] { 0.5f, 0.75f, 1, 1.3f, 1.5f };

                foreach (var scale in scales)
                {
                    var percent = (int)(scale * 100);
                    column.Item()
                        .Scale(scale)
                        .Text(FormattableString.Invariant($"Scale equals {scale} ({percent}%)."))
                            .FontSize(20);

                    column.Item().LineHorizontal(0.5);
                }
            });
    });
});

Le résultat du code ci-dessus est dans positioning-scale.pdf.

ScaleToFit

Vous pouvez réduire le contenu pour l'adapter à un espace disponible. Par exemple, lorsque vous disposez d'une zone fixe pour afficher le nom ou l'adresse d'une personne. Bien entendu, vous pouvez augmenter la zone en cas de nom plus long. Mais une approche plus simple pourrait consister à réduire un peu le texte. Utilisez la méthode ScaleToFit pour réduire le contenu.

ScaleToFit préserve les proportions du contenu. La méthode n’agrandit jamais le contenu. Veuillez noter que cette méthode effectue des calculs itératifs. Cela pourrait ralentir le processus de génération de PDF.

PdfDocumentBuilder.Create().Generate("positioning-scaletofit.pdf", doc =>
{
    doc.Pages(page =>
    {
        page.Content().Column(column =>
        {
            for (int i = 0; i < 5; i++)
            {
                column.Item()
                    .Width(230 - 20 * i)
                    .Height(20)
                    .ScaleToFit()
                    .Border(b => b.Thickness(0.5))
                    .Text(" This text should fit into the changing width.");
            }
        });
    });
});

Le résultat du code ci-dessus est dans positioning-scaletofit.pdf.

AspectRatio

Le rapport hauteur/largeur définit la relation proportionnelle entre la largeur et la hauteur d'un conteneur. Pour connaître les proportions d'un conteneur, divisez sa largeur par sa hauteur.

Utilisez la méthode AspectRatio pour spécifier le rapport hauteur/largeur d'un conteneur. Cela est utile lorsque vous concevez un conteneur réutilisable pour différentes mises en page ou tailles de page.

PdfDocumentBuilder.Create().Generate("positioning-aspectratio.pdf", doc =>
{
    var ratios = new double[] { 0.25, 0.5, 1, 2 };
    foreach (var ratio in ratios)
    {
        var ratioText = ratio.ToString(CultureInfo.InvariantCulture);
        doc.Pages(page =>
        {
            page.Size(200, 200);
            page.Content().Column(column =>
            {
                column.Item()
                    .AspectRatio(ratio)
                    .Background(new PdfGrayColor(75))
                    .Text($"Width / Heigth = {ratioText}");
            });
        });
    }
});

Le résultat du code ci-dessus est dans positioning-aspectratio.pdf.

La méthode a le paramètre facultatif de type AspectRatioMode. Utilisez ce paramètre pour spécifier comment redimensionner le contenu tout en préservant les proportions.

Un conteneur avec un rapport hauteur/largeur spécifié prend autant de place que possible. Selon le mode, le conteneur tentera d'occuper toute la surface disponible (par défaut), la largeur ou la hauteur.

Veuillez noter que la bibliothèque peut lancer une LayoutException. Cela se produit lorsqu'il ne peut pas satisfaire aux exigences de taille, de rapport hauteur/largeur et de mode de rapport hauteur/largeur.

Unconstrained

Les conteneurs ne peuvent avoir aucune contrainte de taille. Utilisez la méthode Unconstrained pour supprimer toutes les contraintes de taille d'un conteneur.

Le contenu d'un conteneur sans contrainte occupe un espace dont la taille est égale à la taille intrinsèque du contenu. Le conteneur sans contrainte lui-même n'occupe aucun espace. Par conséquent, les conteneurs frères peuvent couvrir le contenu du conteneur sans contrainte.

PdfDocumentBuilder.Create().Generate("positioning-unconstrained.pdf", doc =>
{
    doc.Pages(page =>
    {
        page.Content().MinimalBox()
            .Border(b => b.Thickness(0.5))
            .Column(column =>
            {
                column.Item().Text("First item");

                column.Item().Unconstrained()
                    .Text("Second item ignores all size constraints");

                // en utilisant une ligne vide pour le troisième élément
                column.Item().Text(new string(' ', 20))
                    .BackgroundColor(new PdfRgbColor(187, 237, 237), 50);

                column.Item().Text("Fourth item");
            });
    });
});

Le résultat du code ci-dessus se trouve dans positioning-unconstrained.pdf. Dans le code, j'ai utilisé une ligne d'espaces avec un fond semi-transparent pour le troisième élément de la colonne. Comme vous pouvez le constater, le troisième élément couvre partiellement le deuxième élément (sans contrainte).

Position

La position d'un conteneur dépend d'un certain nombre de choses. Certains d'entre eux concernent l'alignement, le remplissage, la position du conteneur parent et la direction du contenu. Par défaut, tout conteneur reste à la position disponible la plus à gauche et la plus haute.

Padding

L'une des exigences les plus courantes consiste à ajouter de l'espace autour du contenu du conteneur. LayoutContainer fournit un ensemble de méthodes pour configurer la zone de remplissage d'un conteneur. La zone de remplissage est l'espace entre son contenu et sa bordure. En d’autres termes, le remplissage représente l’espace intérieur entourant le contenu.

La méthode Padding définit le remplissage sur les quatre côtés d'un conteneur à la fois. Utilisez la méthode PaddingHorizontal pour spécifier le remplissage uniquement sur les côtés gauche et droit. PaddingVertical fait la même chose sur les côtés supérieur et inférieur uniquement. Pour configurer le remplissage individuellement sur un côté, utilisez l'une des méthodes PaddingTop/Bottom/Left/Right.

Align

Pour changer la position d'un conteneur, utilisez les méthodes d'alignement. Les méthodes AlignLeft/AlignCenter/AlignRight appliquent un alignement horizontal et renvoient un conteneur imbriqué. Les méthodes AlignTop/AlignMiddle/AlignBottom renvoient un conteneur imbriqué avec un alignement vertical correspondant.

Un conteneur avec un alignement explicitement appliqué prend la zone avec la largeur et/ou la hauteur minimale requise. Le code suivant crée une colonne avec deux éléments. Un élément a explicitement appliqué l’alignement.

PdfDocumentBuilder.Create().Generate("positioning-alignment.pdf", doc =>
{
    var color = new PdfRgbColor(187, 237, 237);
    var text = "Hello";
    doc.Pages(page =>
    {
        page.Size(200, 100);
        page.Content().Column(c =>
        {
            c.Item().Extend().Background(color).Text(text);
            c.Item().Extend().AlignLeft().Background(color).Text(text);
        });
    });
});

L'appel Extend fait que les deux éléments occupent toute la page. J'appelle la méthode AlignLeft sur le deuxième élément. Cet appel ne modifie pas la position car le conteneur de l'élément aligne le texte à gauche par défaut. Mais l'alignement explicitement appliqué modifie la zone occupée par le deuxième élément.

Le résultat du code ci-dessus est dans positioning-alignment.pdf.

Translate

Pour repositionner un conteneur horizontalement et/ou verticalement, utilisez les méthodes Translate/TranslateX/TranslateY. Le premier déplace les conteneurs horizontalement et verticalement. Les deux autres déplacent les conteneurs dans une seule direction.

Toutes ces méthodes remplacent la position mais préservent les contraintes de taille. Le conteneur décalé peut chevaucher d'autres conteneurs. Utilisez des valeurs de paramètres négatives pour vous déplacer vers la gauche et/ou vers le haut. Les valeurs positives provoquent un déplacement vers la droite et/ou vers le bas.

PdfDocumentBuilder.Create().Generate("positioning-translate.pdf", doc =>
{
    doc.Pages(page =>
    {
        page.Size(200, 100);
        page.Content().Row(r =>
        {
            r.ConstantItem(50)
                .Background(new PdfRgbColor(187, 237, 237))
                .Text("Left");

            r.ConstantItem(50)
                // déplacer cet élément de 10 points vers la gauche et de 5 points plus bas
                .Translate(-10, 5)
                .Background(new PdfRgbColor(15, 130, 9))
                .Text("Right");
        });
    });
});

Le résultat du code ci-dessus est dans positioning-translate.pdf.

Rotate

Le contenu pivoté, en particulier le texte, peut améliorer vos documents de différentes manières. Par exemple, vous pouvez économiser de l'espace et rendre votre document plus attrayant et plus esthétique.

LayoutContainer propose deux approches pour faire pivoter le contenu. Quelle que soit l'approche que vous utilisez, le conteneur avec le contenu pivoté respecte les contraintes de position et de taille.

Rotation de 90 degrés

Les méthodes RotateRight et RotateLeft font pivoter le contenu de 90 degrés respectivement dans le sens des aiguilles d'une montre et dans le sens inverse.

Le code suivant montre comment créer un document avec du texte vertical à côté du contenu de la page principale.

PdfDocumentBuilder.Create().Generate("positioning-rotate.pdf", doc =>
{
    var lightGray = new PdfGrayColor(90);
    doc.Pages(page =>
    {
        page.Size(298, 210);
        page.Content().Row(r =>
        {
            r.AutoItem()
                .RotateLeft()
                .Background(lightGray)
                .Text("This content goes up");

            r.RelativeItem(1)
                .ExtendVertical()
                .PaddingHorizontal(10)
                .Column(t =>
                {
                    for (int i = 0; i < 15; i++)
                        t.Item().Text("The main content line goes here");
                });

            r.AutoItem()
                .RotateRight()
                .Background(lightGray)
                .Text("This content goes down");
        });
    });
});

Le résultat du code ci-dessus est dans positioning-rotate.pdf.

Rotation à n'importe quel angle

La méthode Rotate fait pivoter le contenu d'un nombre arbitraire de degrés. Les nombres positifs provoquent une rotation dans le sens des aiguilles d’une montre. Les nombres négatifs correspondent à une rotation dans le sens inverse des aiguilles d'une montre.

Le point d'origine de la rotation est le coin supérieur gauche du conteneur. Le contenu pivoté peut chevaucher d’autres conteneurs.

PdfDocumentBuilder.Create().Generate("positioning-rotate2.pdf", doc =>
{
    doc.Pages(page =>
    {
        page.Size(298, 210);
        page.Content()
            .Padding(25)
            .Background(new PdfGrayColor(70)) // gray
            .AlignCenter()
            .AlignMiddle()

            .Background(new PdfGrayColor(100)) // white

            .Rotate(30)

            .Width(100)
            .Height(100)
            .Background(new PdfRgbColor(187, 237, 237)); // blue
    });
});

Le résultat du code ci-dessus est dans positioning-rotate2.pdf.

Pour changer le point d'origine de la rotation, appelez l'une des méthodes Translate avant l'appel Rotate. N'oubliez pas de traduire l'origine après l'appel.

// traduire le point d'origine de la rotation
.TranslateX(50)
.TranslateY(50)

.Rotate(30)

// traduire en retour
.TranslateX(-50)
.TranslateY(-50)

Disposition conditionnelle

La mise en page de votre document PDF peut dépendre d'une condition. Par exemple, vous pouvez utiliser un alignement ou une couleur d’arrière-plan différent pour les lignes paires et impaires d’une colonne.

Utilisez la méthode Container pour insérer un conteneur imbriqué avec une disposition qui dépend d'une condition. L'appel de cette méthode ne rompra pas la chaîne d'appels.

PdfDocumentBuilder.Create().Generate("positioning-container.pdf", doc =>
{
    doc.Pages(page =>
    {
        page.Content().Column(c =>
        {
            for (int i = 0; i < 15; i++)
            {
                c.Item()
                    .TextStyle(TextStyle.Parent.FontSize(14))
                    .Container(x => i % 2 == 0 ? x.Background(new PdfGrayColor(70)) : x)
                    .Text($"Row {i + 1}");
            }
        });
    });
});

Le résultat du code ci-dessus est dans positioning-container.pdf.

DSL

Certaines parties d'un document peuvent utiliser la même mise en page. Par exemple, ils peuvent définir une bordure identique ou utiliser le même formatage. Selon le principe « ne vous répétez pas », je recommande d'extraire le code commun dans une méthode.

L'utilisation d'une méthode d'extension pour le code commun offre deux avantages :

  • Vous pouvez utiliser la méthode dans des chaînes d'appels de méthode
  • Vous pouvez avoir un nom significatif pour un ensemble d'appels de méthode

Compte tenu de ces avantages, vous pouvez créer un langage spécifique à un domaine (DSL). Avec le DSL, votre code de mise en page peut être plus court et plus facile à comprendre.

static class LayoutHelpers
{
    public static LayoutContainer NumberCell(this Table table)
        => table.Cell().Border(b => b.Thickness(0.5)).PaddingHorizontal(10);
}

PdfDocumentBuilder.Create().Generate("positioning-dsl.pdf", doc => doc.Pages(page =>
{
    page.Content().Table(t =>
    {
        t.Columns(c =>
        {
            for (int i = 0; i < 4; ++i)
                c.ConstantColumn(50);
        });

        for (int i = 0; i < 16; i++)
            t.NumberCell().Text($"{i + 1}");
    });
}));

Processus de rendu

Le module complémentaire Layout organise tout contenu que vous placez dans un conteneur en fonction de contraintes de taille et de position. Certains contenus peuvent s'étendre sur plusieurs pages. Il existe un ordre strict dans lequel le contenu est rendu. Le flux de contenu est un autre nom pour cette commande.

LayoutContainer fournit quelques méthodes pour peaufiner le flux de contenu. Vous n’en aurez peut-être pas besoin à chaque fois, mais il existe des cas où il n’existe aucun autre moyen d’obtenir la mise en page requise.

PageBreak

Lorsque vous devez démarrer un bloc de contenu à partir d'une nouvelle page, utilisez la méthode PageBreak. Par exemple, vous pouvez utiliser la méthode pour démarrer un élément Column à partir d'une nouvelle page.

Voici un exemple de code qui divise une colonne afin que chaque page ne contienne que deux lignes.

PdfDocumentBuilder.Create().Generate("positioning-pagebreak.pdf", doc => doc.Pages(page =>
{
    page.Size(200, 100);
    page.Content().Column(c =>
    {
        for (int i = 1; i <= 10; ++i)
        {
            c.Item().Text($"Item {i}");

            if (i % 2 == 0)
                c.Item().PageBreak();
        }
    });
}));

Le résultat du code ci-dessus est dans positioning-pagebreak.pdf.

ShowIf

En fonction d'une condition, vous devrez peut-être afficher/masquer un conteneur. Il existe la méthode ShowIf qui est essentiellement un sucre syntaxique pour ce cas particulier de mise en page conditionnelle.

Dans le code suivant, j'utilise la méthode ShowIf pour insérer une ligne verticale après 5 éléments consécutifs.

PdfDocumentBuilder.Create().Generate("positioning-showif.pdf", doc => doc.Pages(page =>
{
    page.Size(200, 100);
    page.Content().Row(r =>
    {
        for (int i = 0; i < 10; ++i)
        {
            r.AutoItem().Text(i.ToString());
            r.AutoItem().ShowIf(i > 0 && (i + 1) % 5 == 0).LineVertical(0.5);
        }
    });
}));

Le résultat du code ci-dessus est dans positioning-showif.pdf.

ShowOnce

Vous pouvez empêcher un élément de contenu de se répéter sur les pages suivantes. Utilisez la méthode ShowOnce pour demander au moteur de mise en page de restituer entièrement le contenu une seule fois.

Vérifiez le code suivant pour voir comment ShowOnce empêche « Environment » d'apparaître sur la deuxième page.

PdfDocumentBuilder.Create().Generate("positioning-showonce.pdf", doc => doc.Pages(page =>
{
    page.Size(200, 100);
    page.Content().Row(r =>
    {
        r.RelativeItem()
            .Background(new PdfGrayColor(75))
            .Border(b => b.Thickness(0.5))
            .Padding(5)
            .ShowOnce()
            .Text("Environment");

        r.RelativeItem()
            .Border(b => b.Thickness(0.5))
            .Padding(5)
            .Column(c =>
            {
                c.Item().Text(Environment.OSVersion.VersionString);
                c.Item().Text(string.Empty);
                c.Item().Text(
                    Environment.GetEnvironmentVariable("PROCESSOR_IDENTIFIER")
                    ?? string.Empty
                );
            });
    });
}));

Le résultat du code ci-dessus est dans positioning-showonce.pdf.

ShowEntire

Le comportement par défaut consiste à diviser le contenu entre les pages lorsqu'il ne tient pas sur une seule page. Utilisez la méthode ShowEntire pour afficher l'intégralité du conteneur sur une seule page.

Veuillez noter que la bibliothèque renvoie une LayoutException lorsqu'il n'est pas possible de faire tenir l'intégralité du contenu sur une seule page.

En raison de l'appel ShowEntire dans le code suivant, le texte du deuxième élément commence à partir de la deuxième page. Sans l'appel, il commencerait sur la première page, immédiatement après le texte du premier élément.

PdfDocumentBuilder.Create().Generate("positioning-showentire.pdf", doc => doc.Pages(page =>
{
    page.Size(100, 100);
    page.Content().Column(c =>
    {
        c.Item().Text(t =>
        {
            for (var i = 0; i < 4; i++)
                t.Line($"First item line {i + 1}");
        });

        c.Item()
            .Background(new PdfRgbColor(250, 123, 5))
            .ShowEntire()
            .Text(t =>
            {
                for (var i = 0; i < 4; i++)
                    t.Line($"Second item line {i + 1}");
            });
    });
}));

Le résultat du code ci-dessus est dans positioning-showentire.pdf.

EnsureSpace

Dans un sens, EnsureSpace est un cas particulier de la méthode ShowEntire. La différence est que EnsureSpace ne nécessite pas que le contenu entier tienne sur une page. La méthode essaie uniquement d'adapter une partie du contenu à la hauteur spécifiée. Tout le reste sera à la page suivante.

Si une zone inoccupée de la page actuelle a une hauteur inférieure à celle demandée, l'intégralité du contenu sera restituée sur une nouvelle page. Ici, la méthode produira le même résultat que la méthode ShowEntire.

StopPaging

Utilisez la méthode StopPaging pour produire une sortie sur au plus une page. L’appel de cette méthode sur un conteneur empêche sa pagination. Le module complémentaire Layout ne divisera pas le contenu de ce conteneur entre les pages. Il ne restituera aucune donnée qui ne tiendra pas sur une seule page.

L'exemple de code suivant ajoute deux ensembles de pages au document. Les deux ensembles utilisent une liste de noms de jours de la semaine comme contenu. Le premier ensemble n'a qu'une seule page, car le code appelle la méthode StopPaging pour le conteneur de contenu des pages.

PdfDocumentBuilder.Create().Generate("positioning-stoppaging.pdf", doc =>
{
    static Action<TextContainer> produceText(string heading)
    {
        var text = string.Join('\n', DateTimeFormatInfo.InvariantInfo.DayNames);
        return t =>
        {
            t.Line(heading).BackgroundColor(new PdfRgbColor(250, 123, 5));
            t.Span(text);
        };
    }

    doc.Pages(page =>
    {
        page.Size(100, 100);
        page.Content()
            .StopPaging()
            .Text(produceText("Without paging:"));
    });

    doc.Pages(page =>
    {
        page.Size(100, 100);
        page.Content()
            .Text(produceText("Default behaviour:"));
    });
});

Le résultat du code ci-dessus est dans positioning-stoppaging.pdf.

SkipOnce

Vous pouvez reporter l'apparition du contenu. Si un conteneur apparaît sur plusieurs pages, utilisez SkipOnce pour ignorer la première page et afficher le contenu sur toutes les pages à partir de la deuxième page.

Cette fonctionnalité est utile pour toutes sortes d’en-têtes, mais vous pouvez également l’utiliser avec d’autres contenus. Vérifiez le code suivant pour voir comment SkipOnce empêche l'en-tête d'apparaître sur la première page.

PdfDocumentBuilder.Create().Generate("positioning-skiponce.pdf", doc => doc.Pages(page =>
{
    page.Size(298, 210);

    page.Header()
        .SkipOnce()
        .Text("This header will appear starting from page 2")
        .Style(TextStyle.Parent.Underline());

    page.Content().Column(c =>
    {
        for (int i = 0; i < 5; i++)
        {
            if (i > 0)
                c.Item().PageBreak();

            c.Item().Text($"Page {i + 1}");
        }
    });
}));

Le résultat du code ci-dessus est dans positioning-skiponce.pdf.

Orientation du contenu

La direction du contenu par défaut est de gauche à droite. Les conteneurs alignent leur texte et autres contenus vers la gauche.

Mais il existe des langues qui s'écrivent de droite à gauche (par exemple l'arabe et l'hébreu). Lors de la création de contenu dans ces langues, utilisez la méthode ContentFromRightToLeft. Un appel à celui-ci fera basculer la direction du contenu du conteneur de droite à gauche. La méthode changera également l’alignement par défaut.

Si la plupart du contenu de vos pages est dans une langue RTL, vous pouvez définir la direction de droite à gauche comme direction de contenu par défaut pour les pages. Utilisez la méthode PageLayout.ContentFromRightToLeft pour cela. Ensuite, pour remplacer la direction du contenu par défaut pour les conteneurs sélectionnés, utilisez la méthode ContentFromLeftToRight.

Veuillez noter que la direction du contenu n'affecte pas l'alignement explicitement spécifié. Par exemple, le contenu aligné à droite restera sur le côté droit, quelle que soit la direction du contenu que vous définissez pour son conteneur. L'ordre visuel des éléments enfants sera différent selon la direction du contenu.