Blazor Serverで、「BlazorDownloadFile、CsvHelper」Nugetパッケージを使ったCSVファイルダウンロード処理を実装しました。今はこの実装方式が最短だと思う。
ソースコードはGitHubで公開しています。
ソースコード構成


ソースコード変更内容を解説
WebApplication1.csproj
・「BlazorDownloadFile、CsvHelper」Nugetパッケージを追加している。
・BlazorDownloadFileを使ってダウンロード機能を実装すると、ブラウザの下にダウンロードしたファイルは表示されず、ダウンロードしたファイルを即開く動きをする。
 ※BlazorDownloadFileの最新版だけかも?
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14  | 
						<Project Sdk="Microsoft.NET.Sdk.Web">   <PropertyGroup>     <TargetFramework>net5.0</TargetFramework>   </PropertyGroup>   <ItemGroup>     <PackageReference Include="BlazorDownloadFile" Version="2.3.1" />     <PackageReference Include="CsvHelper" Version="27.2.1" />   </ItemGroup> </Project>  | 
					


Data/TestCsv.cs
・CSVデータに対応するデータクラスを追加。
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22  | 
						using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using CsvHelper.Configuration.Attributes; namespace WebApplication1.Data {     public class TestCsv     {         [Name("テスト列1")]         public string TestClm1 { get; set; }         [Name("テスト列2")]         public string TestClm2 { get; set; }         [Name("テスト列3")]         public string TestClm3 { get; set; }     } }  | 
					
Pages/DownloadFile.razor
・CSVファイルのダウンロードボタンを設けたテスト画面を追加。
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32  | 
						@page "/DownloadFile" @inject IBlazorDownloadFileService BlazorDownloadFileService <h1>Download CSV File</h1> <button class="btn btn-primary" @onclick="DownloadExec">Text file download</button> @code {     private async Task DownloadExec()     {         var testCsvList = new List<TestCsv>();         testCsvList.Add(new TestCsv()         {             TestClm2 = "1111"         });         using ( var memoryStream = new MemoryStream())         using ( var writer = new StreamWriter(memoryStream, Encoding.UTF8))         using ( var csv = new CsvWriter(writer, CultureInfo.CurrentCulture))         {             csv.WriteRecords(testCsvList);             writer.Flush();             var bytes = memoryStream.ToArray();             string filename = $"{DateTime.Now.ToString("yyyyMMddhhmmss")}.csv";             var result = await BlazorDownloadFileService.DownloadFile(filename, bytes, System.Net.Mime.MediaTypeNames.Application.Octet);         }     } }  | 
					
Shared/NavMenu.razor
・テスト画面へのリンクを追加。
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44  | 
						<div class="top-row pl-4 navbar navbar-dark">     <a class="navbar-brand" href="">WebApplication1</a>     <button class="navbar-toggler" @onclick="ToggleNavMenu">         <span class="navbar-toggler-icon"></span>     </button> </div> <div class="@NavMenuCssClass" @onclick="ToggleNavMenu">     <ul class="nav flex-column">         <li class="nav-item px-3">             <NavLink class="nav-link" href="" Match="NavLinkMatch.All">                 <span class="oi oi-home" aria-hidden="true"></span> Home             </NavLink>         </li>         <li class="nav-item px-3">             <NavLink class="nav-link" href="counter">                 <span class="oi oi-plus" aria-hidden="true"></span> Counter             </NavLink>         </li>         <li class="nav-item px-3">             <NavLink class="nav-link" href="fetchdata">                 <span class="oi oi-list-rich" aria-hidden="true"></span> Fetch data             </NavLink>         </li>         <li class="nav-item px-3">             <NavLink class="nav-link" href="DownloadFile">                 <span class="oi oi-plus" aria-hidden="true"></span> Download File             </NavLink>         </li>     </ul> </div> @code {     private bool collapseNavMenu = true;     private string NavMenuCssClass => collapseNavMenu ? "collapse" : null;     private void ToggleNavMenu()     {         collapseNavMenu = !collapseNavMenu;     } }  | 
					

Startup.cs
・BlazorDownloadFile Nugetパッケージのサービス起動処理を追加。
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60  | 
						using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using BlazorDownloadFile; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using WebApplication1.Data; namespace WebApplication1 {     public class Startup     {         public Startup(IConfiguration configuration)         {             Configuration = configuration;         }         public IConfiguration Configuration { get; }         // This method gets called by the runtime. Use this method to add services to the container.         // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940         public void ConfigureServices(IServiceCollection services)         {             services.AddRazorPages();             services.AddServerSideBlazor();             services.AddSingleton<WeatherForecastService>();             services.AddBlazorDownloadFile(ServiceLifetime.Scoped);         }         // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.         public void Configure(IApplicationBuilder app, IWebHostEnvironment env)         {             if (env.IsDevelopment())             {                 app.UseDeveloperExceptionPage();             }             else             {                 app.UseExceptionHandler("/Error");             }             app.UseStaticFiles();             app.UseRouting();             app.UseEndpoints(endpoints =>             {                 endpoints.MapBlazorHub();                 endpoints.MapFallbackToPage("/_Host");             });         }     } }  | 
					

_Imports.razor
・Nugetパッケージと共通部品のパスを追加。
| 
					 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18  | 
						@using System.Globalization @using System.IO @using System.Net.Http @using System.Text @using Microsoft.AspNetCore.Authorization @using Microsoft.AspNetCore.Components.Authorization @using Microsoft.AspNetCore.Components.Forms @using Microsoft.AspNetCore.Components.Routing @using Microsoft.AspNetCore.Components.Web @using Microsoft.AspNetCore.Components.Web.Virtualization @using Microsoft.JSInterop @using CsvHelper @using BlazorDownloadFile @using WebApplication1 @using WebApplication1.Data @using WebApplication1.Shared  | 
					

  
  
  
  

コメント