Questa pagina può contenere testo tradotto automaticamente.

Convertire HTML in PDF in C# e VB.NET

Se hai già investito molto tempo e denaro nella creazione di contenuti in formato HTML, potresti voler creare PDF da quell'HTML. Questo approccio è una scelta naturale per chi vuole evitare lavoro duplicato.

Questo articolo è una guida dettagliata alla conversione da HTML a PDF in .NET usando Docotic.Pdf insieme al suo componente aggiuntivo gratuito HtmlToPdf.

Per informazioni sul perché Docotic.Pdf sia la scelta giusta, su come installare il componente aggiuntivo e su come funziona internamente la conversione, consulta la pagina panoramica dell'API HTML to PDF.

Conversione da HTML a PDF

Conversione semplice da HTML a PDF in C#

Per prima cosa, installa il componente aggiuntivo.

Install-Package BitMiracle.Docotic.Pdf.HtmlToPdf

Usando l'API HTML to PDF, il codice di conversione C# può essere simile al seguente:

static async Task ConvertUrlToPdfAsync(string urlString, string pdfFileName)
{
    using var converter = await HtmlConverter.CreateAsync();
    using var pdf = await converter.CreatePdfAsync(new Uri(urlString));
    pdf.Save(pdfFileName);
}

È piuttosto semplice. Sono necessarie solo due chiamate per generare un documento PDF.

Il codice crea un'istanza del convertitore e la usa per generare un PDF da HTML. Puoi modificare il PDF oppure firmarlo con una firma digitale. Per semplicità, il codice di esempio salva il documento così com'è.

Come puoi vedere, l'API è asincrona e non fornisce affatto metodi sincroni.

Utilizzo dell'API asincrona in codice sincrono

Ci sono casi in cui è necessario chiamare l'API da codice sincrono. Ad esempio, quando la tua applicazione console usa una versione più vecchia di C# e non hai async Main. Non preoccuparti, puoi comunque usare il componente aggiuntivo nella tua app.

Il codice seguente mostra come convertire un URL in PDF in un normale metodo sincrono:

Task.Run(async () =>
{
    using var converter = await HtmlConverter.CreateAsync();
    var uri = new Uri("https://bitmiracle.com/pdf-library/html-pdf/");
    using var pdf = await converter.CreatePdfAsync(uri);
    pdf.Save("output.pdf");
}).GetAwaiter().GetResult();

Le applicazioni VB.NET usano un codice simile. Ecco un frammento che mostra come convertire HTML in PDF in codice VB.NET sincrono.

Task.Run(
    Async Function()
        Using converter = Await HtmlConverter.CreateAsync()
            Dim uri = New Uri("https://bitmiracle.com/pdf-library/html-pdf/")
            Using pdf = Await converter.CreatePdfAsync(uri)
                pdf.Save("output.pdf")
            End Using
        End Using
    End Function
).GetAwaiter().GetResult()

Tieni presente che in generale non è consigliato chiamare metodi async in modo sincrono, quindi usa il wrapper solo quando non hai altra scelta.

Codice di esempio

Forniamo codici di esempio per applicazioni console, Windows Forms e WPF. Scarica i progetti di test completi dal nostro repository GitHub:

Esiste anche il gruppo di esempi HTML to PDF. Ogni esempio è disponibile nelle versioni C# e VB.NET.

Crea un PDF con una stringa HTML o un file in C# e VB.NET

È facile convertire una stringa HTML in PDF con l'API. La stringa può contenere un documento HTML completo oppure solo un frammento. Il convertitore creerà per te un PDF dal codice HTML.

using var converter = await HtmlConverter.CreateAsync();

var html = "<body><br><br><br><h1>Hello, World</h1></body>";
using var pdf = await converter.CreatePdfFromStringAsync(html);
pdf.Save("output.pdf");

L'HTML può contenere riferimenti relativi a immagini, script e file CSS. Per convertire correttamente questo codice, dovresti specificare un URL di base per tutti i collegamenti relativi nell'HTML. Ecco come specificare un URL di base usando le opzioni di conversione:

using var converter = await HtmlConverter.CreateAsync();

var incompleteHtml = "<img src=\"/images/team.svg\"></img>";

var options = new HtmlConversionOptions();
options.Load.BaseUri = new Uri("https://bitmiracle.com/");

using var pdf = await converter.CreatePdfFromStringAsync(incompleteHtml, options);
pdf.Save("output.pdf");

Il nostro repository GitHub contiene il progetto di test completo.

La conversione di un file HTML è quasi la stessa della conversione di un URL. Basta usare l'overload CreatePdfAsync che accetta un percorso invece di un URL. Anche l'URL di base e altre opzioni sono supportati quando si converte un file HTML in PDF in codice C# o VB.NET.

var sampleHtmlPath = @"C:\path\to\sample.html";
using var pdf = await converter.CreatePdfAsync(sampleHtmlPath);
pdf.Save("output.pdf");

Puoi anche convertire immagini SVG in PDF usando l'API.

Usa dimensioni pagina, margini e scala personalizzati

Quando si gestiscono pagine web con layout ampi, puoi aumentare la dimensione del PDF di output oppure ridimensionare il contenuto per adattarlo alla pagina PDF. Per posizionare meglio il contenuto ridimensionato, puoi anche impostare i margini.

Un PDF ben ridimensionato offre una migliore esperienza di lettura, perché i lettori non dovranno ingrandire o ridurre la visualizzazione per vedere correttamente il contenuto. Se il documento HTML è difficile da leggere a causa di una dimensione del font ridotta, puoi ingrandire il contenuto.

Per impostazione predefinita, l'API produce PDF con dimensione pagina pari ad A4. Non ci sono margini né ingrandimento. Usando le opzioni di conversione, puoi modificare queste impostazioni.

Vedi come impostare il fattore di scala e i margini quando si genera un PDF da HTML

using var converter = await HtmlConverter.CreateAsync();

var html = "<html><head><style>body { background-color: coral; margin-top: 100px;}</style></head>" +
"<body><h1>Did you notice the margins and the scale?</h1></body></html>";

var options = new HtmlConversionOptions();
options.Page.MarginLeft = 10;
options.Page.MarginTop = 20;
options.Page.MarginRight = 30;
options.Page.MarginBottom = 40;
options.Page.Scale = 1.5;

using var pdf = await converter.CreatePdfFromStringAsync(html, options);
pdf.Save("output.pdf");

Il repository di esempi di Docotic.Pdf contiene il progetto completo.

L'API HTML to PDF può aggiungere blocchi ripetibili di piè di pagina / intestazione nelle pagine generate. Il convertitore crea i blocchi dai modelli HTML specificati nelle opzioni di pagina. Consigliamo di usare stili inline e URI dei dati per le immagini all'interno dei modelli.

Il convertitore posiziona intestazioni e piè di pagina all'interno dei margini della pagina. Poiché i margini di pagina predefiniti sono ridotti, il contenuto dell'intestazione e del piè di pagina potrebbe non essere visibile. Consigliamo di specificare esplicitamente i margini superiore e inferiore. La dimensione dovrebbe corrispondere rispettivamente alla dimensione dell'intestazione e del piè di pagina.

Vedi come modificare HTML to PDF e aggiungere intestazione e piè di pagina

using var converter = await HtmlConverter.CreateAsync();

var options = new HtmlConversionOptions();
options.Page.HeaderTemplate = File.ReadAllText("header-template.html");
options.Page.MarginTop = 50;

options.Page.FooterTemplate = File.ReadAllText("footer-template.html");
options.Page.MarginBottom = 50;

var url = new Uri("https://www.iana.org/numbers");
using var pdf = await converter.CreatePdfAsync(url, options);
pdf.Save("output.pdf");

I modelli usano normale codice HTML con supporto per alcune variabili. Queste variabili sono date, title, url, pageNumber e totalPages. Sia i modelli di intestazione sia i modelli di piè di pagina supportano lo stesso insieme di variabili.

Il progetto di test completo e il codice dei modelli si trovano nel repository di esempi di Docotic.Pdf. Il codice di esempio mostra come usare le variabili e gli URI dei dati nei modelli.

Conversione da HTML protetto da password a PDF in C#

Alcune pagine web richiedono autenticazione per accedervi. Quando accedi a un URL sicuro che richiede autenticazione HTTP, il browser ti chiede di fornire nome utente e password.

Usando le opzioni di conversione, puoi indicare all'API di fornire le credenziali per le pagine web che richiedono accesso.

Questo codice C# mostra come convertire HTML protetto da password in PDF

using var converter = await HtmlConverter.CreateAsync();
var url = new Uri("http://httpbin.org/basic-auth/foo/bar");

var options = new HtmlConversionOptions();
options.Authentication.SetCredentials("foo", "bar");

using var pdf = await converter.CreatePdfAsync(url, options);
pdf.Save("output.pdf");

Trova l'esempio completo funzionante nel repository degli esempi.

È anche facile se la pagina necessita di alcuni cookie impostati per funzionare correttamente. Aggiungi semplicemente quei cookie alle opzioni. Ecco come:

var options = new HtmlConversionOptions();
options.Cookies.Add(new Cookie("sessionID", "my-session-ID"));

using var pdf = await converter.CreatePdfAsync(url, options);
pdf.Save("output.pdf");

Ritarda l'avvio della conversione

Per impostazione predefinita, la conversione inizia immediatamente dopo il caricamento. Ritardare la conversione da HTML a PDF può essere utile se la pagina continua ad aggiornarsi per un po' dopo il caricamento. È spesso il caso quando si gestiscono contenuti dinamici generati da JavaScript o chiamate AJAX.

Il test Acid 3 è un esempio perfetto di pagina che trarrebbe vantaggio da un ritardo prima della conversione. Il test esegue una serie di controlli per valutare la capacità di un browser di renderizzare correttamente pagine web complesse. Questi controlli richiedono tempo. Prova a modificare il tempo di attesa nel codice seguente per vedere come influisce sui risultati della conversione.

var options = new HtmlConversionOptions();
options.Start.SetStartAfterDelay(10 * 1000);

using var converter = await HtmlConverter.CreateAsync();
var url = new Uri("http://acid3.acidtests.org/");
using var pdf = await converter.CreatePdfAsync(url, options);
pdf.Save("output.pdf");

Il codice precedente mostra come convertire HTML in PDF con un ritardo. Anche se il tempo aggiuntivo aiuta a ottenere risultati migliori, tieni presente che l'aggiunta di ritardi può influire sulle prestazioni. Ritardi insufficienti possono compromettere negativamente la qualità della conversione. Un approccio alternativo all'uso di un ritardo è usare uno script che venga eseguito finché la pagina non è pronta.

Puoi ottenere il progetto di test completo nel repository di esempi di Docotic.Pdf.

Esegui JavaScript prima della conversione

L'API del componente aggiuntivo fornisce un modo per eseguire codice JS prima della conversione. Il codice può generare dinamicamente o modificare il contenuto HTML. Ad esempio, può attivare o disattivare elementi, oppure far avviare il caricamento di contenuti dinamici.

Il codice seguente mostra come ritardare la conversione da HTML a PDF finché JavaScript non ha terminato l'esecuzione.

using var converter = await HtmlConverter.CreateAsync();

var options = new HtmlConversionOptions();
var js = @"document.body.style.backgroundColor = 'green';";
options.Start.SetStartAfterScriptRun(js);

var url = new Uri("https://google.com");
using var pdf = await converter.CreatePdfAsync(url, options);
pdf.Save("output.pdf");

Il frammento precedente usa un codice molto semplice solo per illustrare l'approccio. Per un esempio più realistico, consulta l'app di esempio corrispondente nel nostro repo GitHub. L'app mostra come gestire una pagina che carica dinamicamente i propri contenuti. Il codice JavaScript nell'app scorre la pagina finché non ci sono più nuovi contenuti. Dopo di che, avviene la conversione in PDF.

Conversione da HTML a PDF in .NET ignorando gli errori SSL

Quando si inviano richieste sicure per caricare HTML, il componente aggiuntivo verifica se il certificato SSL che autentica l'identità di un sito web e abilita una connessione crittografata è valido e attendibile.

Per impostazione predefinita, il componente aggiuntivo genererà un'eccezione se il convertitore HTML in PDF non si fida del certificato per qualsiasi motivo. Di solito ciò accade a causa di un certificato autofirmato, revocato o scaduto.

Se comprendi il rischio di accettare un certificato non attendibile, puoi indicare al componente aggiuntivo di ignorare i controlli usando le opzioni del motore.

var engineOptions = new HtmlEngineOptions
{
    IgnoreSslErrors = true
};
using var converter = await HtmlConverter.CreateAsync(engineOptions);

var url = new Uri("https://self-signed.badssl.com/");
using var pdf = await converter.CreatePdfAsync(url);
pdf.Save("output.pdf");

Per il codice completo, vai al repository degli esempi di Docotic.Pdf.

Sovrapponi HTML a un PDF esistente

Ci sono casi in cui potresti voler usare un PDF esistente come sfondo per il risultato della conversione. Ad esempio, quando hai l'immagine di un modulo e vuoi inserire qualcosa sopra le aree vuote di quell'immagine. Il risultato sembrerà un modulo compilato. Questo è possibile con Docotic.Pdf e il componente aggiuntivo.

Questo processo prevede la creazione di un nuovo PDF dall'HTML (il contenuto di sovrapposizione) e poi la sua unione con il PDF esistente. Il documento finale conterrà sia il contenuto originale sia la nuova sovrapposizione. Ecco il codice che illustra il processo.

using var converter = await HtmlConverter.CreateAsync();

var options = new HtmlConversionOptions();
options.Page.SetSizeInches(4.13, 5.83);

string htmlCode =
    "<div style=\"position: absolute; top: 270px; right: 100px;\">" +
    "I would like to put this here</div>";
using var htmlPdf = await converter.CreatePdfFromStringAsync(htmlCode, options);

using var pdf = new PdfDocument("pdf-to-merge-with.pdf");
var xObj = pdf.CreateXObject(htmlPdf.Pages[0]);

pdf.Pages[0].Canvas.DrawXObject(xObj, 0, 0);
pdf.Save("output.pdf");

È importante specificare una dimensione di pagina per la sovrapposizione. In genere, la dimensione dovrebbe essere uguale a quella della pagina che vuoi sovrapporre. Quindi dovresti produrre il nuovo PDF con il contenuto di sovrapposizione. Tieni presente che lo sfondo è trasparente per impostazione predefinita. Se necessario, puoi modificare lo sfondo eseguendo uno script prima della conversione.

Il codice sopra:

  • crea un documento PDF con una pagina trasparente dall'HTML
  • apre un PDF esistente
  • crea un XObject dalla prima pagina del documento convertito nel documento esistente
  • disegna l'XObject sopra la prima pagina PDF del documento esistente

Il progetto di test completo con un esempio di PDF sorgente si trova nel repository di esempi di Docotic.Pdf.