如何使用Blazor生成并保存文件客户端?

sha*_*mek 11 c# web webassembly blazor

我希望有一个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..?)
}

}
Run Code Online (Sandbox Code Playgroud)

Den*_*Den 17

  1. 添加链接

<a class="form-control btn btn-primary" href="/download?name=test.txt" target="_blank">Download</a>
Run Code Online (Sandbox Code Playgroud)

  1. 使用路由
    2.1添加 Razor 页面。创建 Razor 页面“ Download.cshtml ”或其他名称...“ PewPew.cshtml ”...无关紧要
    2.2。将下一个代码放在创建的页面中
    @page "/download"
    @model MyNamespace.DownloadModel
  2. 编辑Download.cshtml.cs文件
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);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • “@model”仅适用于 MVC 视图和 Razor 页面(不适用于 Blazor 页面)。请参阅 [doc'n](https://learn.microsoft.com/en-us/aspnet/core/mvc/views/razor?view=aspnetcore-5.0#model) (4认同)

Eug*_*kov 13

Blazor Steve Sanderson的创建者在他的上一个演讲中,使用JavaScript互操作完成了类似任务。

您可以在BlazorExcelSpreadsheet上找到示例

解决方案包括三个部分:

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);
    }
Run Code Online (Sandbox Code Playgroud)

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));
    }            
}
Run Code Online (Sandbox Code Playgroud)

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);
    }
Run Code Online (Sandbox Code Playgroud)

}

您可以在Blazor Fiddle中看到它的动作

  • 即使它使用 JS,我相信这是最好的方法,因为它是纯粹的 Blazor。混合 Blazor 和 MVC 并不是那么好。 (2认同)
  • 如果下载一个很大的文件,这个解决方案不会消耗内存吗?对我来说,转换为 Base64 似乎是一个阻碍。 (2认同)
  • Blazor 是否存在支持此开箱即用功能的 GitHub 问题?谢谢! (2认同)

rev*_*btz 6

我创建了一个存储库和 nuget 包,它解决并简化了这个问题,请查看:https : //github.com/arivera12/BlazorDownloadFile

  • 遗憾的是,该文档相当糟糕,也许您可​​以在答案中添加一个示例。 (2认同)

小智 5

尤金提出的解决方案可行,但有一个缺点。如果您尝试对大文件执行此操作,则浏览器会在将 blob 下载到客户端时挂起。我发现的解决方案是稍微更改该代码并将文件存储在临时目录中,并让服务器使用其机制来提供文件,而不是将其作为 blob 推送。

在服务器配置中添加:

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

这会将静态链接添加到系统上某处的下载文件夹。将您想要可供下载的任何文件放在那里。

接下来,您可以使用http://pathToYourApplication/downloads/yourFileName使用该文件的链接,也可以使用主示例中的简化保存 JavaScript:

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);
    }
Run Code Online (Sandbox Code Playgroud)

这会将其推送到您的用户浏览器。