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

Creación de documentos

Por supuesto, necesitas generar un documento PDF con tus datos. Pero con frecuencia también querrás cifrar el archivo PDF con contraseñas. Y normalmente querrás añadir metadatos PDF al archivo de salida.

Sigue leyendo para saber cómo indicar al generador que cifre archivos PDF. Cómo especificar el autor y las palabras clave del documento.

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

Creación de documentos PDF

Crear y generar

El punto de entrada de Layout API es la clase PdfDocumentBuilder. Empiezas creando una instancia de la clase con el método Create. Para generar un PDF, llamas al método Generate de la clase.

Generate puede guardar la salida en un archivo o en un flujo. Cualquiera de las dos versiones del método requiere un delegado del tipo Action<Document> como segundo parámetro. En el delegado, describes el documento que quieres obtener. La biblioteca generará un PDF basado en la descripción.

Cifrado

Para cifrar el PDF de salida, llama al método Encryption antes del método Generate.

Debes crear y proporcionar un controlador de cifrado. Para cifrar PDF con contraseñas, usa un controlador del tipo PdfStandardEncryptionHandler.

PdfDocumentBuilder.Create()
    .Encryption(new PdfStandardEncryptionHandler("owner", "user"))
    .Generate("encrypted-with-password.pdf", doc => doc.Pages(_ => { }));

También puedes cifrar PDF con certificados. Consulta el artículo Cifrar documentos PDF. Contiene información detallada sobre los controladores de cifrado y los permisos PDF.

Metadatos de PDF

En algunos flujos de trabajo, es muy importante especificar correctamente las palabras clave PDF y el autor PDF en el PDF de salida. Layout API ofrece una forma sencilla de hacerlo. Llama al método Info antes del método Generate y proporciona los valores de metadatos en el delegado.

PdfDocumentBuilder.Create()
    .Info(info =>
    {
        info.Author = $"{Environment.UserName}";
        info.Title = "Generate encrypted PDF with custom metadata";
        info.Keywords = "Metadata keywords encryption";
    })
    .Generate("metadata.pdf", doc => doc.Pages(_ => { }));

Opciones

Para el mismo contenido, la biblioteca puede crear archivos PDF con distinta estructura interna. Estas opciones afectarán al PDF de salida.

Versión

Usa el método Version para establecer la versión mínima del formato PDF para el PDF de salida.

PdfDocumentBuilder.Create()
    .Version(PdfVersion.Pdf17)
    .Generate("version.pdf", doc => doc.Pages(_ => { }));

Ten en cuenta que la biblioteca puede crear un PDF con una versión superior a la especificada. Ocurre cuando el contenido del documento requiere una versión más reciente. Dicho de otro modo: cuando el documento usa funciones no disponibles en la versión especificada del estándar PDF.

Flujos de objetos

De forma predeterminada, la biblioteca usa flujos de objetos en los PDF generados. Esto ayuda a producir archivos más pequeños y mejor comprimidos.

Puedes indicar a la API que cree archivos PDF sin flujos de objetos usando el método ObjectStreams.

PdfDocumentBuilder.Create()
    .ObjectStreams(false)
    .Generate("no-object-streams.pdf", doc => doc.Pages(_ => { }));

Te sugiero seguir usando flujos de objetos salvo que existan requisitos normativos. O cuando otras partes de tu flujo de trabajo no puedan procesar documentos con flujos de objetos.

Proveedor de flujos

La biblioteca usa flujos como almacenamiento intermedio. Al generar un PDF, lo hace para imágenes y otros objetos grandes. La biblioteca obtiene los flujos a través del proveedor de flujos. Siempre hay uno asociado con la instancia actual de PdfDocumentBuilder.

La biblioteca usa PdfMixedStorageStreamProvider de forma predeterminada. Esta implementación del proveedor de flujos proporciona flujos que mantienen los datos en memoria. Estos flujos vacían su contenido en archivos temporales cuando hay demasiados datos. Esto permite reducir el consumo de memoria y evitar la fragmentación de LOH.

Puedes usar tu propia implementación de la interfaz IPdfStreamProvider al generar archivos PDF. Una razón para el cambio podría ser operaciones de disco lentas y/o costosas. Los entornos en la nube podrían encajar en esta descripción.

Este código muestra cómo generar un PDF completamente en memoria, sin archivos temporales. Ten en cuenta que esto requerirá bastante más memoria que con las opciones predeterminadas.

using var memoryOnlyProvider = new PdfMemoryStreamProvider();
PdfDocumentBuilder.Create()
    .StreamProvider(memoryOnlyProvider)
    .Generate("created-without-temp-files.pdf", doc => doc.Pages(_ => { }));

La biblioteca finalmente llama a Dispose para cada flujo que obtiene a través del proveedor de flujos. Debes disponer tú mismo de la instancia del proveedor de flujos.