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
- Add a link
<a class="form-control btn btn-primary" href="/download?name=test.txt" target="_blank">Download</a>
- 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
- 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);
}
}