クライアント側ですべての作業を実行し、グラフやビジュアルを生成するSPAが欲しいのですが。
ユーザーがボタンをクリックして、ページからビジュアル、テーブル、およびその他のものを保存できるようにしたいと思います(表示されているものとされていないものの両方を右クリックして保存またはコピー/貼り付けが常にオプションとは限りません)。
Webassembly/blazorライブラリから関数を呼び出して結果を取得し、クライアント側でファイルとして保存するにはどうすればよいですか?
アイデアはこんな感じ...?
cshtml
<input type="file" onchange="@ReadFile">
<input type="file" onchange="@SaveFile">
@functions{
object blazorObject = new blazorLibrary.SomeObject();
void ReadFile(){
blazorObject.someFunction(...selectedFile?...);
}
void SaveFile(){
saveFile(...selectedFile..?)
}
}
<a class="form-control btn btn-primary" href="/download?name=test.txt" target="_blank">Download</a>
@page "/download"
@model MyNamespace.DownloadModel
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);
}
}
Blazorの作成者であるSteve Sandersonは、前回のプレゼンテーションの1つで、同様のタスクにJavaScriptの相互運用を使用しました。
BlazorExcelSpreadsheet で例を見つけることができます
ソリューションには3つの部分があります。
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#相互運用機能ラッパー
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)コンポーネントから呼び出す
@inject IJSRuntime js
@functions {
void DownloadFile() {
var text = "Hello, world!";
var bytes = System.Text.Encoding.UTF8.GetBytes(text);
FileUtil.SaveAs(js, "HelloWorld.txt", bytes);
}
}
Blazor Fiddle でアクションを確認できます