Esta página puede contener texto traducido automáticamente.
Cómo crear documentos PDF en C# y VB.NET
Este artículo describe diferentes maneras de crear documentos PDF en .NET con la ayuda de la biblioteca Docotic.Pdf. Es una biblioteca .NET pura de C# de alto rendimiento, sin dependencias externas, para crear, editar, convertir y procesar documentos PDF.

En las siguientes secciones, presento los principales enfoques para crear PDFs con Docotic.Pdf:
- Usar la Core API, que proporciona control de bajo nivel sobre texto, gráficos e internals de PDF. Esta opción es la mejor para diseños personalizados, documentos con muchos gráficos y funciones avanzadas.
- Usar la Layout API de alto nivel, que admite párrafos, tablas, encabezados, pies de página y paginación automática. Esta API es ideal cuando desea documentos estructurados sin calcular manualmente las posiciones.
- Convertir HTML a PDF con soporte para SVG y otros formatos web. Este enfoque es especialmente útil cuando su solución ya genera documentos HTML y necesita versiones PDF de esos archivos HTML y CSS.
- Crear PDFs a partir de imágenes. Este método es útil para documentos escaneados, informes basados en imágenes, recibos y cualquier flujo de trabajo que comience con imágenes rasterizadas.
- Combinar o dividir PDFs. Esta es una buena opción para ensamblar informes, procesar cargas de usuarios, combinar documentos relacionados y reestructurar PDFs grandes.
- Crear PDFs a partir de plantillas. Este enfoque funciona bien cuando se requiere un formato consistente para documentos generados por lotes, como recibos, formularios fiscales, contratos laborales y otros tipos de documentos repetibles.
Los temas adicionales cubiertos en la guía incluyen:
- Funciones interactivas como vínculos y acciones de JavaScript
- Enfoques para probar la salida PDF y garantizar resultados esperados
Creación de PDFs con Core API
Core API es la base de la creación de PDF en Docotic.Pdf. Le ofrece control total de bajo nivel sobre la colocación de texto, imágenes y gráficos vectoriales en un lienzo PDF mediante su Canvas API. Esta API de dibujo es un subconjunto de Core API y proporciona los métodos y propiedades que se usan para agregar contenido a páginas y otros objetos con lienzos. Más allá del renderizado, Core API también admite anotaciones, campos de formulario, capas, marcadores y otras funciones de PDF.
Aquí hay código C# que crea un PDF sencillo usando tres operaciones fundamentales: dibujar texto, colocar una imagen y renderizar gráficos vectoriales en un lienzo de página.
using var pdf = new PdfDocument();
var canvas = pdf.Pages[0].Canvas;
canvas.Font = pdf.CreateFont(PdfBuiltInFont.HelveticaBold);
canvas.FontSize = 14;
canvas.DrawString(40, 100, "Core API demo: text, images, and vector graphics");
var image = pdf.CreateImage("image.png");
canvas.DrawImage(image, 40, 180, 120, 120, 0);
canvas.Pen.Color = new PdfRgbColor(30, 60, 160);
canvas.Pen.Width = 2;
canvas.Brush.Color = new PdfRgbColor(200, 230, 255);
canvas.DrawRectangle(new PdfRectangle(200, 200, 150, 80), PdfDrawMode.FillAndStroke);
pdf.Save("core-api-demo.pdf");
Esta panorámica presenta solo una pequeña parte de lo que Core API puede hacer. Para temas avanzados, consulte el artículo detallado sobre la creación de PDFs con Core API. El artículo cubre la medición de texto, el trabajo con espacios de color, la aplicación de recorte, el relleno de áreas con patrones, el manejo de transparencia y otras capacidades.
Generación de PDFs con Layout API
Layout API es un motor de creación de documentos de alto nivel que ofrece la forma más fácil y eficiente de generar PDFs complejos y ricos en contenido.
Al usar la API, compone PDFs a partir de elementos estructurales como páginas, contenedores, fragmentos de texto, imágenes, tablas, vínculos, encabezados, pies de página y más. En lugar de calcular coordenadas o administrar manualmente la paginación, usted describe la estructura del documento y deja que el motor de diseño se encargue del resto.
Este ejemplo ilustra cómo crear un PDF usando Layout API, confiando en un diseño declarativo en lugar de un posicionamiento manual.
PdfDocumentBuilder.Create()
.Info(info => info.Title = "Docotic.Pdf Layout API demo")
.Generate("layout-api-demo.pdf", doc => doc.Pages(pages =>
{
pages.Content().Padding(100).Text(text =>
{
text.Span("The Layout API lets you compose PDFs from structural elements ");
text.Line("without manually calculating coordinates or handling pagination.")
.Style(s => s.Strong);
});
}));
Consulte la guía detallada para aprender a usar Layout API al generar PDFs en aplicaciones .NET.
Conversión de contenido web con HTML to PDF API
Docotic.Pdf, junto con su complemento gratuito HtmlToPdf, proporciona un motor moderno, de alta calidad y basado en Chrome para HTML a PDF. Puede convertir HTML moderno y otro contenido web, como SVG o imágenes WebP, en documentos PDF de alta calidad usando la API proporcionada por el complemento.
HTML to PDF API puede crear PDFs a partir de páginas HTML completas o fragmentos HTML. Puede convertir contenido desde URLs, cadenas HTML sin procesar y archivos HTML locales. Las dos últimas opciones facilitan la generación de PDFs a partir de plantillas HTML.
Vea un ejemplo de cómo producir un PDF a partir de una plantilla HTML:
public static async Task HelloHtmlTemplate()
{
static string GetUserName()
{
// Reemplácelo con lógica real: entrada de formulario, llamada a API, configuración, etc.
return "World";
}
string html = $@"
<h1>Hello, {GetUserName()}!</h1>
<p>This PDF was generated from an HTML template.</p>";
using var converter = await HtmlConverter.CreateAsync();
using var pdf = await converter.CreatePdfFromStringAsync(html);
pdf.Save("hello-html-template.pdf");
}
Para más detalles y ejemplos, consulte nuestra visión general detallada de HTML a PDF.
Creación de PDFs a partir de imágenes
Docotic.Pdf ofrece una forma flexible y amigable para desarrolladores de convertir imágenes a PDF. La biblioteca admite formatos de imagen JPEG, BMP, GIF, PNG, TIFF y JPEG 2000 mediante Core API.

Cuando el formato PDF lo permite, Docotic.Pdf inserta los bytes de la imagen tal cual, evitando la decodificación y recodificación de píxeles para preservar la compresión original. La biblioteca también conserva el espacio de color cuando es posible.
Además, los formatos SVG y WebP se admiten a través de HTML to PDF API. Cuando necesita colocar imágenes junto a etiquetas o descripciones, Layout API le ayuda a organizar y alinear elementos con un esfuerzo mínimo.
Cómo combinar varias imágenes en un solo PDF
Con Docotic.Pdf, puede convertir fácilmente un conjunto de imágenes en un único PDF, colocando una imagen en cada página.
El siguiente ejemplo carga imágenes desde archivos y dibuja cada una en su propia página. Cada imagen se escala para ajustarse a la página y se centra para lograr un diseño limpio y consistente.
public static void ImagesOnToPdf(string[] imagePaths, string outputPath)
{
using var pdf = new PdfDocument();
foreach (string path in imagePaths)
{
var image = pdf.CreateImage(path);
var page = pdf.AddPage();
var pageWidth = page.Width;
var pageHeight = page.Height;
var scale = Math.Min(pageWidth / image.Width, pageHeight / image.Height);
var drawWidth = image.Width * scale;
var drawHeight = image.Height * scale;
var x = (pageWidth - drawWidth) / 2;
var y = (pageHeight - drawHeight) / 2;
page.Canvas.DrawImage(image, x, y, drawWidth, drawHeight, 0);
}
pdf.RemovePage(0);
pdf.Save(outputPath);
}
Manejo de imágenes TIFF y GIF multipágina
Docotic.Pdf admite completamente archivos TIFF y GIF multipágina. Al agregar imágenes a un PDF, use el método OpenImage en lugar de CreateImage si alguna de las imágenes puede contener varias páginas.
El siguiente código demuestra cómo convertir TIFF a PDF, y funciona tanto para imágenes de una sola página como multipágina:
public static void OddFramesToPdf(string[] imagePaths, string outputPath)
{
using var pdf = new PdfDocument();
foreach (string path in imagePaths)
{
var imageFrames = pdf.OpenImage(path);
for (int i = 0; i < imageFrames.Count; i++)
{
if (i % 2 != 0)
continue;
var image = pdf.CreateImage(imageFrames[i]);
var page = pdf.AddPage();
page.Width = image.Width;
page.Height = image.Height;
page.Canvas.DrawImage(image, 0, 0, image.Width, image.Height, 0);
}
}
pdf.RemovePage(0);
pdf.Save(outputPath);
}
Puede usar el mismo enfoque para convertir GIF a PDF. También se aplica a otros formatos de imagen, aunque es más elaborado de lo necesario para formatos que contienen solo un fotograma.
Combinación y división de PDFs
Como biblioteca .NET completa, Docotic.Pdf puede crear nuevos PDFs combinando, extrayendo y reorganizando páginas de documentos existentes.
Cuando combina PDFs, la biblioteca no solo agrega páginas de otro documento, sino que también incorpora capas, marcadores, etiquetas de página, JavaScript compartido, destinos (objetivos de vínculo) y archivos incrustados. Para más detalles y orientación sobre cómo reducir el tamaño de los PDFs combinados, consulte el artículo sobre combinación de PDFs.
Los PDFs firmados digitalmente no pueden combinarse sin invalidar sus firmas existentes. Para preservar las firmas, cree un portafolio PDF en lugar de anexar documentos. Otra opción es combinar primero los PDFs y luego aplicar una nueva firma digital al documento combinado.
Docotic.Pdf también le permite copiar y extraer páginas en nuevos documentos. Se conserva todo el contenido asociado a las páginas copiadas, incluidas anotaciones, controles de formulario, contenido estructurado, capas y otros datos relacionados. Para ejemplos prácticos, consulte el artículo sobre división de PDFs en .NET. También explica cómo extraer o eliminar páginas.
Trabajo con plantillas PDF
Las plantillas PDF son archivos PDF prediseñados que sirven como estructura base para crear nuevos documentos. Son útiles cuando necesita producir PDFs con un diseño coherente mientras proporciona datos diferentes. Si desea separar el diseño visual de los datos en sí, las plantillas PDF también son una buena opción.
Las plantillas pueden ser PDFs basados en formularios o PDFs estáticos sin formularios. Ambos tipos sirven al mismo propósito. Además, las plantillas basadas en formularios incluyen elementos interactivos que, si no se aplanan, pueden recopilar información de los usuarios.
Creación de PDFs a partir de plantillas basadas en formularios
Las plantillas basadas en formularios suelen contener AcroForms, el tipo estándar y ampliamente admitido de formulario PDF interactivo. Para generar un PDF a partir de una plantilla de este tipo, normalmente necesita:
- completar cada campo marcador de posición
- aplanar los campos para evitar ediciones posteriores
- guardar el resultado como un nuevo PDF
Aquí hay código C# que busca un campo de texto de marcador de posición por nombre, le asigna un valor, aplana el campo y guarda el resultado, creando un PDF a partir de la plantilla:
var nameOnCertificate = "Eva Marin";
using var pdf = new PdfDocument("certificate-template.pdf");
if (pdf.TryGetControl("name", out var field))
{
if (field is PdfTextBox nameField)
{
nameField.Text = nameOnCertificate;
nameField.Flatten();
}
}
pdf.Save($"certificate-{nameOnCertificate}.pdf");
Si su plantilla contiene muchos marcadores de posición, puede importar datos FDF en lugar de completar cada campo individualmente. También puede usar PdfDocument.FlattenControls para aplanar todos los campos a la vez.
Creación de PDFs a partir de plantillas estáticas sin formularios
Si su plantilla no contiene campos de formulario, dibujará nombres y otros datos directamente sobre el lienzo de la página. Las plantillas PDF estáticas suelen contener marcadores de posición visuales fijos, como texto, imágenes o áreas vacías. Para producir un PDF a partir de la plantilla, deberá rellenar estas áreas vacías y reemplazar texto e imágenes de marcador de posición mediante programación.
Áreas vacías
Use la Canvas API para colocar texto e imágenes en áreas vacías. En casos simples, cuando solo necesita cambios menores, como agregar un nombre y una foto, este enfoque funciona bien. Debe conocer las coordenadas y el tamaño de las áreas, y para posicionar el texto correctamente, es posible que primero deba medirlo y luego alinearlo en consecuencia.
Trabajar con texto de longitud variable o multilínea es más desafiante, pero sigue siendo viable. Combinando DrawText, DrawString y los métodos para medir texto, puede ajustar y posicionar líneas según sea necesario. Si su plantilla contiene más que unas pocas áreas de este tipo, considere un enfoque alternativo como generar PDFs con Layout API.
Texto de marcador de posición
Docotic.Pdf también proporciona métodos para buscar y reemplazar texto. Sin embargo, usar la búsqueda de texto como mecanismo de plantillas generalmente no es más sencillo que trabajar con áreas vacías de marcador de posición. Antes de insertar nuevo contenido, debe localizar el fragmento de texto exacto y eliminarlo de forma limpia.
Imágenes de marcador de posición
Las plantillas estáticas pueden incluir imágenes de marcador de posición para avatares de usuario o fotos de productos. Para encontrar una imagen de marcador de posición, enumere la colección de imágenes dibujadas en cada página. Para cada imagen dibujada, puede obtener su tamaño visible y su posición. Para reemplazar el marcador de posición, use PdfImage.ReplaceWith.
using var pdf = new PdfDocument("invoice-template.pdf");
var paintedImages = pdf.Pages[0].GetPaintedImages();
var placeholder = paintedImages.First();
placeholder.Image.ReplaceWith("company-logo.jpg");
pdf.Save($"invoice.pdf");
Otra opción es dibujar una nueva imagen sobre el área ocupada por la imagen de marcador de posición, pero esto normalmente aumenta el tamaño del PDF resultante sin una buena razón.
Diseño de marcadores de posición para facilitar el reemplazo
Para plantillas estáticas, ayuda diseñar el diseño con regiones predecibles y bien definidas tanto para texto como para imágenes. Deje suficiente relleno alrededor de las áreas que contendrán contenido de longitud variable y use imágenes de marcador de posición neutrales que coincidan con las relaciones de aspecto que espera insertar más adelante.
Si su plantilla usa texto de marcador de posición que planea reemplazar, puede simplificar el flujo de trabajo usando cuadros de texto en lugar de texto sin formato. Agregue un cuadro de texto de solo lectura y sin bordes a la plantilla y coloque dentro el texto de marcador de posición. Al generar el PDF final, abra la plantilla, localice el cuadro de texto por nombre y asigne el nuevo valor directamente con box.Text = "new text";. Luego aplane el cuadro de texto para evitar ediciones posteriores.
Adición de elementos interactivos
Las funciones interactivas convierten un PDF estático en un documento dinámico y fácil de navegar, enriquecido con anotaciones y marcas. Las acciones y JavaScript permiten automatización directamente dentro del PDF.
Anotaciones
Las anotaciones son objetos adjuntos a una página que representan comentarios, resaltados, archivos adjuntos y otros widgets interactivos. Son visibles en el contenido de la página y admiten flujos de revisión y colaboración.
El siguiente ejemplo en C# muestra cómo agregar anotaciones de texto, también conocidas como notas adhesivas, a una página PDF usando Docotic.Pdf.
using var pdf = new PdfDocument("example.pdf");
var page = pdf.Pages[0];
var textAnnot = page.AddTextAnnotation(new PdfPoint(50, 100), "Reviewer comment");
textAnnot.Contents = "Please check the figures on this page.";
pdf.Save("text-annotation.pdf");
El siguiente ejemplo demuestra cómo resaltar texto y otro contenido para llamar la atención sobre partes clave de un documento.
using var pdf = new PdfDocument("example.pdf");
var page = pdf.Pages[0];
var color = new PdfRgbColor(255, 255, 120);
var annotationText = "Please confirm this part.";
var bounds = new PdfRectangle(50, 250, 120, 40);
page.AddHighlightAnnotation(annotationText, bounds, color);
pdf.Save("highlight-annotation.pdf");
Vínculos
Los estándares PDF definen varios tipos de vínculos PDF. Los más importantes y ampliamente usados son los vínculos internos y los hipervínculos.
Los vínculos internos, también llamados acciones GoTo, permiten saltar a una página o a un destino con nombre dentro del mismo PDF. Son útiles para referencias cruzadas y navegación interna.
Aquí hay código C# que crea un vínculo desde la primera página a la página con índice igual a 5:
using var pdf = new PdfDocument();
var page = pdf.Pages[0];
int targetPageIndex = 5;
for (int i = 0; i < targetPageIndex; i++)
pdf.AddPage();
var rect = new PdfRectangle(50, 50, 100, 40);
page.Canvas.DrawRectangle(rect);
page.AddLinkToPage(rect, targetPageIndex);
pdf.Pages[targetPageIndex].Canvas.DrawString(50, 50, "Glad to have you here.");
pdf.Save("link-to-page.pdf");
Layout API proporciona otra forma de crear vínculos internos que no requiere posicionamiento absoluto.
Los vínculos externos, también llamados acciones URI, abren una URL web. Puede agregar un hipervínculo a una página PDF usando el método PdfPage.AddHyperlink. Por lo demás, el enfoque es el mismo que con los vínculos internos.
Marcadores
Los marcadores, también llamados outlines, son accesos directos o vínculos especiales que ayudan a los lectores a navegar rápidamente a secciones o páginas específicas. Cuando el lector hace clic en un marcador, la aplicación visor salta a la parte designada del documento.
Los outlines aparecen en el panel de marcadores del visor y proporcionan un árbol de navegación jerárquico similar a una tabla de contenido de un libro, pero interactivo. Los outlines PDF pueden incluir marcadores principales y marcadores anidados, lo que facilita estructurar documentos grandes.
El siguiente ejemplo muestra cómo crear marcadores en PDFs usando C# y Docotic.Pdf. El código crea tres marcadores de nivel superior. El segundo marcador contiene un marcador anidado.
using var pdf = new PdfDocument();
for (int i = 0; i < 5; i++)
{
var page = i == 0 ? pdf.Pages[0] : pdf.AddPage();
var canvas = page.Canvas;
canvas.FontSize = 14;
canvas.DrawString(50, 50, $"Page {i + 1}");
}
var root = pdf.OutlineRoot;
root.AddChild("Getting Started", 1);
var child = root.AddChild("Things You Can Do", 2);
child.AddChild("Making Quick Improvements", 3);
root.AddChild("Keeping Everything Running Smoothly", 4);
pdf.PageMode = PdfPageMode.UseOutlines;
pdf.Save("bookmarks.pdf");
Los marcadores difieren de la tabla de contenido que podría encontrar impresa en las páginas de un libro físico o mostrada en un PDF. Puede crear una tabla de contenido mediante programación midiendo encabezados y escribiendo entradas con números de página.
Para ver un enfoque alternativo para crear una tabla de contenido usando Layout API, eche un vistazo al código relacionado en nuestro repositorio de ejemplos.
Scripting en PDF
Las acciones de JavaScript están entre las funciones interactivas más potentes. PDF JavaScript es un subconjunto de JavaScript que expone las APIs del documento y del visor. Se usa para validación de formularios, cálculos, diálogos de interfaz de usuario y pequeñas tareas de automatización.
Puede adjuntar scripts a anotaciones, marcadores, controles de formulario o acciones de apertura. Con Docotic.Pdf puede incrustar código JavaScript en un PDF. El código puede validar la entrada de formularios, calcular valores, mostrar u ocultar campos o realizar interacciones con el visor.
La colección de JavaScript compartido contiene scripts almacenados a nivel de documento. Estos scripts pueden reutilizarse por múltiples acciones. En otras palabras, los scripts compartidos son útiles para funciones auxiliares y lógica compartida. Ayudan a reducir la duplicación y simplificar el mantenimiento.
El siguiente código define un script compartido que muestra un mensaje de alerta en el visor de PDF y luego muestra cómo activar ese script asignándolo a la acción de clic del botón.
using var pdf = new PdfDocument();
pdf.SharedScripts.Add(
pdf.CreateJavaScriptAction("function messageBox(message) { app.alert(message,3); }")
);
var button = pdf.Pages[0].AddButton(50, 50, 100, 40);
button.Text = "Click me";
button.OnMouseUp = pdf.CreateJavaScriptAction("messageBox('Hello, dear!');");
pdf.Save("shared-javascript.pdf");
El script del ejemplo es sencillo, pero puede crear acciones de JavaScript de cualquier complejidad. La referencia de la API de JavaScript de Adobe proporciona muchos métodos que puede usar. Tenga en cuenta que los visores que no son de Adobe normalmente solo admiten un subconjunto de la API.
Acciones de apertura
Una acción de apertura es una acción que el visor de PDF ejecuta cuando se abre el documento. Los usos típicos incluyen abrir en una página específica, ejecutar una rutina de inicialización en JavaScript o establecer preferencias del visor. No hay restricciones sobre el tipo de acción de apertura.
El siguiente ejemplo muestra cómo crear una acción de apertura GoTo. El código agrega texto a la segunda página y establece una acción de apertura que hace que el visor navegue automáticamente a esa página cuando se abre el PDF.
using var pdf = new PdfDocument();
var canvas = pdf.AddPage().Canvas;
canvas.FontSize = 14;
var message =
"If you see this immediately after opening the file, " +
"your PDF viewer supports open actions.";
var options = new PdfTextDrawingOptions(new PdfRectangle(100, 100, 100, 150));
canvas.DrawText(message, options);
pdf.OnOpenDocument = pdf.CreateGoToPageAction(1, 0);
pdf.Save("open-action.pdf");
Tenga en cuenta que no todos los visores ejecutan acciones de apertura de JavaScript. Algunos las ignoran o primero muestran un aviso al usuario. Algunos visores bloquean por completo las acciones de apertura.
Para comprobar si un PDF contiene una acción de apertura, cárguelo en un PdfDocument e inspeccione la propiedad OnOpenDocument. Si la propiedad es null, el documento no tiene definida una acción de apertura.
Aplicación de cifrado y firmas digitales
El cifrado y las firmas digitales abordan dos aspectos complementarios de la seguridad de los PDFs que crea. El cifrado controla quién puede abrir un documento y qué puede hacer con él, mientras que las firmas demuestran quién creó o aprobó el archivo y confirman que no ha sido modificado.
La protección con contraseña le permite establecer reglas de acceso durante la creación. Puede asignar una contraseña de apertura para restringir la visualización y una contraseña de propietario para definir permisos como impresión, copia, edición o relleno de formularios. El cifrado con certificados proporciona una protección más fuerte y específica por destinatario, y funciona bien cuando distribuye PDFs confidenciales a varias personas sin depender de una contraseña compartida. Para más detalles, consulte el artículo sobre cifrado de PDFs con contraseñas y certificados.
Las firmas digitales agregan autenticidad e integridad en el momento de la creación. Docotic.Pdf puede firmar PDFs usando certificados de archivos, el almacén de Windows, tokens de hardware, HSM o servicios de claves en la nube. Puede incluir marcas de tiempo y datos de validación a largo plazo para que las firmas sigan siendo verificables mucho después de producir el documento. También se admiten flujos de trabajo de firma externa, incluidos PKCS#11 y KMS en la nube.
Configuración de metadatos PDF
Los metadatos PDF son información descriptiva incrustada en un documento, como el título, el autor, el tema, las palabras clave, las fechas de creación y campos similares. Ayudan al software, los motores de búsqueda y los sistemas de gestión documental a entender de qué trata un archivo sin abrirlo.
Un documento PDF puede contener metadatos en dos sistemas coexistentes:
- metadatos XMP
- diccionario de información del documento (
Infodictionary)

XMP es el formato más rico, estructurado y estandarizado para incrustar metadatos descriptivos. El diccionario Info es simple y ampliamente compatible, pero limitado, y está obsoleto en el estándar PDF 2.0 (ISO 32000‑2) en favor de los metadatos XMP. Docotic.Pdf puede leer y escribir ambos sistemas y proporciona un método auxiliar para mantenerlos sincronizados.
Docotic.Pdf actualiza automáticamente algunos metadatos antes de guardar un archivo PDF. Por ejemplo, la biblioteca establece los valores Producer y Creator de forma predeterminada. Use las opciones de guardado para cambiar este comportamiento y conservar los valores de metadatos establecidos explícitamente.
Metadatos XMP
Use la propiedad PdfDocument.Metadata para acceder y modificar los metadatos XMP en un PDF. A través de esta propiedad puede trabajar con esquemas conocidos como XMP Core, Dublin Core y el esquema PDF, así como administrar sus propios metadatos personalizados.
using var pdf = new PdfDocument();
var xmp = pdf.Metadata;
xmp.Pdf.Creator = new XmpString("Second-line authoring terminal");
xmp.Pdf.Title = new XmpString("Quarterly Report");
var creators = new XmpArray(XmpArrayType.Ordered);
creators.Values.Add(new XmpString("Second-line authoring terminal"));
creators.Values.Add(new XmpString("Assistive authoring terminal"));
xmp.DublinCore.Creators = creators;
var descriptions = new XmpArray(XmpArrayType.Alternative);
descriptions.Values.Add(new XmpLanguageAlternative("x-default", "Quarterly Report"));
descriptions.Values.Add(new XmpLanguageAlternative("fr", "Rapport trimestriel"));
descriptions.Values.Add(new XmpLanguageAlternative("de", "Quartalsbericht"));
xmp.DublinCore.Descriptions = descriptions;
var author1 = new XmpString("First Author");
author1.Qualifiers.Add("role", "main author");
var author2 = new XmpString("Second Author");
author2.Qualifiers.Add("role", "co-author");
var authors = new XmpArray(XmpArrayType.Unordered);
authors.Values.Add(author1);
authors.Values.Add(author2);
xmp.Custom.Properties.Add("authors", authors);
pdf.Save("with-xmp-metadata.pdf");
XMP admite matrices, estructuras y valores con tipo, lo que lo convierte en una buena opción para metadatos enriquecidos. El código anterior también muestra cómo almacenar propiedades específicas de la aplicación en el esquema XMP personalizado.
Diccionario de información del documento
El diccionario Info almacena principalmente valores de cadenas de texto. Es compacto y ampliamente compatible, pero limitado. Use el diccionario Info para compatibilidad con herramientas antiguas y prefiera XMP en otros casos.
Sincronización de metadatos
Es una buena práctica mantener sincronizados ambos sistemas de metadatos para evitar inconsistencias que puedan confundir a lectores y herramientas automatizadas.
Use PdfDocument.SyncMetadata para alinear los valores XMP y Info de modo que los campos correspondientes coincidan. El método rellena las propiedades Info que faltan a partir de XMP y, de forma similar, completa los campos XMP que faltan a partir de Info. Establezca preferXmp: true cuando XMP sea su fuente autoritativa, o false cuando el diccionario Info deba tener prioridad.
pdf.SyncMetadata(preferXmp: true);
Consulte la sección Remarks en la documentación de SyncMetadata para obtener información detallada sobre qué propiedades sincroniza el método.
Configuración de etiquetas de página y preferencias del visor
Un PDF recién creado puede beneficiarse de numeración de páginas explícita, preferencias del visor ajustadas con precisión y un diseño de página elegido para presentar el contenido del documento de forma más eficaz. Estos ajustes afectan cómo los lectores ven y navegan el archivo al abrirlo.
Etiquetas de página
Las etiquetas de página son metadatos que indican a los visores PDF qué etiqueta mostrar para cada página. Úselas cuando la numeración visible deba diferir del índice físico de la página. Por ejemplo, cuando desea i, ii, iii para el contenido preliminar y 1, 2, 3 para el texto principal de su PDF.
Este código C# muestra cómo etiquetar páginas PDF con números romanos en minúscula para las tres primeras páginas y numeración arábiga empezando en 1 para el resto.
using var pdf = new PdfDocument();
for (int i = 0; i < 8; i++)
pdf.AddPage();
pdf.PageLabels.AddRange(0, 2, PdfPageNumberingStyle.LowercaseRoman);
pdf.PageLabels.AddRange(3, PdfPageNumberingStyle.DecimalArabic);
pdf.Save("with-page-labels.pdf");
Preferencias del visor PDF
Las preferencias del visor PDF son recomendaciones incrustadas en el documento que sugieren cómo debería presentarlo un visor. Por ejemplo, puede especificar que el visor oculte las barras de herramientas, centre la ventana o ajuste la ventana a la página. Las preferencias del visor complementan el diseño de página y la configuración de acción de apertura.
Así es como se cambian las preferencias de visualización PDF usando Docotic.Pdf:
using var pdf = new PdfDocument();
pdf.ViewerPreferences.DisplayTitle = false;
pdf.ViewerPreferences.FitWindow = true;
pdf.ViewerPreferences.HideToolBar = true;
pdf.ViewerPreferences.HideMenuBar = true;
pdf.ViewerPreferences.HideWindowUI = true;
pdf.ViewerPreferences.CenterWindow = true;
pdf.Save("with-viewer-prefs.pdf");
Tenga en cuenta que, según su configuración, Adobe Acrobat y otros visores pueden ignorar estas preferencias.
Diseño de página y modo de página
El diseño de página determina cómo se organizan las páginas cuando se abre el documento: una página a la vez, una columna continua o pliegos de dos páginas. El modo de página controla qué paneles de la interfaz de usuario están visibles al abrir: marcadores/outlines, adjuntos, miniaturas o ninguno.
Así es como se especifica que el PDF creado se muestre como un pliego de dos páginas, con la página izquierda primero, y con el panel de miniaturas visible al abrir:
using var pdf = new PdfDocument();
for (int i = 0; i < 7; i++)
{
var page = i > 0 ? pdf.AddPage() : pdf.Pages[0];
page.Canvas.FontSize = 36;
page.Canvas.DrawString(100, 100, $"Page {i + 1}");
}
pdf.PageLayout = PdfPageLayout.TwoPageLeft;
pdf.PageMode = PdfPageMode.UseThumbs;
pdf.Save("with-layout-and-mode.pdf");
Guardado de PDFs
Docotic.Pdf puede producir diferentes archivos PDF o flujos a partir del mismo documento que creó o editó. Estas salidas pueden cumplir distintas versiones del formato PDF, variar en longitud de bytes y requerir diferentes cantidades de memoria para generarse.
La forma en que la biblioteca produce los bytes de un PDF depende de las opciones de guardado. Cuando no especifica opciones de guardado de forma explícita, los métodos Save, SignAndSave y TimestampAndSave de un objeto PdfDocument usan configuraciones predeterminadas. Estas opciones predeterminadas se eligen cuidadosamente y funcionan bien para la mayoría de los escenarios, pero puede que aún necesite ajustarlas.
Consulte la documentación de la clase PdfSaveOptions para obtener información detallada sobre las opciones disponibles y sus valores predeterminados. Las secciones siguientes destacan algunas de las opciones más importantes y ofrecen recomendaciones prácticas.
Versión de PDF
Docotic.Pdf usa flujos de objetos de forma predeterminada para lograr una mejor compresión de los archivos que produce. Como resultado, la biblioteca crea archivos y flujos PDF 1.5 de forma predeterminada.
PDF 1.5 requiere Adobe Reader 6 (lanzado en 2003) o posterior para ver los documentos producidos. Esto normalmente no es un problema, a menos que deba admitir herramientas heredadas, visores antiguos o dispositivos integrados que solo aceptan versiones PDF más antiguas.
Así es como se guarda con una versión de archivo PDF más antigua:
using var pdf = new PdfDocument();
var options = new PdfSaveOptions
{
Version = PdfVersion.Pdf14,
UseObjectStreams = false,
};
pdf.Save("version-1.4.pdf", options);
Para guardar con la versión PDF 1.4, los flujos de objetos también deben deshabilitarse. La biblioteca no usará una versión más antigua si el documento contiene funciones introducidas en versiones posteriores.
Reducción del tamaño del archivo
Varias opciones de guardado, cuando se establecen en true, hacen que Docotic.Pdf produzca archivos más pequeños en bytes: RemoveUnusedObjects, OptimizeIndirectObjects, WriteWithoutFormatting y UseObjectStreams.
Así es como se producen PDFs sin objetos no referenciados ni espacios en blanco adicionales, con los datos empaquetados densamente en flujos de objetos:
using var pdf = new PdfDocument();
var options = new PdfSaveOptions
{
UseObjectStreams = true,
RemoveUnusedObjects = true,
OptimizeIndirectObjects = true,
WriteWithoutFormatting = true,
};
pdf.Save("optimized.pdf", options);
Estas opciones son más eficaces cuando el PDF se reescribe por completo. Durante un guardado incremental, solo se aplican a la revisión recién agregada y no pueden limpiar ni optimizar partes anteriores del archivo.
Actualizaciones incrementales
Docotic.Pdf puede actualizar PDFs de forma incremental. Cuando WriteIncrementally es true, la biblioteca agrega los cambios al archivo existente en lugar de reescribirlo. La información previa de referencia cruzada y de objetos permanece intacta. Los datos agregados se llaman actualización incremental, y la actualización actual junto con todas las anteriores constituye una nueva revisión del archivo.
Las actualizaciones incrementales no son posibles para documentos recién creados porque no hay una revisión anterior a la que anexar. La biblioteca ignora esta opción para documentos nuevos y los escribe en modo no incremental.
Cuando se requieren actualizaciones incrementales
Al agregar una nueva firma digital a un documento que ya contiene firmas, debe guardar el archivo de forma incremental. Lo mismo aplica al actualizar un archivo previamente firmado con nuevas anotaciones o datos de formulario. Reescribir el archivo completo en estos casos invalidaría las firmas existentes.
Al mismo tiempo, es mejor realizar un guardado no incremental (completo) antes de aplicar la primera firma digital, de modo que la base firmada sea un archivo limpio y completamente reescrito. Firmar un documento que contiene problemas estructurales en revisiones anteriores puede provocar problemas inesperados de validación de la firma.
Los anexos incrementales también son necesarios en flujos de trabajo que deben preservar un historial de revisiones auditable o imponer almacenamiento de documentos solo de anexado.
Beneficios del uso de actualizaciones incrementales
Las actualizaciones incrementales permiten múltiples firmas en el mismo archivo y posibilitan un conjunto limitado de modificaciones posteriores a la firma, como rellenar campos de formulario, sin invalidar las firmas existentes.
Este enfoque además ofrece guardados más rápidos para cambios pequeños, ya que solo se escribe la información modificada. También conserva el historial de revisiones del documento, que es esencial para auditoría y otros flujos de trabajo impulsados por cumplimiento normativo.
Problemas y trampas que evitar
Las actualizaciones incrementales no pueden aplicar compresión global ni eliminar objetos obsoletos en todo el archivo porque solo anexan los objetos modificados. Como resultado, generalmente producen archivos más grandes y menos optimizados que una reescritura completa.
El tamaño del archivo crece con cada revisión, incluso cuando no hay objetos no utilizados, porque todas las revisiones anteriores permanecen incrustadas en el archivo y continúan ocupando espacio.
La información sensible o incorrecta de revisiones anteriores sigue siendo recuperable, y los problemas existentes del formato PDF o los defectos estructurales en revisiones previas no se corrigen al anexar nuevos datos.
Por último, algunos visores y herramientas de procesamiento tienen dificultades con PDFs de varias revisiones. Antes de depender de actualizaciones incrementales, asegúrese de que todos los consumidores de sus documentos puedan manejar archivos con múltiples revisiones.
Pruebas de la salida PDF
Las pruebas automáticas de PDF protegen las versiones frente a regresiones en contenido y diseño al comparar los PDFs generados con PDFs base almacenados en su repositorio o en el almacenamiento de artefactos. Las bases de referencia ayudan a detectar cambios accidentales en texto, fuentes, imágenes o diseño y reducen la necesidad de control de calidad manual en cada compilación.
Combine comprobaciones estructurales, extracción de texto y comparaciones visuales para obtener los resultados más fiables.
Comparación rápida de enfoques
| Método | Velocidad | Sensibilidad | Mejor para |
|---|---|---|---|
| Comparación estructural | Rápida | Alta: detecta cambios a nivel de objeto | Pruebas de regresión que deben confirmar que dos versiones del mismo documento son estructuralmente idénticas |
| Extracción de texto | Rápida | Media: normalmente ignora cambios de diseño | Verificar contenido semántico y tablas |
| Diferencias visuales | Más lenta | Alta: detecta cambios de contenido y de renderizado/diseño | Detectar regresiones visuales |
Comparación de la estructura del documento
Use PdfDocument.DocumentsAreEqual para comparar grafos de objetos PDF, la versión PDF y el almacén de seguridad del documento (DSS), ignorando propiedades del documento dependientes del tiempo. El método también ignora los metadatos del documento, los identificadores del trailer y otras propiedades generadas automáticamente.
Este método es ideal para flujos de trabajo de prueba de documentos PDF que deben garantizar que no se agregaron ni eliminaron objetos inesperados. DocumentsAreEqual admite sobrecargas para archivos y flujos, y puede comparar PDFs cifrados.
Un ejemplo completo que demuestra esta técnica está disponible en los ejemplos de Docotic.Pdf. Además de mostrar cómo usar el método en aplicaciones .NET normales, el ejemplo también demuestra cómo usar DocumentsAreEqual en Native AOT aplicaciones.
Verificación de PDFs mediante texto extraído
Extraiga texto del documento completo de una sola vez o de páginas individuales una tras otra y compare las cadenas. Puede usar opciones de extracción de texto para ajustar el proceso, como excluir el rectángulo del pie de página. Para facilitar la comparación, puede dividir el texto extraído en líneas o palabras.
Para comprobaciones estructuradas, primero extraiga texto con posición, fuente y otra información detallada sobre cada fragmento, palabra o carácter. Luego compare cada elemento extraído con el elemento de referencia correspondiente.
Detección de diferencias visuales
Comience renderizando páginas PDF a imágenes y compare cada imagen con la imagen de referencia. Use bibliotecas especializadas como ImageSharp.Compare o Magick.NET para detectar diferencias en las imágenes.
Prefiera una comparación estricta píxel por píxel, de modo que cada píxel correspondiente en ambas imágenes deba coincidir. Si sus requisitos permiten pequeñas variaciones de renderizado, puede ajustar la lógica de comparación para tolerar diferencias menores, pero la igualdad exacta de píxeles proporciona los resultados más fiables.
Considere usar hash como una comprobación previa rápida para determinar si dos imágenes probablemente son idénticas sin realizar una comparación completa píxel por píxel. Calcule un hash SHA-256 para cada imagen renderizada y, si los hashes coinciden, las imágenes son casi con seguridad iguales. Si los hashes difieren, ejecute entonces la comparación completa píxel por píxel.
Conclusión
Docotic.Pdf proporciona un conjunto de herramientas completo y multicapa para crear y manipular PDFs en .NET. Los desarrolladores pueden elegir entre control de bajo nivel con Core API, generación de documentos de alto nivel con Layout API o conversión de HTML a PDF para flujos de trabajo ya basados en tecnologías web.
La biblioteca también admite PDFs basados en imágenes, generación guiada por plantillas y un conjunto rico de funciones interactivas como anotaciones, vínculos, marcadores, acciones de JavaScript y acciones de apertura.
Para garantizar la fiabilidad, Docotic.Pdf incluye métodos para probar la salida PDF, de modo que los cambios en su aplicación no introduzcan regresiones ni diferencias inesperadas.