Esta página puede contener texto traducido automáticamente.
Cómo diseñar páginas PDF
El método PdfDocumentBuilder.Generate proporciona un objeto de tipo Document a su delegado. Use el método Pages de ese objeto para construir las páginas de su documento. Debe proporcionar un delegado que acepte un parámetro de tipo PageLayout al método.

Una sola llamada al método basta si todas las páginas de su documento PDF tienen el mismo diseño. Si tiene diseños diferentes en su documento, use más de una llamada al método Pages. Por ejemplo, puede llamar al método una vez para diseñar una portada. Luego, llame al método de nuevo para describir el cuerpo del informe.
Cada llamada a Pages crea al menos una página. La página creada puede estar vacía si no se le proporciona contenido.
Este artículo forma parte de una serie sobre Layout API para la generación de PDF. Si es nuevo en la API, lea primero la parte Primeros pasos con Layout API.
Contenedores de contenido
Para describir el diseño de las páginas, use contenedores predefinidos. Yo también los llamo contenedores de contenido. Puede acceder a estos contenedores llamando a métodos de un objeto PageLayout.
Hay tres contenedores principales: Content, Header y Footer. Y dos contenedores para contenido adicional: Background y Foreground. De forma predeterminada, los cinco contenedores están vacíos y no ocupan espacio en la página. Distribuya el contenido de la página entre los contenedores según sus requisitos.
Lea el artículo Contenedores y su contenido para saber cómo diseñar sus páginas usando contenedores.
Encabezado y pie de página
No le sorprenderá saber que el contenido del encabezado y del pie de página va a los contenedores Header y Footer, respectivamente. La API repite estos contenedores encima y debajo del contenido principal en cada página generada. Layout API nunca divide el contenido del encabezado o del pie de página entre páginas. Obtendrá una LayoutException si un encabezado o un pie de página no cabe en una página.
Contenido principal
El contenido principal de la página, como imágenes, tablas y texto, va al contenedor Content. Layout API divide automáticamente ese contenido entre páginas.
El siguiente código asigna contenido de texto simple a todos los contenedores de contenido principal. El código también establece colores de fondo para los contenedores.
PdfDocumentBuilder.Create().Generate("pages-main-slots.pdf", doc => doc.Pages(pages => {
pages.Header()
.Text("This text goes to the header")
.BackgroundColor(new PdfRgbColor(66, 135, 245));
pages.Content()
.Text("The main content goes in this slot")
.BackgroundColor(new PdfRgbColor(242, 233, 206));
pages.Footer()
.Text("This is the footer contents")
.BackgroundColor(new PdfRgbColor(194, 192, 188));
}));
Compruebe el resultado del código en pages-main-slots.pdf.
Como puede ver, cada contenedor ocupa solo una parte de la página. El área exacta depende del contenido dentro del contenedor. El contenedor Header se adhiere a la parte superior de la página. El contenedor Content comienza inmediatamente después de Header. El contenedor Footer se adhiere a la parte inferior.
Contenido adicional
Background y Foreground proporcionan contenedores que pueden usarse para marcas de agua, superposiciones y fondos. Todo el contenido del contenedor Background va debajo del encabezado, el pie de página y el contenido principal de una página. El contenido del contenedor Foreground cubre todo lo que se agrega a la página.
Estos contenedores ocupan toda la página. Esta es la característica única de estos contenedores. La API repite su contenido en cada página generada. Igual que hace con los contenedores de encabezado y pie de página.
Añadí algunas líneas al código anterior para mostrar cómo usar los contenedores Foreground y Background.
PdfDocumentBuilder.Create().Generate("pages-all-slots.pdf", doc => doc.Pages(pages => {
// ...
pages.Background()
.Background(new PdfRgbColor(208, 227, 204));
pages.Foreground()
.Rotate(45)
.Text(new string(' ', 30) + "Your watermark could go here, in the foreground");
}));
Para el contenedor Background, no proporciono ningún texto ni nada. Solo especifico un color de fondo. Todo lo que esté debajo del encabezado, el contenido principal y el pie de página mostrará ese tono de verde.
Roto el contenido del contenedor Foreground y le añado algo de texto. Debido a los espacios iniciales, el texto no cubre el contenido del encabezado ni del pie de página. El contenido en todos los contenedores es visible en la página.
Puede ver el resultado del código en pages-all-slots.pdf.
Configuración
Hasta ahora, todos los fragmentos de código se han centrado en los contenedores que forman las páginas. Es hora de ver cómo puede personalizar las propias páginas, en lugar de sus ranuras de contenido.
Para configurar páginas, use métodos de la clase PageLayout. Recuerde que un objeto PageLayout puede describir más de una página. Las llamadas a métodos afectarán a todas las páginas que describa.
Tamaño
Probablemente, la configuración más básica es el tamaño de página. Puede usar el método Size para especificar uno de los tamaños predefinidos para sus páginas. Están todos los tamaños habituales como A4, Ledger o Monarch Envelope.
Opcionalmente, puede especificar una orientación para las páginas. Es posible establecer un tamaño personalizado para las páginas proporcionando su ancho y alto en puntos.
Márgenes
Los márgenes de página pueden contribuir a la legibilidad, la estética y la composición general de sus páginas.
Establezca todos los márgenes al mismo valor en puntos usando el método Margin. Use los métodos MarginVertical y MarginHorizontal para establecer solo márgenes verticales u horizontales. Use los métodos MarginLeft/Top/Right/Bottom para especificar cada margen de forma independiente.
Estilo de texto
Layout API proporciona la clase TextStyle para crear estilos de texto. Usted crea y aplica estilos al texto para lograr la apariencia deseada.
Hay casos en los que una gran parte del texto de sus páginas usa el mismo estilo. Puede establecer ese estilo como el estilo de texto predeterminado para las páginas. El estilo predeterminado afecta a todo el texto en los contenedores de contenido principal. Pero puede reemplazar el estilo predeterminado para ciertos elementos. Solo aplique otro estilo a fragmentos de texto que deban verse diferentes.
PdfDocumentBuilder.Create().Generate("pages-text-styles.pdf", doc =>
{
var defaultStyle = TextStyle.Parent.FontSize(30);
var tightSpacing = TextStyle.Parent.LetterSpacing(-0.1);
doc.Pages(pages =>
{
pages.TextStyle(defaultStyle);
pages.Content().Text(t =>
{
t.Line("This line uses the default text style.");
t.Line("This line uses a tight letter spacing.").Style(tightSpacing);
t.Line("This line uses the default text style, again.");
});
});
});
Puede ver el resultado del código en pages-text-styles.pdf.
Tenga en cuenta que puede configurar estilos de texto para todo el documento usando el método Document.Typography. Cada propiedad de la clase Typography define un estilo para un caso de uso. Estos estilos reemplazan el estilo especificado por el método PageLayout.TextStyle. Por ejemplo, la propiedad Typography.Body reemplaza el estilo predeterminado para el texto en los contenedores Content.
Dirección del contenido
Hay idiomas que se escriben de derecha a izquierda. Layout API maneja el texto en estos idiomas sin problema. Pero tendría que especificar explícitamente la dirección del texto.
Si la mayor parte del texto de sus páginas está en un idioma RTL, puede establecer de derecha a izquierda como la dirección de contenido predeterminada para las páginas. Podrá especificar una dirección distinta para cualquier contenedor de sus páginas.
PdfDocumentBuilder.Create().Generate("pages-content-direction.pdf", doc =>
{
var defaultTextStyle = doc.TextStyleWithFont(SystemFont.Family("Calibri"));
doc.Pages(pages =>
{
pages.Size(PdfPaperSize.A6).TextStyle(defaultTextStyle);
pages.ContentFromRightToLeft();
pages.Content().Column(column =>
{
column.Item()
.ContentFromLeftToRight()
.Text("There are languages written from right to left.");
column.Item()
.Text("هناك لغات تكتب من اليمين إلى اليسار.");
column.Item()
.Text("יש שפות שנכתבות מימין לשמאל.");
});
});
});
En el código anterior, establecí de derecha a izquierda como la dirección de contenido predeterminada. Para el contenedor con la versión en inglés de la frase, cambio la dirección a de izquierda a derecha. Puede ver el resultado del código en pages-content-direction.pdf.
Números de página
Al generar PDF, Layout API calcula automáticamente el número de página actual. También calcula el número total de páginas del documento. Puede obtener los números llamando a los métodos CurrentPageNumber y PageCount de cualquier contenedor de texto. No importa si el contenedor está en el encabezado, el pie de página o el contenido principal.
PdfDocumentBuilder.Create().Generate("pages-page-numbers.pdf", doc => doc.Pages(pages =>
{
pages.Content().Text(t =>
{
t.Span("This line is on page ");
t.CurrentPageNumber();
t.Line();
t.Line("Check the footer.");
});
pages.Footer().Row(r =>
{
r.AutoItem().Text("Created with Docotic.Pdf Layout API");
r.RelativeItem(2).Text(t =>
{
t.AlignRight();
t.Span("Page ");
t.CurrentPageNumber();
t.Span(" of ");
t.PageCount();
});
});
}));
El resultado del código está en pages-page-numbers.pdf.
Ambos métodos devuelven una instancia de TextPageNumber que puede usar para dar formato a los números.
Agregar encabezado y pie de página a documentos PDF muestra cómo aplicar un formato personalizado a los números de página.
Código de muestra
Tenemos algunas aplicaciones de ejemplo que cubren las características mencionadas con más detalle. Dedique algo de tiempo a revisarlas.