Esta página puede contener texto traducido automáticamente.
Generador de PDF .NET
Con Docotic.Pdf, puedes generar documentos PDF a partir de elementos estructurales como páginas, contenedores, bloques de texto, imágenes, enlaces, encabezados, pies de página, tablas, listas y más. Estos elementos están disponibles a través de la API de alto nivel Layout, proporcionada por el complemento gratuito Layout para Docotic.Pdf. La API también admite componentes personalizados reutilizables.

La API de Layout permite definir documentos completamente en código C# o VB.NET mediante un enfoque fluido. Según esta descripción, el generador de PDF proporcionado por el complemento puede producir documentos con diseños de complejidad arbitraria, desde páginas sencillas hasta informes PDF altamente estructurados.
Conceptos básicos de generación de PDF
Para generar documentos PDF con la API de Layout, necesita el complemento gratuito Layout. También se requiere una clave de licencia para usar la biblioteca principal y los complementos. Puede usar una clave de prueba gratuita o una clave de compra.
Instala el complemento
La forma recomendada es instalar el complemento desde NuGet.
Install-Package BitMiracle.Docotic.Pdf.Layout
El gestor de paquetes se encargará automáticamente de las dependencias.
Si prefiere instalar el complemento manualmente, comience descargando el archivo ZIP con los binarios de Docotic.Pdf. Descomprima el archivo y agregue referencias a las siguientes DLL:
BitMiracle.Docotic.Pdf.dllBitMiracle.Docotic.Pdf.Layout.dllde la subcarpetaLayout add-on.
Obtén una clave de licencia
Para probar la biblioteca, solicite una clave de licencia gratuita por tiempo limitado completando el formulario en la página de descarga de Docotic.Pdf. Si ya adquirió una licencia, utilice el código que recibió tras la compra.
El complemento Layout es gratuito y no requiere una licencia adicional. Puede usar la API de Layout con la licencia de Docotic.Pdf que ya posee.
¡Hola, mundo! con la API de Layout
Aquí hay un ejemplo de código que utiliza la API para generar un PDF con la clásica frase "¡Hola, mundo!":
BitMiracle.Docotic.LicenseManager.AddLicenseData("PUT-LICENSE-HERE");
PdfDocumentBuilder.Create().Generate("hello.pdf", doc => doc.Pages(pages =>
{
pages.Content().Text("Hello, world!");
}));
Este código genera un PDF de una sola página con el texto en la esquina superior izquierda.
Comprender el ejemplo de código
El ejemplo comienza agregando una clave de licencia. Sin una licencia, la biblioteca Docotic.Pdf no generará nada. El código para generar el PDF comienza en la siguiente línea.
El código crea una instancia del generador de documentos llamando al método estático
PdfDocumentBuilder.Create(). La llamada al método Generate inicia el proceso de generación del
PDF. Este método acepta dos parámetros: el nombre del archivo a generar y un delegado de tipo
Action<Document>. El complemento genera hello.pdf como resultado de la llamada a Generate.
Para determinar el diseño del PDF, el generador de documentos llama al delegado con una instancia
de Document. El código del delegado compone el contenido del documento. En este ejemplo, el
delegado utiliza el método Pages para proporcionar al generador otro delegado que define el
diseño de las páginas del documento.
El generador llama al delegado proporcionado al método Pages con una instancia de PageLayout.
Esta instancia representa una o más páginas del documento. El número exacto de páginas depende del
contenido que se añada a cada una.
El delegado de página llama al método Content para acceder al contenedor de diseño del contenido
principal de la(s) página(s). Una llamada encadenada al método Text del contenedor añade el
fragmento de texto de ejemplo a la página. Consulte la guía sobre contenedores de
diseño para obtener una explicación detallada de su funcionamiento.
El generador de documentos divide automáticamente el contenido entre las páginas, creando exactamente las páginas necesarias para contener todos los datos añadidos al contenedor de diseño del contenido principal. En este ejemplo, una sola página es suficiente, por lo que el resultado contiene exactamente una página.
Tareas comunes más allá de la muestra básica
El código de ejemplo primero crea una instancia de PdfDocumentBuilder y luego llama al método
Generate para generar un PDF. Puede configurar el generador antes de que comience a generar el
PDF.
Por ejemplo, puede generar un PDF cifrado proporcionando un controlador de cifrado al generador. También puede especificar metadatos que el generador incluirá en el documento generado. Para obtener más detalles sobre cómo personalizar el generador, consulte el artículo correspondiente.
El código de ejemplo utiliza únicamente el contenedor de diseño del espacio de contenido principal,
pero también hay otros espacios de contenido disponibles. Aquí está la lista completa de métodos de
PageLayout para acceder a los espacios de contenido:
Background(): devuelve la capa de fondo, que queda oculta por el resto del contenido.Header(): devuelve el encabezado común para todas las páginas.Content(): devuelve el espacio de contenido principal de la página.Footer(): devuelve el pie de página común para todas las páginas.Foreground(): devuelve la capa de primer plano, que aparece por encima del resto del contenido.
Solo el contenido del espacio de contenido principal afecta al número de páginas del PDF generado.
El generador de documentos repite todos los espacios, excepto el proporcionado por Content(), en
cada página. Para obtener más información sobre los espacios de contenido, consulte el artículo
sobre diseño de página.
Muchos documentos utilizan diseños diferentes en distintas páginas. Por ejemplo, la primera página
puede tener un diseño de portada, mientras que las páginas siguientes utilizan un diseño más
sencillo. Algunos documentos incluyen páginas especiales para tablas o aplican fondos diferentes
según la sección. Para generar este tipo de documentos con Docotic.Pdf y el complemento Layout,
llame al método Document.Pages varias veces. Puede encontrar un ejemplo
práctico en nuestro repositorio de ejemplos.
Organizando el código
Para código corto, como en el ejemplo, es aceptable encadenar llamadas y usar expresiones lambda anidadas. Al desarrollar código más extenso, puede resultar más conveniente dividirlo en métodos separados. Esto facilita la lectura y el mantenimiento del código.
Así se ve el ejemplo "¡Hola, mundo!" cuando su código se divide en métodos.
public void GeneratePdf()
{
BitMiracle.Docotic.LicenseManager.AddLicenseData("PUT-LICENSE-HERE");
PdfDocumentBuilder.Create().Generate("hello.pdf", BuildDocument);
}
private void BuildDocument(Document doc)
{
doc.Pages(BuildPages);
}
private void BuildPages(PageLayout pages)
{
pages.Content().Text("Hello, world!");
}
¿Por qué generar archivos PDF con la API de diseño de Docotic.Pdf?
La API de Layout es una solución moderna y fácil de usar para desarrolladores que permite generar PDF a partir de bloques de construcción componibles, sin necesidad de comprender el funcionamiento interno del formato PDF. Genera PDF con alto rendimiento y un comportamiento determinista y predecible. Puede utilizar la API en escenarios de generación de documentos de alto volumen.
La API está disponible al usar Docotic.Pdf junto con el complemento gratuito Layout. Tanto Docotic.Pdf como el complemento Layout son DLL de código 100% administrado, sin bloques de código inseguros. La API de Layout se implementa sin dependencias externas de terceros, como navegadores o binarios de Skia, lo que resulta en una solución ligera y eficiente, fácil de implementar y mantener.
Descripción general de la API
La API de Layout es fluida y fácil de usar. Describes el diseño de tu documento completamente mediante código, utilizando elementos de diseño flexibles. El generador organiza el contenido, lo pagina automáticamente y genera el resultado como un PDF.
El complemento Layout utiliza un sistema de diseño declarativo basado en flujo. Sus elementos de diseño incluyen listas, columnas, filas, tablas, imágenes, bloques de texto, encabezados y pies de página, contenedores y más. En lugar de colocar manualmente los elementos en coordenadas exactas, describes su comportamiento. El generador de documentos calcula el diseño final y crea el PDF.
El sistema de diseño basado en flujo garantiza que el diseño se adapte al tamaño de la página y al contenido. Gracias a este sistema, el complemento destaca en diseños complejos, estructurados y basados en reglas. Puedes anidar diferentes tipos de contenedores y crear estructuras sofisticadas sin sacrificar la legibilidad.
Al trabajar con la API de Layout, puedes encadenar la mayoría de las llamadas. Esto da como resultado un código más compacto y expresivo que con las API tradicionales. El orden de las llamadas en una cadena es importante. Todo está fuertemente tipado, lo que proporciona seguridad en tiempo de compilación y facilita la refactorización del código. También puedes realizar pruebas unitarias del código que utiliza la API de Layout.
Para que tu implementación de diseño sea aún más concisa, puedes extender la API con tus propios métodos y crear un DSL limpio y expresivo a su alrededor.
Para obtener más información sobre posicionamiento y creación de DSL, consulta el artículo que explica cómo controlar el tamaño, la posición, la alineación y el comportamiento de renderizado de los contenedores.
Versiones de .NET y compatibilidad con plataformas
Puedes usar la API de Layout en proyectos que utilizan .NET Standard 2.1 y versiones posteriores. En otras palabras, el complemento de Layout es compatible con .NET 5 a .NET 10. Además, es compatible con .NET Core 3.0 y versiones posteriores.
Puedes generar archivos PDF con la API de Layout en aplicaciones ASP.NET Core, MAUI, Unity, Xamarin y aplicaciones de consola. Docotic.Pdf, con el complemento de Layout, puede generar archivos PDF en Windows, macOS y Linux.
Plataformas en la nube e imágenes Docker
Docotic.Pdf, con el complemento Layout, puede ejecutarse en entornos de nube Azure y AWS, incluyendo configuraciones sin servidor. La biblioteca y el complemento son totalmente compatibles con cambios dinámicos de hardware, escalado automático y otras características de ejecución nativas de la nube.
En la mayoría de los escenarios de nube, se requiere una licencia ilimitada. Las preguntas frecuentes sobre licencias explican cómo elegir la licencia adecuada para aplicaciones en la nube.
La API de Layout funciona directamente en contenedores Docker. No se necesita ninguna configuración especial para generar archivos PDF al ejecutar la biblioteca y el complemento Layout dentro de un contenedor.
Agregar texto a archivos PDF
El texto es una parte fundamental de cualquier documento PDF. Puede utilizar los métodos Text de
la clase LayoutContainer para agregar texto a un
espacio de contenido.

El texto abarca
En el ejemplo "Hola, mundo", utilicé la sobrecarga LayoutContainer.Text(string) para agregar
texto al contenido principal de la página. Ahora veamos otra sobrecarga del método Text.
public static void GenerateTextPdf()
{
PdfDocumentBuilder.Create().Generate("text-spans.pdf", doc => doc.Pages(pages =>
{
pages.Content().Text(AddTextSpans);
}));
}
private static void AddTextSpans(TextContainer text)
{
text.Line("About VB.NET")
.Style(t => t.Strong);
text.Span("VB.NET is a multi-paradigm, object-oriented language ");
text.Span("that runs on .NET, Mono, and the ");
text.Hyperlink(
".NET Framework",
new Uri("https://dotnet.microsoft.com/download/dotnet-framework"));
text.Line(".");
text.Span("Released by Microsoft in 2002, ");
text.Line("it continues the lineage of the original Visual Basic language.");
}
Este código utiliza los métodos Span y Line de la clase TextContainer para añadir texto a la
línea actual. El método Line también completa la línea actual. El código de ejemplo utiliza
además el método Hyperlink para adjuntar un enlace a un recurso externo a un segmento de texto
específico.
Observe cómo el código de ejemplo aplica formato fuerte a la primera línea mediante el método
Style. Exploremos el concepto de estilos de texto con más detalle.
Estilos de texto
Los estilos de texto permiten personalizar la apariencia del texto. La clase
TextStyle proporciona métodos para cambiar el tamaño de
la fuente, el espaciado entre letras, los colores y otras propiedades del texto. Los objetos
TextStyle son inmutables, por lo que cada llamada a un método genera una nueva instancia de
estilo. Se pueden aplicar estilos de texto en diferentes niveles de diseño.
PdfDocumentBuilder.Create().Generate("text-styles.pdf", doc =>
{
doc.Pages(pages =>
{
pages.TextStyle(TextStyle.Parent.FontSize(30));
pages.Content()
.TextStyle(TextStyle.Parent.FontColor(new PdfRgbColor(0, 0, 255)))
.Text(text =>
{
text.Span("Hello,");
text.Span("World!")
.Style(TextStyle.Parent.Underline());
});
});
});
La propiedad TextStyle.Parent devuelve un estilo especial en el que todas las propiedades de
texto no están definidas. En el ejemplo anterior, el código dibuja «¡Hola, mundo!» en azul, con la
segunda palabra subrayada, utilizando un tamaño de fuente de 30 puntos.
Esto sucede porque el código:
- establece el tamaño de fuente a 30 puntos a nivel de página,
- luego establece el color del texto a azul para el espacio de contenido principal,
- luego aplica el estilo de subrayado al último segmento de texto.
Cada estilo posterior hereda los anteriores a través de la propiedad TextStyle.Parent.
Mediante los métodos de la clase TextStyle, puede, entre otras cosas, cambiar la dirección del
texto a de derecha a izquierda. Consulte otro ejemplo de herencia de estilos de
texto en nuestro repositorio de ejemplos.
Tipografía
La clase TextStyle permite personalizar todas las propiedades de texto, excepto la fuente. Para
cambiar la fuente predeterminada, utilice los métodos Document.TextStyleWithFont para crear un
estilo de texto basado en una fuente específica. Puede usar una fuente instalada en el sistema
operativo o cargarla desde un archivo o flujo de datos.
Tras crear un estilo basado en una fuente, puede aplicar propiedades opcionales adicionales y, a continuación, aplicar el estilo resultante a un segmento de texto. Este ejemplo en C# muestra cómo usar una fuente del sistema.
PdfDocumentBuilder.Create().Generate("text-style-with-font.pdf", doc =>
{
var font = SystemFont.Family("Calibri");
var style = doc.TextStyleWithFont(font).FontSize(30);
doc.Pages(pages =>
{
pages.Content().Text(text =>
{
text.Span("Hello,");
text.Span("World!")
.Style(style);
});
});
});
El método TextStyleWithFont incluye un parámetro opcional que especifica cómo se debe incrustar
la fuente en el documento generado. Por defecto, la biblioteca:
- incrusta los glifos utilizados para las fuentes TrueType/OpenType,
- incrusta todos los glifos para las fuentes Type1 y CFF,
- no incrusta los glifos para las fuentes PDF integradas (fuentes Base14).
Debido a estas configuraciones predeterminadas, los documentos que usan fuentes TrueType y OpenType pueden permanecer pequeños incluso cuando se usan fuentes grandes. También puede especificar un cargador de fuentes personalizado, fuentes alternativas y un controlador para glifos faltantes. Consulte el código de ejemplo en nuestro repositorio de ejemplos para obtener más detalles sobre la gestión de fuentes en documentos PDF.
La API de diseño proporciona una colección de estilos predefinidos, a los que puede acceder y modificar a través de la clase Typography.
PdfDocumentBuilder.Create().Generate("typography.pdf", doc =>
{
doc.Typography(t =>
{
var fontsPath = Environment.GetFolderPath(Environment.SpecialFolder.Fonts);
var arialFont = new FileInfo(Path.Combine(fontsPath, "arial.ttf"));
t.Document = doc.TextStyleWithFont(arialFont);
t.Header = t.Parent.FontSize(20).FontColor(new PdfGrayColor(20));
t.Footer = t.Footnote;
});
doc.Pages(pages =>
{
pages.Header().AlignCenter().Text("Header");
pages.Content().Text(t =>
{
t.Line("Title").Style(t => t.Title);
t.Line("Heading 1").Style(t => t.Heading1);
t.Line("Regular");
});
pages.Footer()
.Height(20)
.AlignCenter()
.Text(t => t.CurrentPageNumber());
});
});
Recomiendo sobrescribir los estilos predefinidos configurando la tipografía para todo el documento, aunque no es obligatorio y aún se pueden aplicar estilos de texto a nivel de fragmento de texto.
Con la clase Typography, no es necesario almacenar referencias de estilos de texto en variables.
En su lugar, se registran los estilos necesarios mediante los métodos Document.Typography y
posteriormente se accede a ellos a través de las propiedades del objeto Typography. Consulte el
ejemplo de Typography para ver cómo usar estilos de texto predefinidos y
personalizados al generar documentos PDF.
Trabajar con encabezados y pies de página
Muchos documentos PDF reales, como informes o facturas, incluyen encabezados y pies de página. Esta sección muestra cómo agregarlos a un PDF.
public static void GeneratePdfWithHeaderAndFooter()
{
PdfDocumentBuilder.Create()
.Generate("header-footer.pdf", doc => doc.Pages(pages =>
{
pages.Size(PdfPaperSize.A6).Margin(10);
BuildPagesHeader(pages.Header());
BuildPagesFooter(pages.Footer());
pages.Content().Text("Hello, world!");
}));
}
public static void BuildPagesHeader(LayoutContainer header)
{
header.TextStyle(TextStyle.Parent.FontSize(8))
.AlignRight()
.Text(t =>
{
t.Line($"Created by: {Environment.UserName}");
t.Line($"Date: {DateTime.Now}");
});
}
public static void BuildPagesFooter(LayoutContainer footer)
{
footer.AlignRight().Text(text =>
{
text.Style(t => t.Parent.FontColor(new PdfRgbColor(255, 0, 0)));
text.CurrentPageNumber();
text.Span(" / ");
text.PageCount();
});
}
El método BuildPagesHeader establece un tamaño de fuente más pequeño para el texto del
encabezado. Utiliza dos líneas para el contenido del encabezado: una con el nombre del usuario
actual y otra con la fecha actual. El texto está alineado a la derecha.
Observe que el código no especifica ningún tamaño explícito para el encabezado. Ocupa todo el ancho de la página menos los márgenes izquierdo y derecho, y su altura depende de la altura de las líneas de texto.
El método BuildPagesFooter muestra cómo colocar el número de página actual en el pie de página
del PDF. La biblioteca calcula automáticamente el número de página actual y el número total de
páginas. Puede acceder a estos valores mediante los métodos CurrentPageNumber y PageCount de un
objeto TextContainer.
La API de Layout también proporciona una forma de formatear los números de página. Por ejemplo, puede dibujar números de página hexadecimales de esta manera:
text.CurrentPageNumber().Format(p => "0x" + p?.ToString("x2"));
Nuestro repositorio de ejemplos contiene otro ejemplo de cómo agregar un encabezado y un pie de página a un PDF. Ese ejemplo formatea los números de página como números romanos.
Insertar imágenes
Como dice el refrán, una imagen vale más que mil palabras. En presupuestos o recibos, es común incluir el logotipo de la empresa u otra imagen importante. Para este ejemplo, usaré una imagen sencilla y atractiva.
Para usar una imagen, primero debe agregarla al documento. La biblioteca puede cargar imágenes desde un archivo o un flujo de datos. Solo se admiten formatos ráster: PNG, JPEG, JPEG 2000, BMP, GIF y TIFF.
Una vez que tenga un objeto Image, puede establecerlo como contenido de uno o más contenedores de
diseño llamando al método Image del contenedor. Puede escalar, rotar, agregar relleno y
organizar la imagen como cualquier otro contenido.
PdfDocumentBuilder.Create().Generate("image-with-text.pdf", doc =>
{
var imageFile = new FileInfo("red-flowers-at-butterfly-world.jpg");
var image = doc.Image(imageFile);
doc.Pages(pages =>
{
pages.Size(PdfPaperSize.A6);
pages.Content().Column(c =>
{
c.Spacing(20);
c.Item()
.AlignCenter()
.Text("Hello, world!")
.FontSize(20);
c.Item()
.AlignCenter()
.MaxWidth(200)
.Image(image);
});
});
});
El código de ejemplo utiliza texto e imagen en el espacio de contenido principal. Sin embargo, un contenedor de diseño solo puede contener texto o solo imagen. Para incluir ambos en el espacio de contenido principal de la página, se necesita un contenedor compuesto.
Utilizo un contenedor Column para colocar el texto y la imagen verticalmente, uno tras otro. El
método Item del contenedor Column proporciona un subcontenedor. Una llamada a Item crea un
contenedor para el texto y otra crea un contenedor para la imagen. El contenedor compuesto con
todos sus subcontenedores se convierte en el contenido principal.
Para ejecutar el código de ejemplo, descargue la imagen de la flor de nuestro repositorio de ejemplos y colóquela en el directorio de trabajo de su aplicación.
Imágenes en línea
Si solo dispone de la URL de la imagen en lugar del archivo, descargue la imagen en un flujo de
memoria y cree un objeto Image a partir de ese flujo. El siguiente ejemplo muestra cómo usar
imágenes en línea con la API de Layout.
public static async Task AddImageWithTextFromUrl()
{
using var http = new HttpClient();
using var stream = await http.GetStreamAsync("url/to/image");
var memoryStream = new MemoryStream();
await stream.CopyToAsync(memoryStream);
memoryStream.Position = 0;
PdfDocumentBuilder.Create().Generate("online-image-with-text.pdf", doc =>
{
var image = doc.Image(memoryStream);
doc.Pages(pages =>
{
pages.Size(PdfPaperSize.A6);
pages.Content().Column(c =>
{
c.Spacing(20);
c.Item()
.AlignCenter()
.Text("Hello, world!")
.FontSize(20);
c.Item()
.AlignCenter()
.MaxWidth(200)
.Image(image);
});
});
});
}
Dado que el método realiza una operación asíncrona (descarga de una imagen desde una URL), se
declara como async Task en lugar de void. Quienes lo utilicen deben esperar a que finalice para
garantizar que la generación del PDF se complete correctamente. En su propio código, un método
similar también puede devolver un valor, en cuyo caso se declararía como async Task<TResult>.
Crear listas
¿Qué es una lista? Puedes imaginarla como un grupo de elementos numerados escritos uno debajo del otro. La API de Layout no proporciona un tipo de contenedor específico para listas, pero es fácil implementarlo utilizando otros contenedores compuestos.
var dayNames = DateTimeFormatInfo.InvariantInfo.DayNames;
var dayNamesSpain = DateTimeFormatInfo.GetInstance(new CultureInfo("es-ES")).DayNames;
PdfDocumentBuilder.Create().Generate("list.pdf", doc => doc.Pages(pages =>
{
pages.Size(PdfPaperSize.A6);
pages.Content().Column(column =>
{
for (int i = 0; i < dayNames.Length; i++)
{
column.Item().Row(row =>
{
row.Spacing(5);
row.AutoItem().Text($"{i + 1}.");
row.RelativeItem().Text(t =>
{
t.Line(dayNames[i]);
t.Line($"In Spain they call it {dayNamesSpain[i]}");
});
});
}
});
}));
El código de ejemplo crea la lista como una columna de filas. Cada fila contiene dos elementos: el primero (a la izquierda) contiene el número del elemento y el segundo (a la derecha) contiene el texto del elemento. El código establece explícitamente el espaciado entre los elementos de cada fila.
Para organizar los elementos, el contenedor Row debe tener el tamaño de cada elemento
especificado explícitamente o calcularlo. En este ejemplo, se utilizan los métodos AutoItem y
RelativeItem. Como resultado, el contenedor de filas calcula el ancho necesario para el primer
elemento y luego utiliza el ancho restante disponible para el segundo.
Al usar este método y ajustar la apariencia de las filas según sea necesario, puede crear una lista que se adapte mejor al diseño y estilo de su documento.
Construir mesas
Muchos documentos PDF contienen tablas, lo cual no sorprende, ya que las tablas mejoran la claridad y la organización de los datos. Esta sección muestra cómo crear una tabla en un PDF utilizando la API de Layout.
public static void AddTable()
{
PdfDocumentBuilder.Create().Generate("table.pdf", doc => doc.Pages(pages =>
{
pages.Size(PdfPaperSize.A6);
var color = new PdfGrayColor(75);
pages.Content().Padding(20).Table(t =>
{
t.Columns(c =>
{
c.RelativeColumn(4);
c.RelativeColumn(1);
c.RelativeColumn(4);
});
t.Header(h =>
{
h.Cell().Background(color).Text("Month");
h.Cell().Background(color).Text("Days");
h.Cell().Background(color).Text("First Day");
});
var year = DateTime.Now.Year;
for (int yearDiff = 0; yearDiff < 4; yearDiff++)
{
for (int i = 11; i >= 0; i--)
{
var stats = GetMonthStats(year - yearDiff, i);
t.Cell().Text(stats.Item1);
t.Cell().Text(stats.Item2);
t.Cell().Text(stats.Item3);
}
}
});
}));
}
private static (string, string, string) GetMonthStats(int year, int monthIndex)
{
return (
$"{DateTimeFormatInfo.InvariantInfo.MonthNames[monthIndex]} {year}",
DateTime.DaysInMonth(year, monthIndex + 1).ToString(),
new DateTime(year, monthIndex + 1, 1).DayOfWeek.ToString()
);
}
El código de ejemplo crea una tabla sencilla que muestra información básica sobre los meses del año actual y de los tres años anteriores. El código define tres columnas con anchos relativos. Las columnas de la izquierda y la derecha son cuatro veces más anchas que la columna central.
El código también define el encabezado de la tabla añadiendo celdas de encabezado y especificando el texto y el color de fondo de cada celda. Si una tabla no cabe en una sola página, el encabezado se repite en todas las páginas que ocupa. Este comportamiento se puede observar en el PDF generado por el código de ejemplo.
Se utilizan dos bucles sencillos para construir las filas. El bucle exterior itera sobre los años, y el bucle interior itera sobre los meses en orden inverso. El bucle interior recupera la información de cada mes y luego añade tres celdas para formar una fila.
Para obtener más detalles, puede consultar el artículo que explica en profundidad las características del contenedor de tabla.
Creación de enlaces internos a PDF
Los documentos PDF admiten enlaces internos que permiten a los lectores acceder a otras secciones del mismo archivo. En un visor de PDF, estos enlaces aparecen como elementos de texto o imagen en los que se puede hacer clic. Funcionan como hipervínculos, pero en lugar de dirigir a un sitio web externo, permiten navegar dentro del propio documento.

Muchos documentos PDF utilizan enlaces internos para marcadores o tablas de contenido, lo que permite a los lectores navegar rápidamente entre secciones. A continuación, se muestra cómo agregar un enlace a una sección del documento mediante la API de Layout:
PdfDocumentBuilder.Create().Generate("link.pdf", doc =>
{
doc.Pages(pages =>
{
pages.Content().Column(c =>
{
const string SectionName = "Chapter 1";
c.Item().SectionLink(SectionName).Text("Link");
c.Item().PageBreak();
c.Item().Section(SectionName).Text("Target");
});
});
});
El código de ejemplo convierte el texto de la primera página en un enlace a la sección con el
nombre especificado. Para ello, llama al método SectionLink del contenedor de diseño que contiene
el texto. La sección puede existir o no en este punto. El texto se vuelve clicable en un visor de
PDF.
A continuación, el código marca el texto de la segunda página como el inicio de la sección con el
mismo nombre. Su apariencia y comportamiento no cambian, pero se convierte en el destino del enlace
de la primera página. Esto se logra llamando al método Section del contenedor de diseño
correspondiente.
En este ejemplo, tanto el enlace como su destino son elementos de texto, pero puede crear secciones y enlaces en cualquier contenedor de diseño. Puede ser un contenedor con una imagen, un contenedor de tabla o un contenedor que usted mismo cree.
Consulte un ejemplo de cómo crear una tabla de contenido de PDF en nuestro repositorio de ejemplos.
Diseño de diseños PDF complejos
La API de Layout proporciona una variedad de contenedores de diseño que puedes combinar para generar documentos PDF de complejidad arbitraria. También puedes ampliar la API con tus propios componentes personalizados.
Los ejemplos de esta página son intencionadamente sencillos, diseñados para crear documentos directos y que puedas centrarte en las ideas principales sin perderte en los detalles. Si quieres ver cómo se pueden combinar diferentes contenedores para generar un PDF más complejo, consulta el ejemplo correspondiente en nuestro repositorio de ejemplos en GitHub.
Además de usar los contenedores integrados, puedes definir y usar componentes de diseño personalizados. Estos componentes son especialmente útiles cuando quieres que una sola clase encapsule tanto los datos como la lógica de diseño. Mantener todo en un solo lugar facilita la comprensión, modificación y reutilización del componente, a la vez que te proporciona una forma flexible de gestionar diseños complejos.
Para crear un componente de diseño personalizado, implementa la interfaz ILayoutComponent en tu
clase. Al generar un PDF, la biblioteca llama al método Compose de la interfaz y proporciona un
objeto LayoutContext. Su código puede usar este objeto para crear elementos de diseño y acceder a
la información del documento que se está generando.
Para agregar un componente de diseño personalizado a su diseño, llame al método Component de la
clase LayoutContainer. En cuanto al tamaño y la posición, un componente personalizado se comporta
igual que el texto o las imágenes.
Para ver un ejemplo de cómo implementar un componente personalizado con la interfaz
ILayoutComponent, consulte el ejemplo Componentes de diseño.
Otras formas de crear un PDF
Docotic.Pdf ofrece diversas maneras de crear archivos PDF, cada una adaptada a diferentes situaciones. Esta sección explica cuándo utilizar la API de Layout y cuándo otras alternativas pueden ser más convenientes.
¿Cuándo es preferible la API de Layout?
La API Layout de Docotic.Pdf es una potente herramienta para generar PDF a partir de diseños estructurados. Permite crear documentos combinando texto, imágenes, contenedores y tablas en estructuras anidadas de complejidad arbitraria. El proceso de generación es rápido, consume poca memoria y se comporta de forma predecible.
Docotic.Pdf y el complemento Layout forman un conjunto ligero y completamente autónomo. La API no requiere bibliotecas externas ni navegadores para generar PDF. Esto la convierte en una excelente opción para microservicios .NET, aplicaciones en la nube (especialmente las sin servidor) y otros entornos donde el tamaño es un factor importante.
Dado que el diseño del documento se define mediante código, se puede realizar pruebas unitarias de cualquier parte del mismo. La lógica del diseño se puede reutilizar como cualquier otro código, y se pueden encapsular tanto los datos como el comportamiento del diseño en componentes personalizados.
Alternativas a la API de Layout
Un artículo específico ofrece una comparación detallada de todas las formas de crear archivos PDF con Docotic.Pdf. A continuación, se presentan algunas de las alternativas más utilizadas.
-
Conversión de HTML a PDF
Reutiliza las plantillas HTML/CSS existentes. Elija el método HTML-to-PDF cuando su equipo ya produzca documentos en HTML/CSS y necesite versiones PDF de esos documentos. -
Generación de PDF de bajo nivel
Ofrece el máximo control disponible en la biblioteca sobre la estructura y el contenido de los PDF. Elija esta opción cuando necesite posicionamiento a nivel de píxel o gráficos vectoriales complejos. Se recomienda este método para situaciones críticas de rendimiento o cuando se requiera el menor consumo de recursos posible. -
Generación de PDF basada en plantillas
Ofrece una forma rápida y predecible de rellenar documentos sin necesidad de diseñar ni organizar sus elementos. Elija esta opción cuando disponga de una estructura PDF predefinida, como plantillas aprobadas o controladas por normativas, y solo necesite modificar campos de texto, reemplazar marcadores de posición, adjuntar documentos relacionados y realizar tareas similares. -
Combinación y composición de archivos PDF
Te permite crear un PDF a partir de elementos existentes en lugar de crearlo desde cero. Elige esta opción cuando tengas imágenes, páginas escaneadas u otros archivos PDF que necesites combinar en un solo archivo.
Comparación con otras soluciones de generación de PDF
Esta sección contiene dos tablas comparativas: una con las conclusiones clave y otra con información detallada y estructurada sobre cómo se compara Docotic.Pdf con el complemento Layout con otras soluciones populares para generar archivos PDF.
Conclusiones clave de la comparación
Existen excelentes opciones para generar archivos PDF, incluso gratuitas. Sin embargo, las funcionalidades como la firma, el cifrado o la combinación de documentos varían, lo que puede limitar las herramientas que mejor se adapten a tus necesidades.
| Solución | Cuándo usar | La mejor para |
|---|---|---|
| Docotic.Pdf con el complemento Layout | Si buscas un motor de maquetación de alta calidad y rendimiento capaz de generar PDF optimizados, con soporte avanzado para firmas, cifrado y edición de PDF en diversas plataformas, esta es la solución | Generación de facturas, informes, extractos y documentos similares de alta calidad, con una excelente experiencia de usuario. Ideal cuando se necesita procesamiento de PDF de nivel empresarial y soporte profesional |
| PDFsharp + MigraDoc | Cuando buscas una biblioteca gratuita con licencia MIT para la generación básica de PDF y no necesitas firmas digitales ni algoritmos de cifrado modernos | Creación sencilla de documentos en proyectos de código abierto o con presupuestos limitados |
| QuestPDF | Si buscas un motor de maquetación moderno dedicado exclusivamente a la generación de PDF y no necesitas edición, firmas ni cifrado, y no necesitas un editor de textos, firmas ni cifrado, este es el lugar ideal | Generación de PDF de alta calidad con una licencia MIT o una licencia comercial de bajo costo, siempre que todas las demás funciones que no sean de generación se gestionen en otro lugar |
| iText | Cuando necesite un conjunto de herramientas PDF maduro y con muchas funciones para generar y procesar archivos PDF, y esté dispuesto a publicar su solución como código abierto bajo la licencia AGPL/GPLv3 o a adquirir una costosa licencia comercial | Equipos que ya están familiarizados con la API de iText y, por lo tanto, no se ven afectados por su pronunciada curva de aprendizaje |
Comparación detallada
Revise la tabla para comprender el contexto general y saque sus propias conclusiones.
| Docotic.Pdf con Layout | PDFsharp + MigraDoc | QuestPDF | iText | |
|---|---|---|---|---|
| Capacidades de PDF | Biblioteca de PDF con todas las funciones | Generación de PDF y edición limitada | Generación de PDF únicamente | Amplia funcionalidad PDF |
| Modelo de renderizado | Motor de diseño moderno, declarativo y de modo retenido | Motor de diseño basado en cajas | Motor de diseño moderno, declarativo y de modo retenido | Motor de diseño basado en cajas + árbol de renderizado |
| Tipo de API | API fluida | API imperativa | API fluida | API imperativa |
| Experiencia del desarrollador | Excelente. La API es limpia, moderna e intuitiva | Bien. El diseño de la API es convencional | Excelente. La API es limpia, moderna e intuitiva | Satisfactorio. La API es verbosa y excesivamente compleja |
| Subconjunto de fuentes | Compatible; solo los glifos utilizados se incrustan por defecto | No compatible; puede generar archivos PDF innecesariamente grandes | Compatible; solo los glifos utilizados se incrustan por defecto | Compatible; solo los glifos utilizados se incrustan por defecto |
| Dirección de contenido de derecha a izquierda (RTL) | Compatible | No compatible | Compatible | Compatible |
| Firmas digitales | Compatible, incluyendo LTV y firmas externas | No compatible | No compatible | Compatible, incluyendo LTV y firmas externas |
| Cifrado / permisos | Compatible totalmente | Solo se admite el cifrado RC4; no admite AES ni certificados | No compatible | Soporte completo |
| Dependencias externas | Ninguna | Ninguna | Componentes basados en SkiaSharp/Skia | Ninguna |
| Apoyo | Soporte profesional para clientes potenciales y actuales; soporte prioritario con licencias de primer nivel | Apoyo comunitario; el apoyo profesional se puede adquirir por separado | Soporte de la comunidad a través de GitHub | Soporte comunitario para la versión AGPL; soporte profesional para titulares de licencias comerciales |
| Licencia | Comercial, con licencias gratuitas para casos de uso elegibles | MIT | Licencia MIT para particulares y pequeñas empresas; se requiere licencia comercial para empresas más grandes | Licencia AGPL para uso de código abierto, licencia comercial costosa para proyectos propietarios |
| Licencias para desarrolladores | Desarrolladores ilimitados con todas las licencias | Desarrolladores ilimitados con todas las licencias | Desarrolladores ilimitados con MIT; 10 desarrolladores con Professional; desarrolladores ilimitados con Enterprise | Licencia para desarrolladores ilimitada con la versión AGPL; licencia por desarrollador con la licencia comercial |
Conclusión
Docotic.Pdf, con el complemento Layout, ofrece una forma moderna, de alto rendimiento y alta calidad para generar PDF en C# y VB.NET. La biblioteca genera informes, estados de cuenta, facturas y documentos similares. Su API intuitiva y bien diseñada ofrece una excelente experiencia para el desarrollador. Puede contar con el soporte profesional que Bit Miracle proporciona para Docotic.Pdf y sus complementos.
A diferencia de otras soluciones de generación de PDF, Docotic.Pdf es una API de PDF completa. La biblioteca puede firmar los PDF generados con firmas digitales, incluidas firmas compatibles con LTV. Docotic.Pdf es compatible con certificados almacenados en hardware seguro, como tokens USB y tarjetas inteligentes. También admite módulos de seguridad de hardware (HSM) basados en la nube, como Microsoft Azure Key Vault y AWS Key Management Service (KMS).
Con Docotic.Pdf, puede adjuntar documentos de apoyo, como hojas de cálculo o notas de voz, a los PDF generados. Para mostrar documentos en una página web o en una interfaz similar, puede crear imágenes en miniatura desde una o más de sus páginas.
Próximos pasos:
- Explora los ejemplos de código de la API de Layout.
- Compara la generación de PDF a partir de bloques de construcción componibles con otros métodos para crear PDF.
- Contáctanos si tienes preguntas, comentarios o casos especiales.