Esta página puede contener texto traducido automáticamente.

Contenedores y su contenido

Un documento es un conjunto de páginas. Cada página, a su vez, es un conjunto de contenidos. Como ya sabrás, PageLayout proporciona contenedores para contenido principal y adicional. ¿Pero qué hacer con estos contenedores?

Contenedores para el contenido de la página.

Los contenedores ayudan a organizar el contenido de las páginas. Todo lo que pongas en una página debe ir a un contenedor. Si el contenido es lo suficientemente grande, un contenedor puede ocupar espacio en más de una página.

Puedes poner texto o una imagen en un contenedor. Para fines de alineación y posicionamiento, puede colocar un contenedor dentro de otro contenedor. Hay contenedores que brindan espacio para más de un contenido.

Los contenedores de una página están representados por objetos de la clase LayoutContainer. Utilice esta clase para configurar el tamaño, la posición, el contenido y el proceso de representación de sus contenedores.

Este artículo es parte de una serie sobre la API Layout para la generación de PDF. Si es nuevo en la API, lea primero la parte Introducción a la API de Layout.

Biblioteca Docotic.Pdf 9.4.17342 Complemento de diseño 9.4.17342
Pruebas de regresión 14,727 pasaron Descargas totales de NuGet 4,260,602

Cómo funcionan los contenedores

Empiece por obtener un contenedor. Por ejemplo, llamando al método PageLayout.Content. Este método devolverá un contenedor que no ocupa espacio y no tiene contenido ni propiedades establecidas. Utilice métodos de la clase LayoutContainer para configurar el contenedor.

Lo más importante que hay que entender es que todos los métodos LayoutContainer colocan contenido en el contenedor. Cuando agrega algo de texto al contenedor, se espera. Pero, ¿en qué se convierte el contenido cuando estableces una sangría o un ancho?

Cuando establece una propiedad de contenedor, la biblioteca crea un contenedor nuevo con la propiedad especificada. El nuevo contenedor se convierte en el contenido del contenedor original. La biblioteca devuelve el contenedor anidado como resultado del método.

Las propiedades de los contenedores anidados afectan a los contenedores principales y viceversa. Por ejemplo, el ancho de un contenedor anidado afecta el tamaño de los contenedores principales. El estilo de texto predeterminado de un contenedor principal afecta al texto en contenedores anidados. El complemento Layout utiliza la jerarquía de contenedores y sus propiedades para crear el diseño resultante.

El resultado del siguiente código puede sorprenderte, pero dedica algo de tiempo a analizarlo. El código ilustra cómo funcionan los contenedores anidados.

PdfDocumentBuilder.Create().Generate("containers-how.pdf", doc => doc.Pages(page =>
{
    page.Size(150, 150);
    page.Content()
        .Background(new PdfRgbColor(235, 64, 52)) // rojo

        .PaddingTop(50)
        .Background(new PdfRgbColor(187, 237, 237)) // azul

        .PaddingRight(50)
        .Background(new PdfRgbColor(15, 130, 9)) // verde

        .PaddingBottom(50)
        .Background(new PdfRgbColor(250, 123, 5)) // naranja

        .PaddingLeft(50)
        .Background(new PdfRgbColor(204, 204, 204)); // gris
}));

Decoración

El diseño de documentos implica más que organizar texto e imágenes. Un documento correctamente diseñado crea no sólo una comunicación efectiva sino también visualmente atractiva.

Con Layout API, puedes aplicar un color de fondo a cualquier contenedor. Esto ayuda a establecer una jerarquía dentro de su contenido. También puede definir límites aplicando bordes. Utilice líneas verticales y horizontales para separar los elementos del contenido.

PdfDocumentBuilder.Create().Generate("containers-decor.pdf", doc => doc.Pages(page =>
{
    page.Size(150, 150);
    page.Content()
        .Background(new PdfRgbColor(250, 123, 5))
        .Border(b =>
        {
            b.Color(new PdfGrayColor(0), 50);
            b.Thickness(15);
        })
        .PaddingTop(74)
        .LineHorizontal(2)
            .Color(new PdfCmykColor(73, 45, 0, 4))
            .DashPattern(new PdfDashPattern(new double[] { 8, 2 }));
}));

La API admite colores opacos y semitranslúcidos en espacios de color Gray, RGB y CMYK. Además de las líneas sólidas, Layout API brinda soporte para líneas que usan patrones de guiones.

El resultado del código anterior está en containers-decor.pdf.

Contenido

Veamos qué proporciona la clase LayoutContainer para organizar el contenido.

Text

Para agregar algo de texto a un contenedor, use uno de los métodos Text.

Si todo el texto usa el mismo estilo, use la versión abreviada simple del método. Esa versión acepta una cadena y devuelve un objeto TextSpan. Puede utilizar ese objeto para configurar el estilo de texto para el intervalo.

Existe otra versión del método Text que acepta un delegado de tipo Action<TextContainer>. Utilice esa versión para tener intervalos con diferentes estilos dentro de un bloque de texto. TextContainer proporciona métodos para insertar imágenes y otros elementos entre tramos de texto. Hay otras funciones avanzadas, como la posibilidad de establecer una distancia entre párrafos.

PdfDocumentBuilder.Create().Generate("containers-text.pdf", doc => doc.Pages(page =>
{
    page.Header().Text("This is a simple text span");

    page.Content().Text(t =>
    {
        t.Span("This line contains ");
        t.Span("some underlined text").Style(TextStyle.Parent.Underline());
    });
}));

Puedes ver el resultado del código en containers-text.pdf.

Image

Layout API proporciona métodos para crear objetos Image a partir de datos de imagen en un archivo o secuencia. Cualquier objeto Image puede servir como contenido de un contenedor. Puede utilizar el mismo objeto Image en varios contenedores. Hay diferentes modos de contenido que afectan el aspecto de la imagen dentro del contenedor.

La biblioteca solo puede cargar imágenes en formatos rasterizados: PNG, JPEG, JPEG 2000, BMP, GIF y TIFF.

PdfDocumentBuilder.Create().Generate("containers-image.pdf", doc =>
{
    var imageFile = new FileInfo(@"path-to-image.jpg");
    var image = doc.Image(imageFile);

    doc.Pages(pages =>
    {
        pages.Size(image.Width, image.Height);
        pages.Content().Image(image, ImageContentMode.FitArea);
    });
});

Column

Las columnas proporcionan espacio para un número ilimitado de elementos colocados verticalmente uno tras otro. Puede utilizar elementos de cualquier tipo dentro de una columna. Por ejemplo, una columna puede contener elementos de imagen y texto. El ancho de cada elemento es igual al ancho de la columna. La altura de cada elemento depende del contenido y las propiedades del elemento.

PdfDocumentBuilder.Create().Generate("containers-column.pdf", doc => doc.Pages(page =>
{
    page.Content().Column(c =>
    {
        for (int i = 0; i < 10; i++)
        {
            PdfColor color = i % 2 == 0
                ? new PdfRgbColor(187, 237, 237)
                : new PdfGrayColor(66);

            c.Item().Background(color).Height(10 + i * 3);
        }
    });
}));

Puedes ver el resultado del código en containers-column.pdf.

Row

Los contenedores Row ayudan a organizar una cantidad ilimitada de elementos horizontalmente. Cada elemento de una fila es un contenedor. Debido a esto, puedes poner contenido de diferentes tipos en una fila.

PdfDocumentBuilder.Create().Generate("containers-row.pdf", doc => doc.Pages(page =>
{
    var rowItems = new[] { "three", "two", "one" };

    page.Content().Row(row =>
    {
        for (int index = 0; index < rowItems.Length; index++)
        {
            row.AutoItem().Text(rowItems[index]);

            if (index != rowItems.Length - 1)
                row.AutoItem().PaddingHorizontal(10).LineVertical(0.5);
        }
    });
}));

Puedes ver el resultado del código en containers-row.pdf.

Table

Utilice contenedores Table para diseñar sus datos más complejos. Comience definiendo al menos una columna y luego complete las columnas y filas llamando al método Cell varias veces.

Las tablas pueden tener un encabezado y un pie de página. Las celdas de una tabla pueden abarcar más de una columna y/o fila. Aquí hay un código que agrega una tabla simple.

PdfDocumentBuilder.Create().Generate("containers-table.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.Cell()
                .Border(b => b.Thickness(0.5))
                .PaddingHorizontal(10)
                .Text($"{i + 1}");
        }
    });
}));

El resultado del código está en containers-table.pdf.

Inlined

El contenedor Inlined proporciona una manera conveniente de llenar un área con elementos de una colección de contenedores. Simplemente agrega elementos uno tras otro y la biblioteca los coloca en una fila, uno tras otro. Si no hay espacio para colocar un elemento, la biblioteca comienza una nueva fila.

Layers

Hay casos en los que es mejor colocar el contenido en varias capas. El contenedor Layers sirve exactamente para este propósito. Debe definir exactamente una capa primaria y cualquier cantidad de capas no primarias. Layout API compondrá capas en el mismo orden en que las crea.

Element

Este es un tipo especial de contenido. Puede crear un elemento dinámicamente y poner el resultado en un contenedor.

Los elementos creados dinámicamente pueden proporcionar un diseño que depende del número de página, el tamaño y otras propiedades.