Nello scorso script (https://www.aspitalia.com/script/1456/Generare-File-Download-Blazor-WebAssembly.aspx) abbiamo visto come possiamo scatenare il download di un file da Blazor WebAssembly tramite un componente custom che abbiamo chiamato FileSaver. Questa tecnica può essere utile in una grande varietà di contesti, come per esempio la generazione al volo di file PDF per l'utente.
Come al solito, il primo passo è quello di aggiungere i corrispondenti pacchetti NuGet. Nel nostro caso useremo la libreria iText.
dotnet add package itext7 dotnet add package itext7.bouncy-castle-adapter
A questo punto abbiamo a disposizione un potente strumento per creare il contenuto di un file PDF direttamente in un MemoryStream. Modifichiamo allora la pagina FetchData per consentire il download di questo tipo di file:
@page "/fetchdata" @using iText.Kernel.Colors; @using iText.Kernel.Geom; @using iText.Kernel.Pdf; @using iText.Layout; @using iText.Layout.Element; @using iText.Layout.Properties; @inject FileSaver FileSaver; @* altro codice qui *@ <button class="btn btn-primary" @onclick="DownloadPdfStream"> Download forecast data in Pdf </button>
Con una tecnica del tutto analoga a quella del precedente script, possiamo iniziare a manipolare il modello a oggetti di iText per generare il file desiderato. Diamo innanzi tutto un'occhiata all'impostazione generale:
private async Task DownloadPdfStream() { using var stream = new MemoryStream(); var writer = new PdfWriter(stream); writer.SetCloseStream(false); var pdf = new PdfDocument(writer); var document = new Document(pdf, PageSize.A4); // ... qui codice che popola il document ... document.Close(); stream.Position = 0; await this.FileSaver.SaveAsAsync("forecasts.pdf", stream); }
Come possiamo notare, inizialmente costruiamo un MemoryStream che poi inviamo al corrispondente PdfWriter. Attenzione al fatto di impostare SetCloseStream a false, altrimenti questo oggetto chiuderà il MemoryStream in fase di flush dei contenuti, con il risultato da renderlo inaccessibile per il successivo download.
Successivamente, creiamo nell'ordine l'oggetto PdfDocument e finalmente il vero e proprio Document, che potremo poi popolare con il contenuto del forecast.
Una volta che il document è popolato correttamente, dobbiamo invocarne il metodo Close, così da salvare tutto il contenuto del buffer sullo stream, per poi inviarlo al nostro oggetto FileSaver che abbiamo costruito nel precedente script.
Il codice che popola il contenuto del document, è un po' tedioso, ma lo riportiamo per completezza:
// aggiungiamo un titolo alla pagina document.Add(new Paragraph("Weather forecast") .SetTextAlignment(TextAlignment.CENTER) .SetFontSize(20)); // creiamo la tabella per i forecast Table table = new Table(UnitValue.CreatePercentArray(4)).UseAllAvailableWidth(); // header table.AddHeaderCell("Date"); table.AddHeaderCell("Temp. (C)"); table.AddHeaderCell("Temp. (F)"); table.AddHeaderCell("Summary"); // righe foreach (var forecast in forecasts) { table.AddCell(forecast.Date.ToShortDateString()); table.AddCell(forecast.TemperatureC.ToString()); table.AddCell(forecast.TemperatureF.ToString()); table.AddCell(forecast.Summary); } document.Add(table);
Se abbiamo svolto i passaggi correttamente, il risultato sarà simile a quello in figura.

Attenzione a un aspetto importante: iText è disponibile gratuitamente come CommunityEdition, ma con licenza AGPLv3 (https://itextpdf.com/how-buy/AGPLv3-license), che tra le varie cose, obbliga a pubblicare il vostro progetto come open source. Alternativamente è possible acquistare una licenza commerciale.
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimenti
Eseguire i worklow di GitHub su runner potenziati
Effettuare il log delle chiamate a function di GPT in ASP.NET Web API
Generare la software bill of material (SBOM) in GitHub
Gestione file Javascript in Blazor con .NET 9
Eseguire query per recuperare il padre di un record che sfrutta il tipo HierarchyID in Entity Framework
Ottimizzare le performance delle collection con le classi FrozenSet e FrozenDictionary
Eliminare una project wiki di Azure DevOps
Gestione degli eventi nei Web component HTML
Supportare lo HierarchyID di Sql Server in Entity Framework 8
Esporre i propri servizi applicativi con Semantic Kernel e ASP.NET Web API
Testare l'invio dei messaggi con Event Hubs Data Explorer
Persistere la ChatHistory di Semantic Kernel in ASP.NET Core Web API per GPT