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
Usare i settings di serializzazione/deserializzazione di System.Text.Json di ASP.NET all'interno di un'applicazione non web
Loggare le query più lente con Entity Framework
Ricerca delle GitHub issue tramite operatori logici
Utilizzare il metodo IntersectBy per eseguire l'intersection di due liste
Dallo sviluppo locale ad Azure con .NET Aspire
Fissare una versione dell'agent nelle pipeline di Azure DevOps
Gestione file Javascript in Blazor con .NET 9
Gestione CSS in Blazor con .NET 9
Supportare la sessione affinity di Azure App Service con Application Gateway
Analizzare il contenuto di una issue con GitHub Models e AI
La gestione della riconnessione al server di Blazor in .NET 9
I più letti di oggi
- .NET Campus - Roma
- .NET Conference Italia 2022 - Track in presenza - Milano
- Release Candidate 1 di Internet Explorer 8
- Windows Azure in versione 1.0: annunciata la piattaforma Microsoft per il cloud computing
- Disponibile la June 2011 CTP di Entity Framework
- Microsoft Security Bulletin MS02-043
- .NET vs J2EE? Secondo Microsoft non ci sono paragoni


