Questa pagina può contenere testo tradotto automaticamente.

Dimensioni, posizione e rendering dei contenitori

Il contenuto è la parte più importante di un documento. Non ci sono dubbi a riguardo. Un'altra parte cruciale è la formattazione che crea una comunicazione chiara, professionale ed efficace. Un documento formattato correttamente è visivamente accattivante, leggibile e facile da navigare.

Potresti già sapere come organizzare i contenuti utilizzando i contenitori. E come applicare loro un colore di sfondo. In questo articolo viene descritto come specificare la dimensione e la posizione dei contenitori. Copre anche funzionalità avanzate come il rendering condizionale dei contenuti. Sono disponibili informazioni sul supporto per le indicazioni dei contenuti da destra a sinistra.

Posizionamento dei contenitori

La classe LayoutContainer fornisce tutto il necessario per organizzare i tuoi contenitori in modo professionale. Applicando la spaziatura e l'allineamento, puoi creare un documento che lasci un'impressione positiva ai suoi utenti.

Questo articolo fa parte di una serie sull'API Layout per la generazione di PDF. Se sei nuovo all'API, leggi prima la parte Introduzione all'API Layout.

Libreria Docotic.Pdf 9.4.17467-dev Componente aggiuntivo di layout 9.4.17467-dev
Test di regressione Ne sono passati 14,760 Download totali di NuGet 4,415,970

Misurare

Per impostazione predefinita, i contenitori occupano l'area più piccola richiesta per il loro contenuto. In altre parole, la dimensione del contenitore è pari alla dimensione intrinseca del suo contenuto.

La dimensione intrinseca di un'immagine determinata dalle dimensioni del file immagine stesso. La dimensione intrinseca di un intervallo di testo è la dimensione dell'area che copre tutti i glifi nell'intervallo.

La dimensione di un contenitore composto come Column o Table dipende dalla dimensione delle parti del contenitore.

Width & Height

È possibile specificare la larghezza e l'altezza esatte di un contenitore utilizzando i metodi Width e Height. Questo è molto comodo per i contenitori segnaposto.

Una dimensione esatta funziona bene anche per le immagini. Questo perché l'API Layout li ridimensiona per adattarli o riempire il contenitore in base al loro ImageContentMode.

Dovresti fare attenzione alle dimensioni esatte dei contenitori composti e dei contenitori con testo. Riceverai una LayoutException quando non è possibile adattare un contenuto alla dimensione fornita.

Ci sono casi in cui desideri impostare solo un vincolo sulla larghezza o sull'altezza. Puoi impostare vincoli utilizzando i metodi MinWidth, MinHeight, MaxWidth e MaxHeight.

Tieni presente che la libreria lancerà una LayoutException quando non è possibile soddisfare i vincoli.

Extend

Un contenitore può estendersi per occupare il massimo spazio disponibile. Ciò è utile quando non si conoscono le dimensioni esatte o i limiti di dimensione.

Utilizza il metodo ExtendHorizontal quando vuoi che il contenitore occupi tutto lo spazio disponibile solo nella direzione orizzontale. ExtendVertical è utile quando desideri estendere il contenitore solo nella direzione verticale. Il metodo Extend fa sì che il contenitore occupi tutto lo spazio disponibile in entrambe le direzioni.

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;
                }
            });
        });
    }
});

Il risultato del codice sopra è in position-extend.pdf. Come puoi vedere, ciascuna delle quattro pagine contiene lo stesso testo su sfondo grigio. Ma la dimensione del contenitore è diversa in ogni pagina.

MinimalBox

LayoutContainer fornisce il metodo MinimalBox. È un po' l'opposto dei metodi Extend. MinimalBox produce contenitori nidificati che utilizzano solo lo spazio minimo necessario per il contenuto.

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");
    });
});

Il risultato del codice sopra è in posizionamento-minimalbox.pdf. A causa della chiamata MinimalBox, il testo sulla prima pagina occupa solo lo spazio richiesto. Nella seconda pagina il testo occupa l'intera pagina.

Scale

È possibile ridimensionare qualsiasi contenuto in un contenitore. Il metodo Scale influisce sul contenuto sia in direzione orizzontale che verticale. Utilizza il metodo ScaleHorizontal o ScaleVertical per modificare il contenuto in una sola direzione. Gli ultimi due metodi non preservano le proporzioni del contenuto.

Valori di scala inferiori a 1 riducono l'area occupata da un contenitore. Valori maggiori di 1 aumentano l'area. Per capovolgere il contenuto in un contenitore, utilizzare un valore di scala negativo. Ad esempio, ScaleVertical(-1) restituisce una versione capovolta del contenuto originale.

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);
                }
            });
    });
});

Il risultato del codice sopra è in position-scale.pdf.

ScaleToFit

È possibile ridimensionare il contenuto per adattarlo allo spazio disponibile. Ad esempio, quando si dispone di un'area fissa per l'output del nome o dell'indirizzo di una persona. Naturalmente è possibile aumentare l'area in caso di nome più lungo. Ma un approccio più semplice potrebbe essere quello di ridimensionare leggermente il testo. Utilizza il metodo ScaleToFit per ridimensionare il contenuto.

ScaleToFit preserva le proporzioni del contenuto. Il metodo non ingrandisce mai il contenuto. Tieni presente che questo metodo esegue calcoli iterativi. Ciò potrebbe rallentare il processo di generazione del 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.");
            }
        });
    });
});

Il risultato del codice sopra è in positioning-scaletofit.pdf.

AspectRatio

Le proporzioni definiscono la relazione proporzionale tra la larghezza e l'altezza di un contenitore. Per scoprire le proporzioni di un contenitore, dividi la sua larghezza per la sua altezza.

Utilizza il metodo AspectRatio per specificare le proporzioni di un contenitore. È utile quando progetti un contenitore riutilizzabile per layout o dimensioni di pagina diversi.

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}");
            });
        });
    }
});

Il risultato del codice sopra è in positioning-aspectratio.pdf.

Il metodo ha il parametro facoltativo di tipo AspectRatioMode. Utilizza questo parametro per specificare come ridimensionare il contenuto preservando le proporzioni.

Un contenitore con proporzioni specificate occupa quanto più spazio possibile. A seconda della modalità, il contenitore proverà ad occupare l'intera area disponibile (impostazione predefinita), larghezza o altezza.

Tieni presente che la libreria può lanciare una LayoutException. Succede quando non è possibile soddisfare i requisiti di dimensioni, proporzioni e modalità proporzioni.

Unconstrained

I contenitori non possono avere alcun vincolo di dimensione. Utilizza il metodo Unconstrained per rimuovere tutti i vincoli di dimensione da un contenitore.

Il contenuto in un contenitore non vincolato occupa uno spazio con dimensioni pari alla dimensione intrinseca del contenuto. Il contenitore non vincolato in sé non occupa spazio. Di conseguenza, i contenitori fratelli possono coprire il contenuto del contenitore non vincolato.

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");

                // utilizzando una riga vuota per il terzo elemento
                column.Item().Text(new string(' ', 20))
                    .BackgroundColor(new PdfRgbColor(187, 237, 237), 50);

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

Il risultato del codice sopra è in posizionamento-unconstrained.pdf. Nel codice ho utilizzato una riga di spazi con uno sfondo semitrasparente per il terzo elemento della colonna. Come puoi vedere, il terzo elemento copre parzialmente il secondo elemento (non vincolato).

Posizione

La posizione di un contenitore dipende da una serie di cose. Alcuni di essi sono l'allineamento, il riempimento, la posizione del contenitore principale e la direzione del contenuto. Per impostazione predefinita, qualsiasi contenitore rimane nella posizione disponibile più a sinistra e più in alto.

Padding

Uno dei requisiti più comuni è aggiungere spazio attorno al contenuto del contenitore. LayoutContainer fornisce una serie di metodi per impostare l'area di riempimento di un contenitore. L'area di riempimento è lo spazio tra il suo contenuto e il suo bordo. In altre parole, il riempimento rappresenta lo spazio interno che circonda il contenuto.

Il metodo Padding imposta il riempimento su tutti e quattro i lati di un contenitore contemporaneamente. Utilizza il metodo PaddingHorizontal per specificare il riempimento solo sui lati sinistro e destro. PaddingVertical fa lo stesso solo sui lati superiore e inferiore. Per impostare il riempimento individualmente su un lato, utilizza uno dei metodi PaddingTop/Bottom/Left/Right.

Align

Per modificare la posizione di un contenitore, utilizzare i metodi di allineamento. I metodi AlignLeft/AlignCenter/AlignRight applicano un allineamento orizzontale e restituiscono un contenitore nidificato. I metodi AlignTop/AlignMiddle/AlignBottom restituiscono un contenitore nidificato con un corrispondente allineamento verticale.

Un contenitore con allineamento applicato esplicitamente occupa l'area con la larghezza e/o l'altezza minima richiesta. Il codice seguente crea una colonna con due elementi. Un elemento ha applicato esplicitamente l'allineamento.

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);
        });
    });
});

La chiamata Extend fa sì che entrambi gli elementi occupino l'intera pagina. Chiamo il metodo AlignLeft sul secondo elemento. Questa chiamata non modifica la posizione perché il contenitore dell'elemento allinea il testo a sinistra per impostazione predefinita. Ma l'allineamento applicato esplicitamente modifica l'area occupata dal secondo elemento.

Il risultato del codice sopra è in positioning-alignment.pdf.

Translate

Per riposizionare un contenitore orizzontalmente e/o verticalmente, utilizza i metodi Translate/TranslateX/TranslateY. Il primo sposta i contenitori sia orizzontalmente che verticalmente. Gli altri due spostano i contenitori solo in una direzione.

Tutti questi metodi sovrascrivono la posizione ma preservano i vincoli di dimensione. Il contenitore spostato può sovrapporsi ad altri contenitori. Utilizzare valori di parametro negativi per spostarsi a sinistra e/o in alto. Valori positivi provocano uno spostamento verso destra e/o verso il basso.

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)
                // spostando questo oggetto di 10 punti a sinistra e di 5 punti più in basso
                .Translate(-10, 5)
                .Background(new PdfRgbColor(15, 130, 9))
                .Text("Right");
        });
    });
});

Il risultato del codice sopra è in positioning-translate.pdf.

Rotate

Il contenuto ruotato, in particolare il testo, può migliorare i tuoi documenti in diversi modi. Ad esempio, puoi risparmiare spazio e rendere il tuo documento più accattivante ed esteticamente gradevole.

LayoutContainer fornisce due approcci per ruotare il contenuto. Indipendentemente dall'approccio utilizzato, il contenitore con il contenuto ruotato rispetta i vincoli di posizione e dimensione.

Ruota di 90 gradi

I metodi RotateRight e RotateLeft ruotano il contenuto di 90 gradi rispettivamente in senso orario e antiorario.

Il codice seguente mostra come creare un documento con testo verticale accanto al contenuto della pagina 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");
        });
    });
});

Il risultato del codice sopra è in positioning-rotate.pdf.

Ruota a qualsiasi angolazione

Il metodo Rotate ruota il contenuto di un numero arbitrario di gradi. I numeri positivi provocano la rotazione in senso orario. I numeri negativi indicano la rotazione in senso antiorario.

Il punto di origine della rotazione è l'angolo in alto a sinistra del contenitore. Il contenuto ruotato può sovrapporsi ad altri contenitori.

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

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

            .Rotate(30)

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

Il risultato del codice sopra è in positioning-rotate2.pdf.

Per modificare il punto di origine della rotazione, chiama uno dei metodi Translate prima della chiamata Rotate. Non dimenticare di tradurre nuovamente l'origine dopo la chiamata.

// traslare il punto di origine della rotazione
.TranslateX(50)
.TranslateY(50)

.Rotate(30)

// tradurre indietro
.TranslateX(-50)
.TranslateY(-50)

Disposizione condizionale

Il layout del documento PDF può dipendere da una condizione. Ad esempio, puoi utilizzare un allineamento o un colore di sfondo diverso per le righe pari e dispari in una colonna.

Utilizza il metodo Container per inserire un contenitore nidificato con un layout che dipende da una condizione. La chiamata a questo metodo non interromperà la catena di chiamate.

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}");
            }
        });
    });
});

Il risultato del codice sopra è in positioning-container.pdf.

DSL

Alcune parti di un documento possono utilizzare lo stesso layout. Ad esempio, possono impostare lo stesso bordo o utilizzare la stessa formattazione. Secondo il principio "non ripeterti", consiglio di estrarre il codice comune in un metodo.

L'utilizzo di un metodo di estensione per il codice comune offre due vantaggi:

  • È possibile utilizzare il metodo in catene di chiamate al metodo
  • È possibile avere un nome significativo per una serie di chiamate al metodo

Considerati questi vantaggi, puoi costruire un linguaggio specifico del dominio (DSL). Con DSL, il codice di layout può essere più breve e più facile da capire.

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}");
    });
}));

Processo di rendering

Il componente aggiuntivo Layout organizza qualsiasi contenuto inserito in un contenitore in base ai vincoli di dimensione e posizione. Alcuni contenuti possono estendersi su più pagine. Esiste un ordine rigoroso in cui viene visualizzato il contenuto. Il flusso di contenuto è un altro nome per questo ordine.

LayoutContainer fornisce alcuni metodi per modificare il flusso dei contenuti. Potresti non averne bisogno ogni volta, ma ci sono casi in cui non c'è altro modo per ottenere il layout richiesto.

PageBreak

Quando è necessario iniziare un blocco di contenuto da una nuova pagina, utilizzare il metodo PageBreak. Ad esempio, puoi utilizzare il metodo per avviare un elemento Column da una nuova pagina.

Di seguito è riportato un codice di esempio che divide una colonna in modo che ogni pagina contenga solo due righe.

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();
        }
    });
}));

Il risultato del codice sopra è in positioning-pagebreak.pdf.

ShowIf

A seconda della condizione, potrebbe essere necessario mostrare/nascondere un contenitore. Esiste il metodo ShowIf che essenzialmente è uno zucchero sintattico per questo caso speciale di layout condizionale.

Nel codice seguente, utilizzo il metodo ShowIf per inserire una linea verticale dopo ogni 5 elementi di fila.

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);
        }
    });
}));

Il risultato del codice sopra è in positioning-showif.pdf.

ShowOnce

Puoi impedire che un contenuto si ripeta nelle pagine successive. Utilizza il metodo ShowOnce per indicare al motore di layout di eseguire il rendering completo del contenuto una sola volta.

Controlla il codice seguente per vedere come ShowOnce impedisce a "Environment" di apparire nella seconda pagina.

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
                );
            });
    });
}));

Il risultato del codice sopra è in positioning-showonce.pdf.

ShowEntire

Il comportamento predefinito consiste nel dividere il contenuto tra le pagine quando non rientra in una pagina. Utilizza il metodo ShowEntire per visualizzare l'intero contenitore su una pagina.

Tieni presente che la libreria lancia una LayoutException quando non è possibile adattare l'intero contenuto su una pagina.

A causa della chiamata ShowEntire nel codice seguente, il testo del secondo elemento inizia dalla seconda pagina. Senza la chiamata, inizierebbe nella prima pagina, immediatamente dopo il testo del primo elemento.

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}");
            });
    });
}));

Il risultato del codice sopra è in positioning-showentire.pdf.

EnsureSpace

In un certo senso, EnsureSpace è un caso speciale del metodo ShowEntire. La differenza è che EnsureSpace non richiede che l'intero contenuto si adatti a una pagina. Il metodo tenta solo di adattare una parte del contenuto con l'altezza specificata. Tutto il resto andrà nella pagina successiva.

Se un'area non occupata della pagina corrente ha un'altezza inferiore a quella richiesta, l'intero contenuto verrà visualizzato su una nuova pagina. In questo caso, il metodo produrrà lo stesso risultato del metodo ShowEntire.

StopPaging

Utilizza il metodo StopPaging per produrre output al massimo su una pagina. La chiamata a questo metodo su un contenitore ne impedisce il paging. Il componente aggiuntivo Layout non dividerà il contenuto di questo contenitore tra le pagine. Non visualizzerà alcun dato che non possa rientrare in una pagina.

Il seguente codice di esempio aggiunge due serie di pagine al documento. Entrambi i set utilizzano come contenuto un elenco di nomi di giorni feriali. Il primo set ha una sola pagina, perché il codice chiama il metodo StopPaging per il contenitore del contenuto delle pagine.

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:"));
    });
});

Il risultato del codice sopra è in positioning-stoppaging.pdf.

SkipOnce

Puoi posticipare la visualizzazione dei contenuti. Se un contenitore appare su più di una pagina, utilizza SkipOnce per saltare la prima pagina ed eseguire il rendering del contenuto su tutte le pagine a partire dalla seconda pagina.

Questa capacità è utile per tutti i tipi di intestazioni, ma puoi usarla anche con altri contenuti. Controlla il codice seguente per vedere come SkipOnce impedisce all'intestazione di apparire nella prima pagina.

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}");
        }
    });
}));

Il risultato del codice sopra è in positioning-skiponce.pdf.

Direzione del contenuto

La direzione predefinita del contenuto è da sinistra a destra. I contenitori allineano il testo e gli altri contenuti a sinistra.

Ma ci sono lingue scritte da destra a sinistra (ad esempio arabo ed ebraico). Quando crei contenuti in queste lingue, utilizza il metodo ContentFromRightToLeft. Una chiamata ad esso cambierà la direzione del contenuto del contenitore da destra a sinistra. Il metodo cambierà anche l'allineamento predefinito.

Se la maggior parte dei contenuti delle tue pagine è in una lingua RTL, puoi impostare da destra a sinistra come direzione predefinita dei contenuti per le pagine. Utilizza il metodo PageLayout.ContentFromRightToLeft per questo. Quindi, per sovrascrivere la direzione del contenuto predefinita per i contenitori selezionati, utilizza il metodo ContentFromLeftToRight.

Tieni presente che la direzione del contenuto non influisce sull'allineamento esplicitamente specificato. Ad esempio, il contenuto allineato a destra rimarrà sul lato destro indipendentemente dalla direzione del contenuto impostata per il suo contenitore. L'ordine visivo degli elementi secondari sarà diverso a seconda della direzione del contenuto.