😎

Blazorで名前を付けて保存ダイアログを表示して保存する

2023/03/09に公開
SaveDialog
/// <summary>
/// 保存ダイアログを表示する
/// </summary>
public class SaveDialog
{
    private IJSRuntime _jSRuntime;

    public SaveDialog(IJSRuntime jSRuntime)
    {
        _jSRuntime= jSRuntime;
    }

    /// <summary>
    /// 実行
    /// </summary>
    /// <param name="stream">保存したいオブジェクト</param>
    /// <param name="suggestedName">ダイアログに表示する初期ファイル名称</param>
    /// <see cref="https://webfrontend.ninja/js-show-save-file-picker/"/>
    /// <see cref="https://blog.jbs.co.jp/entry/2022/06/07/100000"/>
    public async Task Execute(MemoryStream stream, String suggestedName)
    {
        //JavaScriptの関数を呼び出し
        var module = await _jSRuntime.InvokeAsync<IJSObjectReference>("import", "./js/SaveDialog.js");
        await module.InvokeVoidAsync("Download", suggestedName, stream.ToArray());
    }
}
SaveDialog
export async function Download(_suggestedName ,content) {
    // ファイル保存ダイアログを表示して FileSystemFileHandle オブジェクトを取得
    const fh = await window.showSaveFilePicker({
        suggestedName: _suggestedName,
        types: [
            { accept: { "application/octet-stream": [".xlsx"] } }]
    });

    // FileSystemWritableFileStream オブジェクトを取得
    const stream = await fh.createWritable();

    // データの Blob オブジェクトを生成
    const file = new File([content], fh.name, {type: "application/octet-stream"});

    //データをファイルに書き込む
    await stream.write(file);

    // ファイルを閉じる
    await stream.close();

    // 保存したファイルパスを表示するなら以下を解放

    //const exportUrl = URL.createObjectURL(file);

    //const a = document.createElement("a");
    //document.body.appendChild(a);
    //a.href = exportUrl;
    //a.download = fh.name;
    //a.target = "_self";
    //a.click();
    //document.body.removeChild(a);

    //URL.revokeObjectURL(exportUrl);
}
ExcelOutputer
@using AngleSharp.Html.Dom;
@using AngleSharp.Html.Parser;
@inject IJSRuntime JS

<Button Type="primary" @onclick="OutPut">
    出力
</Button>
@code
{
    /// <summary>出力対象となるID属性</summary>
    [Parameter]
    public List<string> IdNames { get; set; }

    private async Task OutPut()
    {
        TabelReader reader = new TabelReader(JS);
        Book book = await reader.Execute(IdNames);
        ExcelCreator creator = new ExcelCreator();
        using var stream = new MemoryStream();
        creator.Execute(book, stream);
        Saves.SaveDialog saveDialog = new Saves.SaveDialog(JS);
        await saveDialog.Execute(stream, book.Name);
    }
}

Discussion