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);
    }
}