How can one generate and save a file client side using Blazor?

Creator of Blazor Steve Sanderson used JavaScript interop for similar task during one of his last presentations.

You can find example on BlazorExcelSpreadsheet

Solution includes three parts:

1) JavaScript

function saveAsFile(filename, bytesBase64) {
        var link = document.createElement('a');
        link.download = filename;
        link.href = "data:application/octet-stream;base64," + bytesBase64;
        document.body.appendChild(link); // Needed for Firefox
        link.click();
        document.body.removeChild(link);
    }

2) C# interop wrapper

public static class FileUtil
{
    public async static Task SaveAs(IJSRuntime js, string filename, byte[] data)
    {
        await js.InvokeAsync<object>(
            "saveAsFile",
            filename,
            Convert.ToBase64String(data));
    }            
}

3) Call from your component

@inject IJSRuntime js
@functions {
    void DownloadFile() {
        var text = "Hello, world!";
        var bytes = System.Text.Encoding.UTF8.GetBytes(text);
        FileUtil.SaveAs(js, "HelloWorld.txt", bytes);
    }
}

You can see it an action in Blazor Fiddle


  1. Add a link

<a class="form-control btn btn-primary" href="/download?name=test.txt" target="_blank">Download</a>
  1. Add Razor Page with a route
    2.1. Create Razor page 'Download.cshtml' or another name... 'PewPew.cshtml'... does not matter
    2.2. Put the next code in the created page
    @page "/download"
    @model MyNamespace.DownloadModel
  2. Edit Download.cshtml.cs file
public class DownloadModel : PageModel
{
    public IActionResult OnGet(string name) {
        // do your magic here
        var content = new byte[] { 1, 2, 3 };
        return File(content, "application/octet-stream", name);
    }
}

I created a repository and nuget package which solves and simplifies this issue please take a look: https://github.com/arivera12/BlazorDownloadFile


The solution proposed by Eugene work, but have one drawback. If you try to do it with large files the browser hangs while downloading the blob to the client side. Solution I have found is to change that code a bit and store files in temporary directory and let the server use its mechanics for serving files instead of pushing it as a blob.

In the server configuration add :

app.UseStaticFiles();
app.UseStaticFiles(new StaticFileOptions
{
    FileProvider = new PhysicalFileProvider(
        Path.Combine(___someTempDirectoryLocation___, "downloads")),
    RequestPath = "/downloads"
});

This will add static link to a download folder somewhere on your system. Put any files you want to be available for download in there.

Next You can use either link to that file using http://pathToYourApplication/downloads/yourFileName or use simplified save javascript from main example:

function saveAsFile(filename) {
        var link = document.createElement('a');
        link.download = filename;
        link.href = "/downloads/" + filename;
        document.body.appendChild(link); // Needed for Firefox
        link.click();
        document.body.removeChild(link);
    }

which will push it to user browser for you.