Questa pagina può contenere testo tradotto automaticamente.

Come creare documenti PDF in C# e VB.NET

Questo articolo descrive diversi modi per creare documenti PDF in .NET con l'aiuto della libreria Docotic.Pdf. Si tratta di una libreria .NET ad alte prestazioni, scritta interamente in C# e priva di dipendenze esterne, per la creazione, la modifica, la conversione e l'elaborazione di documenti PDF.

Illustrazione che mostra la creazione di PDF e l'automazione dei documenti con Docotic.Pdf.

Nelle sezioni seguenti, presento i principali approcci per la creazione di PDF con Docotic.Pdf:

  • Utilizzo dell'API Core, che fornisce un controllo di basso livello su testo, grafica e dettagli interni del PDF. Questa opzione è ideale per layout personalizzati, documenti con molti elementi grafici e funzionalità avanzate.
  • Utilizzo dell'API Layout di alto livello, che supporta paragrafi, tabelle, intestazioni, piè di pagina e impaginazione automatica. Questa API è ideale quando si desidera creare documenti strutturati senza dover calcolare manualmente le posizioni.
  • Conversione da HTML a PDF con supporto per SVG e altri formati web. Questo approccio è particolarmente utile quando la soluzione in uso produce già documenti HTML e si necessita di versioni PDF di tali file HTML e CSS.
  • Creazione di PDF da immagini. Questo metodo è utile per documenti scansionati, report basati su immagini, ricevute e qualsiasi flusso di lavoro che inizi con immagini raster.
  • Unione o divisione di PDF. Questa è un'ottima soluzione per assemblare report, elaborare i caricamenti degli utenti, combinare documenti correlati e ristrutturare PDF di grandi dimensioni.
  • Creazione di PDF da modelli. Questo approccio funziona bene quando è necessaria una formattazione coerente per documenti generati in batch, come ricevute, moduli fiscali, contratti di lavoro e altri tipi di documenti ripetibili.

Altri argomenti trattati nella guida includono:

Creazione di PDF con l'API Core

L'API Core è il fondamento della creazione di PDF in Docotic.Pdf. Offre un controllo completo e di basso livello sul posizionamento di testo, immagini e grafica vettoriale su un'area di disegno PDF tramite la sua API Canvas. Questa API di disegno è un sottoinsieme dell'API Core e fornisce i metodi e le proprietà utilizzati per aggiungere contenuti a pagine e altri oggetti con aree di disegno. Oltre al rendering, l'API Core supporta anche annotazioni, campi modulo, livelli, segnalibri e altre funzionalità PDF.

Ecco un esempio di codice C# che crea un semplice PDF utilizzando tre operazioni fondamentali: disegnare testo, posizionare un'immagine e renderizzare grafica vettoriale su un'area di disegno.

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");

Questa panoramica introduce solo una piccola parte delle funzionalità dell'API Core. Per argomenti avanzati, consultare l'articolo dettagliato sulla creazione di PDF con l'API Core. L'articolo tratta argomenti quali la misurazione del testo, la gestione degli spazi colore, l'applicazione del ritaglio, il riempimento di aree con motivi, la gestione della trasparenza e altre funzionalità.

Generazione di PDF con l'API Layout

L'API Layout è un motore di alto livello per la creazione di documenti che offre il modo più semplice ed efficiente per generare PDF complessi e ricchi di contenuti.

Utilizzando l'API, i PDF vengono composti a partire da elementi strutturali come pagine, contenitori, blocchi di testo, immagini, tabelle, collegamenti, intestazioni, piè di pagina e altro ancora. Invece di calcolare le coordinate o gestire manualmente la paginazione, si descrive la struttura del documento e si lascia che il motore di layout si occupi del resto.

Questo esempio illustra come creare un PDF utilizzando l'API Layout, basandosi sul layout dichiarativo anziché sul posizionamento manuale.

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);
        });
    }));

Consulta la guida dettagliata per imparare a utilizzare l'API Layout durante la generazione di PDF nelle applicazioni .NET.

Conversione di contenuti web tramite API da HTML a PDF

Docotic.Pdf, abbinato al suo componente aggiuntivo gratuito HtmlToPdf, offre un motore di conversione da HTML a PDF moderno e di alta qualità, basato su Chrome. È possibile convertire HTML moderno e altri contenuti web, come immagini SVG o WebP, in documenti PDF di alta qualità utilizzando l'API fornita dal componente aggiuntivo.

L'API HTML to PDF può creare PDF da pagine HTML complete o da frammenti HTML. È possibile convertire contenuti da URL, stringhe HTML grezze e file HTML locali. Queste ultime due opzioni semplificano la generazione di PDF da modelli HTML.

Vedi un esempio di come produrre un PDF da un modello HTML:

public static async Task HelloHtmlTemplate()
{
    static string GetUserName()
    {
        // Replace with real logic: form input, API call, config, 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");
}

Per maggiori dettagli ed esempi, consulta la nostra panoramica approfondita sulla conversione da HTML a PDF.

Creazione di PDF da immagini

Docotic.Pdf offre un metodo flessibile e intuitivo per gli sviluppatori per convertire le immagini in PDF. La libreria supporta i formati immagine JPEG, BMP, GIF, PNG, TIFF e JPEG 2000 tramite l'API Core.

Illustrazione che mostra come Docotic.Pdf converte più file immagine in un singolo documento PDF.

Quando supportato dal formato PDF, Docotic.Pdf incorpora i byte delle immagini così come sono, evitando la decodifica e la ricodifica dei pixel per preservare la compressione originale. La libreria preserva anche lo spazio colore quando possibile.

Inoltre, i formati SVG e WebP sono supportati tramite l'API da HTML a PDF. Quando è necessario posizionare immagini accanto a etichette o descrizioni, l'API Layout consente di disporre e allineare gli elementi con il minimo sforzo.

Come unire più immagini in un unico PDF

Con Docotic.Pdf, puoi convertire facilmente una serie di immagini in un singolo PDF, posizionando un'immagine su ogni pagina.

L'esempio seguente carica le immagini da file e le visualizza ciascuna su una pagina separata. Ogni immagine viene ridimensionata per adattarsi alla pagina e centrata per un layout pulito e uniforme.

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);
}

Gestione di immagini TIFF e GIF multipagina

Docotic.Pdf supporta completamente i file TIFF e GIF multipagina. Quando si aggiungono immagini a un PDF, utilizzare il metodo OpenImage anziché CreateImage se una delle immagini può contenere più pagine.

Il codice seguente mostra come convertire un file TIFF in PDF, e funziona sia per immagini a pagina singola che per immagini multipagina:

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);
}

È possibile utilizzare lo stesso metodo per convertire un file GIF in PDF. Si applica anche ad altri formati di immagine, sebbene sia più elaborato del necessario per i formati che contengono un solo fotogramma.

Unire e dividere i PDF

Essendo una libreria .NET completa, Docotic.Pdf consente di creare nuovi PDF unendo, estraendo e riorganizzando pagine da documenti esistenti.

Quando si uniscono PDF, la libreria non solo aggiunge pagine da un altro documento, ma anche livelli, segnalibri, etichette di pagina, codice JavaScript condiviso, destinazioni (link) e file incorporati. Per maggiori dettagli e per indicazioni su come ridurre le dimensioni dei PDF combinati, consultare l'articolo sull'unione di PDF.

I PDF con firma digitale non possono essere uniti senza invalidare le firme esistenti. Per preservare le firme, creare un portfolio PDF anziché unire i documenti. Un'altra opzione è unire prima i PDF e poi applicare una nuova firma digitale al documento combinato.

Docotic.Pdf consente anche di copiare ed estrarre pagine in nuovi documenti. Tutto il contenuto associato alle pagine copiate viene conservato, incluse annotazioni, controlli modulo, contenuto strutturato, livelli e altri dati correlati. Per esempi pratici, consultare l'articolo su come dividere i PDF in .NET. L'articolo spiega anche come estrarre o rimuovere pagine.

Lavorare con i modelli PDF

I modelli PDF sono file PDF predefiniti che fungono da struttura di base per la creazione di nuovi documenti. Sono utili quando è necessario produrre PDF con un layout coerente pur inserendo dati diversi. Se si desidera separare l'aspetto grafico dai dati stessi, i modelli PDF rappresentano un'ottima soluzione.

I modelli possono essere PDF basati su moduli o PDF statici senza moduli. Entrambi i tipi hanno lo stesso scopo. Inoltre, i modelli basati su moduli includono elementi interattivi che, se non vengono appiattiti, possono raccogliere informazioni dagli utenti.

Creazione di PDF da modelli basati su moduli

I modelli basati su moduli contengono solitamente AcroForms, il tipo standard e ampiamente supportato di modulo PDF interattivo. Per generare un PDF da un modello di questo tipo, in genere è necessario:

  • compilare ogni campo segnaposto
  • appiattire i campi per impedire ulteriori modifiche
  • salvare il risultato come nuovo PDF

Ecco un codice C# che individua un campo di testo segnaposto in base al nome, gli assegna un valore, appiattisce il campo e salva il risultato, creando un PDF dal modello:

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");

Se il tuo modello contiene molti segnaposto, puoi importare i dati FDF anziché compilare ogni campo singolarmente. Puoi anche utilizzare PdfDocument.FlattenControls per appiattire tutti i campi contemporaneamente.

Creazione di PDF da modelli statici senza moduli

Se il modello non contiene campi modulo, dovrai disegnare nomi e altri dati direttamente sull'area di lavoro della pagina. I modelli PDF statici in genere contengono segnaposto visivi fissi come testo, immagini o aree vuote. Per generare un PDF dal modello, dovrai riempire queste aree vuote e sostituire il testo e le immagini segnaposto tramite programmazione.

Zone vuote

Utilizza l'API Canvas per posizionare testo e immagini nelle aree vuote. Nei casi più semplici, quando sono necessarie solo piccole modifiche come l'aggiunta di un nome e una foto, questo approccio funziona bene. È necessario conoscere le coordinate e le dimensioni delle aree e, per posizionare correttamente il testo, potrebbe essere necessario misurarlo prima e poi allinearlo di conseguenza.

Lavorare con testo a lunghezza variabile o su più righe è più complesso, ma comunque fattibile. Combinando DrawText, DrawString e i metodi per misurare il testo, è possibile mandare a capo e posizionare le righe secondo necessità. Se il modello contiene più di poche aree di questo tipo, considera un approccio alternativo come la generazione di PDF con l'API Layout.

Testo segnaposto

Docotic.Pdf offre anche metodi per trovare e sostituire il testo. Tuttavia, utilizzare la ricerca testuale come meccanismo di template non è solitamente più semplice che lavorare con aree segnaposto vuote. Prima di inserire nuovo contenuto, è necessario individuare il frammento di testo esatto e rimuoverlo in modo pulito.

Immagini segnaposto

I modelli statici possono includere immagini segnaposto per avatar utente o foto di prodotto. Per trovare un'immagine segnaposto, è necessario enumerare la raccolta di immagini visualizzate su ciascuna pagina. Per ogni immagine visualizzata, è possibile ottenere le sue dimensioni e la sua posizione visibili. Per sostituire il segnaposto, utilizzare 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");

Un'altra opzione è quella di disegnare una nuova immagine sull'area occupata dall'immagine segnaposto, ma questo in genere aumenta le dimensioni del PDF risultante senza una valida ragione.

Progettazione di segnaposto per una facile sostituzione

Per i modelli statici, è utile progettare il layout con aree prevedibili e ben definite sia per il testo che per le immagini. Lascia uno spazio sufficiente intorno alle aree che conterranno contenuti di lunghezza variabile e utilizza immagini segnaposto neutre che corrispondano alle proporzioni che prevedi di inserire in seguito.

Se il tuo modello utilizza testo segnaposto che intendi sostituire, puoi semplificare il flusso di lavoro utilizzando caselle di testo anziché testo semplice. Aggiungi una casella di testo di sola lettura e senza bordi al modello e inserisci il testo segnaposto al suo interno. Quando generi il PDF finale, apri il modello, individua la casella di testo per nome e assegna il nuovo valore direttamente con box.Text = "nuovo testo";. Infine, appiattisci la casella di testo per impedire ulteriori modifiche.

Aggiunta di elementi interattivi

Le funzionalità interattive trasformano un PDF statico in un documento dinamico e di facile navigazione, arricchito da annotazioni e markup. Azioni e JavaScript consentono l'automazione direttamente all'interno del PDF.

Annotazioni

Le annotazioni sono oggetti allegati a una pagina che rappresentano commenti, evidenziazioni, allegati e altri elementi interattivi. Sono visibili nel contenuto della pagina e supportano i flussi di lavoro di revisione e la collaborazione.

L'esempio C# seguente mostra come aggiungere annotazioni di testo, note anche come note adesive, a una pagina PDF utilizzando 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");

L'esempio seguente mostra come evidenziare il testo e altri contenuti per attirare l'attenzione sulle parti chiave di 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");

Gli standard PDF definiscono diversi tipi di collegamenti PDF. I più importanti e diffusi sono i collegamenti interni e i collegamenti ipertestuali.

I collegamenti interni, chiamati anche azioni GoTo, consentono di passare a una pagina o a una destinazione specifica all'interno dello stesso PDF. Sono utili per i riferimenti incrociati e la navigazione interna.

Ecco un codice C# che crea un collegamento dalla prima pagina alla pagina con indice 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");

L'API Layout offre un altro modo per creare collegamenti interni che non richiedono un posizionamento assoluto.

I collegamenti esterni, chiamati anche azioni URI, aprono un URL web. È possibile aggiungere un collegamento ipertestuale a una pagina PDF utilizzando il metodo PdfPage.AddHyperlink. In caso contrario, la procedura è la stessa dei collegamenti interni.

Segnalibri

I segnalibri, detti anche schemi, sono scorciatoie o collegamenti speciali che aiutano i lettori a navigare rapidamente verso sezioni o pagine specifiche. Quando il lettore fa clic su un segnalibro, l'applicazione di visualizzazione si sposta alla parte designata del documento.

Gli schemi vengono visualizzati nel pannello dei segnalibri del visualizzatore e forniscono una struttura di navigazione gerarchica simile a un indice di un libro, ma interattiva. Gli schemi dei PDF possono includere segnalibri principali e segnalibri annidati, il che semplifica la strutturazione di documenti di grandi dimensioni.

L'esempio seguente mostra come creare segnalibri nei PDF utilizzando C# e Docotic.Pdf. Il codice crea tre segnalibri di primo livello. Il secondo segnalibro contiene un segnalibro annidato.

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");

I segnalibri differiscono dall'indice che si trova stampato sulle pagine di un libro fisico o visualizzato in un PDF. È possibile creare un indice a livello di programmazione, misurando le intestazioni e scrivendo voci con i numeri di pagina.

Per un approccio alternativo alla creazione di un indice utilizzando l'API Layout, consultare il codice correlato nel nostro repository di esempio.

Scripting PDF

Le azioni JavaScript sono tra le funzionalità interattive più potenti. PDF JavaScript è un sottoinsieme di JavaScript che espone le API del documento e del visualizzatore. Viene utilizzato per la convalida dei moduli, i calcoli, le finestre di dialogo dell'interfaccia utente e piccole attività di automazione.

È possibile allegare script ad annotazioni, segnalibri, controlli dei moduli o azioni di apertura. Con Docotic.Pdf è possibile incorporare codice JavaScript in un PDF. Il codice può convalidare l'input del modulo, calcolare valori, mostrare o nascondere campi o eseguire interazioni con il visualizzatore.

La raccolta di JavaScript condiviso contiene script memorizzati a livello di documento. Questi script possono essere riutilizzati da più azioni. In altre parole, gli script condivisi sono utili per funzioni di utilità e logiche condivise. Contribuiscono a ridurre la duplicazione e a semplificare la manutenzione.

Il codice seguente definisce uno script condiviso che visualizza un messaggio di avviso nel visualizzatore PDF e mostra come attivare tale script assegnandolo all'azione di clic del pulsante.

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");

Lo script nell'esempio è semplice, ma è possibile creare azioni JavaScript di qualsiasi complessità. La documentazione dell'API JavaScript di Adobe fornisce molti metodi utilizzabili. Tieni presente che i visualizzatori non Adobe in genere supportano solo un sottoinsieme dell'API.

Azioni aperte

Un'azione di apertura è un'azione che il visualizzatore PDF esegue all'apertura del documento. Gli utilizzi tipici includono l'apertura a una pagina specifica, l'esecuzione di una routine di inizializzazione JavaScript o l'impostazione delle preferenze del visualizzatore. Non ci sono restrizioni sul tipo di azione di apertura.

L'esempio seguente mostra come creare un'azione di apertura GoTo. Il codice aggiunge del testo alla seconda pagina e imposta un'azione di apertura che fa sì che il visualizzatore navighi automaticamente a quella pagina all'apertura del 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");

Tieni presente che non tutti i visualizzatori eseguono le azioni di apertura JavaScript. Alcuni le ignorano o chiedono prima all'utente di eseguirle. Alcuni visualizzatori bloccano completamente le azioni di apertura.

Per verificare se un PDF contiene un'azione di apertura, caricalo in un oggetto PdfDocument e controlla la proprietà OnOpenDocument. Se la proprietà è null, il documento non ha alcuna azione di apertura definita.

Applicazione della crittografia e delle firme digitali

La crittografia e le firme digitali affrontano due aspetti complementari della sicurezza dei PDF che create. La crittografia controlla chi può aprire un documento e cosa può farne, mentre le firme attestano chi ha creato o approvato il file e confermano che non è stato alterato.

La protezione tramite password consente di impostare regole di accesso durante la creazione. È possibile assegnare una password di apertura per limitare la visualizzazione e una password di proprietario per definire autorizzazioni come la stampa, la copia, la modifica o la compilazione di moduli. La crittografia con certificato offre una protezione più robusta e specifica per il destinatario ed è particolarmente utile quando si distribuiscono PDF riservati a più persone senza dover utilizzare una password condivisa. Per maggiori dettagli, consultare l'articolo sulla crittografia dei PDF con password e certificati.

Le firme digitali aggiungono autenticità e integrità al momento della creazione. Docotic.Pdf può firmare i PDF utilizzando certificati provenienti da file, dal Microsoft Store, da token hardware, HSM o servizi di chiavi cloud. È possibile includere timestamp e dati di convalida a lungo termine, in modo che le firme rimangano verificabili anche molto tempo dopo la produzione del documento. Sono supportati anche flussi di lavoro di firma esterni, tra cui PKCS#11 e KMS cloud.

Imposta i metadati PDF

I metadati PDF sono informazioni descrittive incorporate in un documento, come titolo, autore, oggetto, parole chiave, date di creazione e campi simili. Aiutano software, motori di ricerca e sistemi di gestione documentale a comprendere il contenuto di un file senza doverlo aprire.

Un documento PDF può contenere metadati in due sistemi coesistenti:

  • Metadati XMP
  • Dizionario delle informazioni del documento (dizionario Info)

Illustrazione del processo di aggiunta di metadati XMP a un documento PDF utilizzando Docotic.Pdf.

XMP è il formato più ricco, strutturato e standardizzato per l'incorporamento di metadati descrittivi. Il dizionario Info è semplice e ampiamente supportato, ma limitato, ed è stato deprecato nello standard PDF 2.0 (ISO 32000-2) a favore dei metadati XMP. Docotic.Pdf è in grado di leggere e scrivere entrambi i sistemi e fornisce un metodo di supporto per mantenerli sincronizzati.

Docotic.Pdf aggiorna automaticamente alcuni metadati prima di salvare un file PDF. Ad esempio, la libreria imposta per impostazione predefinita i valori di Produttore e Autore. Utilizzare opzioni di salvataggio per modificare questo comportamento e preservare i valori dei metadati impostati esplicitamente.

Metadati XMP

Utilizza la proprietà PdfDocument.Metadata per accedere e modificare i metadati XMP in un PDF. Tramite questa proprietà puoi lavorare con schemi noti come XMP Core, Dublin Core e lo schema PDF, nonché gestire i tuoi metadati personalizzati.

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 supporta array, strutture e valori tipizzati, il che lo rende adatto a metadati complessi. Il codice sopra riportato mostra anche come memorizzare proprietà specifiche dell'applicazione nello schema XMP personalizzato.

Dizionario delle informazioni del documento

Il dizionario Info memorizza principalmente valori di stringhe di testo. È compatto e ampiamente supportato, ma presenta delle limitazioni. Utilizzate il dizionario Info per la compatibilità con strumenti meno recenti, mentre in altri casi è preferibile utilizzare XMP.

Sincronizzazione dei metadati

È buona norma mantenere sincronizzati entrambi i sistemi di metadati per evitare incongruenze che possono confondere i lettori e gli strumenti automatizzati.

Utilizzare PdfDocument.SyncMetadata per allineare i valori XMP e Info in modo che i campi corrispondenti corrispondano. Il metodo riempie le proprietà mancanti di Info con i dati XMP e, analogamente, popola i campi mancanti di XMP con i dati Info. Impostare preferXmp: true quando XMP è la fonte autorevole, oppure false quando il dizionario Info deve avere la precedenza.

pdf.SyncMetadata(preferXmp: true);

Consultare la sezione Osservazioni nella documentazione di SyncMetadata per informazioni dettagliate su quali proprietà vengono sincronizzate dal metodo.

Configurazione delle etichette di pagina e delle preferenze del visualizzatore

Un PDF appena creato può trarre vantaggio da una numerazione esplicita delle pagine, da preferenze di visualizzazione ottimizzate e da un layout di pagina scelto per presentare il contenuto del documento in modo più efficace. Queste impostazioni influenzano il modo in cui i lettori visualizzano e navigano il file.

Etichette di pagina

Le etichette di pagina sono metadati che indicano ai visualizzatori di PDF quale etichetta visualizzare per ogni pagina. Utilizzatele quando la numerazione visibile deve essere diversa dall'indice fisico della pagina. Ad esempio, quando si desidera che i, ii, iii sia visualizzato per le pagine introduttive e 1, 2, 3 per il testo principale del PDF.

Questo codice C# mostra come etichettare le pagine di un PDF con numeri romani minuscoli per le prime tre pagine e con numeri arabi a partire da 1 per le restanti.

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");

Preferenze del visualizzatore PDF

Le preferenze di visualizzazione dei PDF sono suggerimenti incorporati nel documento che indicano come il visualizzatore dovrebbe presentarlo. Ad esempio, è possibile specificare che il visualizzatore nasconda le barre degli strumenti, centri la finestra o la adatti alla pagina. Le preferenze di visualizzazione integrano le impostazioni di layout di pagina e di azione di apertura.

Ecco come modificare le preferenze di visualizzazione dei PDF utilizzando 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");

Si prega di notare che, a seconda della loro configurazione, Adobe Acrobat e altri visualizzatori potrebbero ignorare queste preferenze.

Layout di pagina e modalità di pagina

Il layout di pagina determina la disposizione delle pagine all'apertura del documento: una pagina alla volta, una colonna continua o due pagine affiancate. La modalità di visualizzazione controlla quali pannelli dell'interfaccia utente sono visibili all'apertura: segnalibri/struttura, allegati, miniature o nessuno.

Ecco come specificare che il PDF creato debba essere visualizzato come una doppia pagina, con la pagina di sinistra per prima, e con il pannello delle miniature visibile all'apertura:

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");

Salvataggio dei PDF

Docotic.Pdf può generare diversi file o flussi PDF dallo stesso documento creato o modificato. Questi output possono essere conformi a diverse versioni del formato PDF, variare in lunghezza in byte e richiedere diverse quantità di memoria per la generazione.

Il modo in cui la libreria genera i byte di un PDF dipende dalle opzioni di salvataggio. Quando non si specificano esplicitamente le opzioni di salvataggio, i metodi Save, SignAndSave e TimestampAndSave di un oggetto PdfDocument utilizzano le impostazioni predefinite. Queste impostazioni predefinite sono state scelte con cura e funzionano bene nella maggior parte dei casi, ma potrebbe comunque essere necessario modificarle.

Consultare la documentazione della classe PdfSaveOptions per informazioni dettagliate sulle opzioni disponibili e i relativi valori predefiniti. Le sezioni seguenti evidenziano alcune delle opzioni più importanti e forniscono consigli pratici.

Versione PDF

Docotic.Pdf utilizza per impostazione predefinita gli object stream per ottenere una migliore compressione dei file prodotti. Di conseguenza, la libreria crea file e stream PDF 1.5 per impostazione predefinita.

Per visualizzare i documenti PDF 1.5 è necessario Adobe Reader 6 (rilasciato nel 2003) o versioni successive. Questo di solito non rappresenta un problema, a meno che non sia necessario supportare strumenti legacy, visualizzatori meno recenti o dispositivi embedded che accettano solo versioni PDF obsolete.

Ecco come salvare un file PDF in una versione precedente:

using var pdf = new PdfDocument();

var options = new PdfSaveOptions
{
    Version = PdfVersion.Pdf14,
    UseObjectStreams = false,
};
pdf.Save("version-1.4.pdf", options);

Per salvare con la versione PDF 1.4, è necessario disabilitare anche i flussi di oggetti. La libreria non utilizzerà una versione precedente se il documento contiene funzionalità introdotte in versioni successive.

Riduzione delle dimensioni del file

Diverse opzioni di salvataggio, se impostate su true, consentono a Docotic.Pdf di produrre file di dimensioni inferiori (in termini di byte): RemoveUnusedObjects, OptimizeIndirectObjects, WriteWithoutFormatting e UseObjectStreams.

Ecco come produrre PDF senza oggetti non referenziati e spazi bianchi superflui, con i dati ben impacchettati in flussi di oggetti:

using var pdf = new PdfDocument();

var options = new PdfSaveOptions
{
    UseObjectStreams = true,
    RemoveUnusedObjects = true,
    OptimizeIndirectObjects = true,
    WriteWithoutFormatting = true,
};
pdf.Save("optimized.pdf", options);

Queste opzioni sono più efficaci quando il PDF viene completamente riscritto. Durante un salvataggio incrementale, si applicano solo alla revisione appena aggiunta e non possono pulire o ottimizzare le parti precedenti del file.

Aggiornamenti incrementali

Docotic.Pdf può aggiornare i PDF in modo incrementale. Quando WriteIncrementally è impostato su true, la libreria aggiunge le modifiche al file esistente anziché riscriverlo. I riferimenti incrociati e i dati degli oggetti precedenti rimangono intatti. I dati aggiunti costituiscono un aggiornamento incrementale e l'aggiornamento corrente, insieme a tutti gli aggiornamenti precedenti, rappresenta una nuova revisione del file.

Gli aggiornamenti incrementali non sono possibili per i documenti appena creati, poiché non esiste una revisione precedente a cui aggiungere le modifiche. La libreria ignora questa opzione per i nuovi documenti e li scrive in modalità non incrementale.

Quando sono necessari aggiornamenti incrementali

Quando si aggiunge una nuova firma digitale a un documento che ne contiene già, è necessario salvare il file in modo incrementale. Lo stesso vale quando si aggiorna un file precedentemente firmato con nuove annotazioni o dati di modulo. Riscrivere l'intero file in questi casi invaliderebbe le firme esistenti.

Allo stesso tempo, è consigliabile eseguire un salvataggio completo (non incrementale) prima di applicare la prima firma digitale, in modo che la base di partenza firmata sia un file pulito e completamente riscritto. Firmare un documento che presenta problemi strutturali nelle revisioni precedenti può causare problemi imprevisti di convalida della firma.

L'aggiunta incrementale è necessaria anche nei flussi di lavoro che devono preservare una cronologia delle revisioni verificabile o imporre l'archiviazione dei documenti in modalità di sola aggiunta.

Vantaggi dell'utilizzo di aggiornamenti incrementali

Gli aggiornamenti incrementali consentono di apporre più firme sullo stesso file e permettono un numero limitato di modifiche successive alla firma, come la compilazione di campi modulo, senza invalidare le firme esistenti.

Questo approccio offre inoltre salvataggi più rapidi per le piccole modifiche, poiché vengono scritti solo i dati modificati. Preserva anche la cronologia delle revisioni del documento, elemento essenziale per le attività di audit e altri flussi di lavoro orientati alla conformità.

Problemi e insidie ​​da evitare

Gli aggiornamenti incrementali non possono applicare la compressione globale o rimuovere gli oggetti obsoleti dall'intero file, poiché aggiungono solo gli oggetti modificati. Di conseguenza, generalmente producono file più grandi e meno ottimizzati rispetto a una riscrittura completa.

Le dimensioni del file aumentano a ogni revisione, anche in assenza di oggetti inutilizzati, perché tutte le revisioni precedenti rimangono incorporate nel file e continuano a occupare spazio.

Le informazioni sensibili o errate provenienti da revisioni precedenti rimangono recuperabili e i problemi di formato PDF o i difetti strutturali presenti nelle revisioni precedenti non vengono corretti con l'aggiunta di nuovi dati.

Infine, alcuni visualizzatori e strumenti di elaborazione hanno difficoltà a gestire i PDF con più revisioni. Prima di affidarsi agli aggiornamenti incrementali, assicurarsi che tutti gli utenti dei documenti siano in grado di gestire file con più revisioni.

Test dell'output PDF

Il test automatico dei PDF protegge le release da regressioni di contenuto e layout confrontando i PDF generati con i PDF di riferimento archiviati nel repository o nella memoria degli artefatti. I file di riferimento aiutano a rilevare modifiche accidentali a testo, font, immagini o layout e riducono la necessità di controlli di qualità manuali a ogni build.

Combina controlli strutturali, estrazione del testo e confronti visivi per ottenere risultati più affidabili.

Confronto rapido degli approcci

Metodo Velocità Sensibilità Ideale per
Confronti strutturali Veloce Alto: rileva modifiche a livello di oggetto Test di regressione che devono confermare che due versioni dello stesso documento siano strutturalmente identiche
Estrazione del testo Veloce Medio: solitamente ignora le modifiche al layout Verifica del contenuto semantico e delle tabelle
Differenza visiva Più lentamente Alto: rileva sia i cambiamenti di contenuto che quelli di rendering/layout Individuare le regressioni visive

Confronto della struttura del documento

Utilizza PdfDocument.DocumentsAreEqual per confrontare i grafi degli oggetti PDF, la versione del PDF e l'archivio di sicurezza del documento (DSS), ignorando le proprietà del documento dipendenti dal tempo. Il metodo ignora anche i metadati del documento, gli ID di intestazione e altre proprietà generate automaticamente.

Questo metodo è ideale per i flussi di lavoro di test dei documenti PDF che devono garantire che non siano stati aggiunti o rimossi oggetti imprevisti. DocumentsAreEqual supporta overload di file e stream e può confrontare PDF crittografati.

Un esempio completo che dimostra questa tecnica è disponibile negli esempi di Docotic.Pdf. Oltre a mostrare come utilizzare il metodo nelle normali applicazioni .NET, l'esempio mostra anche come utilizzare DocumentsAreEqual nelle applicazioni Native AOT.

Verifica dei PDF tramite testo estratto

Estrai il testo dall'intero documento in una sola volta o da singole pagine una alla volta e confronta le stringhe. Puoi utilizzare le opzioni di estrazione del testo per perfezionare il processo, ad esempio escludendo il rettangolo con il piè di pagina. Per facilitare il confronto, puoi suddividere il testo estratto in righe o parole.

Per i controlli strutturati, estrai prima il testo con posizione, carattere e altre informazioni dettagliate su ogni blocco, parola o carattere. Quindi confronta ogni elemento estratto con l'elemento di riferimento corrispondente.

Rilevamento delle differenze visive

Iniziate convertendo le pagine PDF in immagini e confrontate ciascuna immagine con quella di riferimento. Utilizzate librerie specializzate come ImageSharp.Compare o Magick.NET per rilevare le differenze tra le immagini.

È preferibile un confronto rigoroso pixel per pixel, in modo che ogni pixel corrispondente in entrambe le immagini corrisponda. Se i requisiti consentono piccole variazioni di rendering, è possibile adattare la logica di confronto per tollerare differenze minime, ma l'uguaglianza esatta a livello di pixel fornisce i risultati più affidabili.

Considerate l'utilizzo dell'hashing come rapido controllo preliminare per determinare se due immagini sono probabilmente identiche senza eseguire un confronto completo a livello di pixel. Calcolate un hash SHA-256 per ciascuna immagine renderizzata e, se gli hash corrispondono, le immagini sono quasi certamente identiche. Se gli hash differiscono, eseguite il confronto completo pixel per pixel.

Conclusione

Docotic.Pdf offre un toolkit completo e multilivello per la creazione e la manipolazione di PDF in .NET. Gli sviluppatori possono scegliere tra il controllo di basso livello con l'API Core, la generazione di documenti di alto livello con l'API Layout o la conversione da HTML a PDF per flussi di lavoro già basati su tecnologie web.

La libreria supporta anche PDF basati su immagini, la generazione basata su modelli e un ricco set di funzionalità interattive come annotazioni, collegamenti, segnalibri, azioni JavaScript e azioni di apertura.

Per garantire l'affidabilità, Docotic.Pdf include metodi per testare l'output PDF in modo che le modifiche all'applicazione non introducano regressioni o differenze impreviste.