Building Dynamic Zip Bundle in ASP.NET Core: Part 1 - Dynamic PDFs
How do you create dynamic files and include them in a dynamic zip file for download? In this two-part series, we first explain how to create a dynamic PDF
Recently, a client requested something interesting. While I can't give away all of the details, I can say the project is taking some time.
Basically, the system I'm writing contains a lot of sections: general project details, a discussion area, attachments, and other accompanying files associated with a project. They want the ability to bundle all of those sections into a ZIP file for archive purposes. Consider it like a snapshot of a project.
They also said they don't want a file on disk. They don't want it stored anywhere except when requested. So they are requesting a dynamically-generated zip file with dynamically-generated content.
Quite a task, wouldn't you say?
In this two-part series, I will be showing you how to create such a routine to bundle a variety of files into a dynamically-generated zip file.
But first, let's focus on creating a dynamic PDF.
Building Dynamic PDFs
I've mentioned how to build dynamic PDFs in an older post, but this time around, I wanted to use an updated library so I went searching.
What I landed on was IronPDF. I went with their library for the following reasons:
- Turn hard-coded HTML into a PDF
- Create a PDF-version of a web page by simply passing in a URL
- Return a PDF as a document, but provide the ability to turn that into a Stream (BIG selling point)
I've found IronPDF gives you the greatest flexibility when working with PDFs. Of course, this is only scratching the surface of what this library can do.
We'll be using feature 2 and 3.
Feature 2 for the ability to modify my PDF contents declaratively as opposed to hard-coding HTML into a string and compiling every time we need to make a change. Besides, it makes more sense to have it as a webpage with an easy model backing it.
Feature 3 should be evident as to why we'll be using this feature the most. We want to take these PDFs and generate a virtual file to include into a compressed zip file.
Enough chit-chat...what does the code look like?
This sample project was built using Visual Studio 2017 with ASP.NET Core 2.2.
Installing IronPDF
In your project, install the package IronPDF through Nuget in the Package Manager Console.
Install-Package IronPDF
And you should be ready to go.
Creating the PDF Stream
I created a class called ArchiveFile. This class contains the basics of our generated files: a filename, extension, and the bytes of the actual file.
Models\ArchiveFile.cs
public class ArchiveFile { public string Name { get; set; } public string Extension { get; set; } public byte[] FileBytes { get; set; } }
This makes it easy to work with when writing to a zip file for later.
Next, we create a service to give us our PDF document.
Services\DocumentService.cs
public class DocumentService: IDocumentService { public ArchiveFile GetDocument() { return GetTableOfContents(); }
private ArchiveFile GetTableOfContents() { // Test parameter. var projectId = 5;
var uri = new Uri("http://localhost:42006/Template/ArchiveHeader/"+projectId);
var pdf = CreatePdf(uri);
return new ArchiveFile { Name="Header", Extension = "pdf", FileBytes = pdf.ToArray() }; }
private MemoryStream CreatePdf(Uri uri) { var urlToPdf = new HtmlToPdf();
// if you want to create a Razor page with custom data, // make the call here to call a local HTML page w/ your data // in it.
// var pdf = urlToPdf.RenderUrlAsPdf(uri);
var pdf = urlToPdf.RenderHtmlAsPdf(@" <html> <head> </head> <body> <h1>Table of Contents</h1> <p>This is where you place you custom content!</p> </body> </html> ");
return pdf.Stream; } }
We place a button on our HTML page for a simple postback. Our code-behind on the Index.cshtml.cs takes the document and returns the bytes of the PDF as a FileContentResult.
Pages/Index.cshtml.cs
public class IndexModel : PageModel { private IDocumentService _service;
public IndexModel(IDocumentService service) { _service = service; }
public void OnGet() {
}
public FileContentResult OnPostDownload() { var document = _service.GetDocument();
var file = document.Name + "."+document.Extension;
return File(document.FileBytes, "application/pdf", file); } }
That's it. The file returns as a PDF and the name of the file is called Header.pdf.
This simple project is fueled by the awesome IronPDF and performs all of the heavy lifting with their self-contained PDF library.
Conclusion
For this introduction to dynamically bundling files, our first achievement turns a simple HTML into a PDF document.
While this is an extremely simple PDF document, you can easily uncomment the RenderUrlAsPdf
in the DocumentService
and transform any webpage into a PDF file.
In the next post, we'll show how to take these dynamically created files and build them into a Zip file for the user without saving it on the server.
How do you create PDFs dynamically? Is there a better library? Post your comments below and let's discuss.