For one of our clients we needed a “Save As” or “Print As” dialog option specifically for PDF files(invoices and such). Unfortunately there are no native components or wrappers which handle this specific case using Blazor. So we started building our own.
The final result
Exploring the alternatives
In our initial release we tried to use the built-in
NavigationManager. Which can easily download a file (even if the file is returned by a
Controller action or on any other domain) using the
foreLoadparameter. I even recall an entire discussion about it on the old Blazor repository in the early days of Blazor (2018). But unfortunately it just downloads a file, the client still had to open every
Overload UriHelper to forceLoad the page even if it's not a Blazor defined Route. by vertonghenb ·…
PR issued to solve Add UrlHelper.NavigateTo overload that forces a full page reload #979 Handle FileResult from…
At the time of writing this post, this option is currently not possible due to some regression bug, which caused quite some trouble in our production environment (to say the least). Which made the need for a descent printing solution even more demanding. If you had some issues downloading files, you might have seen the following issue passing along. (should be fixed in the next release of 3.1 and 5.0 RC).
Blazor Server with MVC Controller for downloads leads to "Error: Circuit has been shut down due to…
Describe the bug Create a Controller for sending downloads to the client as follows. Call it using the Navigation…
PrintJS as baseline
Fortunately there was already some work done in the PrintJS repository which we could use to wrap a
PrintingService around so it’s easier to call from a .NET perspective. The good part is that it supports downloading and printing in one go using the native look and feel (see .gif above).
You can download the latest version of Print.js from the GitHub releases. Download 1.4.0 To install using npm: npm…
Add the NuGet Package
program.cs and don’t forget the
//using Append.Blazor.Printingbuilder.Services.AddScoped<IPrintingService, PrintingService>();
@inject IPrintingService PrintingService
<button @onclick="@(()=> PrintingService.Print("docs/sample.pdf"))">
wwwroot folder or a controller action. In this example a folder
/docs was added to the
wwwroot folder with a file named
sample.pdf , but you can also specify a controller action like this:
public IActionResult Get()
var stream = new FileStream(@"path\to\file", FileMode.Open);
return File(stream, "application/pdf", "FileDownloadName.pdf");
Currently the service only supports
PrintJSare available (yet) so feel free to create some PR’s and add some functionality where needed.
The code is available on the following GitHub Repository.
In a next post we’ll be going through multiple html to pdf processors to see which one can help us out the most. For example
wkhtmltopdf, razor light, etc. If you have some experience with generating