こんにちは、システム開発部のながたにです。
今、ASP.NET core を使用した開発をしておりまして、Entity Framework Core 3 を使用しているのですが、その Entity Framework Core で DB から取得したデータを ボタンをクリックすることで CSV ファイルとしてダウンロードできる機能を実装しました。
今回はその実装の方法について、紹介させていただきます。
プロジェクトを作成する
まずは ASP.NET Core 3 MVC のプロジェクトを作成します。
1. Visual Studio 2019 を開きます
2.「新しいプロジェクトの作成」を選択します
3.「ASP.NET Core Web アプリケーション」を選択します
4. プロジェクト名を任意で入力して作成します(今回は CsvDownload としました)
これでプロジェクトが作成されました。
ASP.NET Core 3 で Entity Framework Core 3 を使用できるようにする
公式のドキュメントにチュートリアルがありますので、こちらを参考にしながら、Entity Framework Core 3 を使用できるように設定してください。
あくまで CSV ファイルのダウンロードの実装方法を紹介することが目的ですので、今回は割愛させていただきます。
データを用意する
まずは、CSVファイル をダウンロードするデータを用意する必要があるので、Entity Framework Core 3 を使用してテーブルを作成し、データを挿入していきましょう。
■ テーブルを用意する
今回は Users テーブルを用意します。
カラムは
Id :プライマリーキー
Name:名前
Age:年齢
Height:身長
Weight:体重
にしましょう。
■ User モデルを作成する
次に上記テーブルを作成するため、 User モデルを用意します。
Models フォルダ以下に User.cs を作成します。
作成した User.cs を開いて、下記コードのようにカラムのプロパティを定義しましょう。
namespace CsvDownload.Models
{
/// <summary>
/// Users テーブルのモデルクラス
/// </summary>
public class User
{
public int Id { get; set; } // ID プライマリーキー
public string Name { get; set; } // 名前
public int Age { get; set; } // 年齢
public float Height { get; set; } // 身長
public float Weight { get; set; } // 体重
}
}
■ コンテキストファイルを作成する
次に、DB と Model の接続を行うためのコンテキストファイルを用意します。
今回は プロジェクト下にContext.cs を作成しました。
作成した Context.cs に以下のようにコードを記述します。
using CsvDownload.Models;
using Microsoft.EntityFrameworkCore;
namespace CsvDownload
{
/// <summary>
/// DB との接続を行うためのコンテキストクラス
/// </summary>
public class Context : DbContext
{
public Context(DbContextOptions<Context> options) : base(options)
{
}
// モデルをセットする
public DbSet<User> Users { get; set; } // プロパティ名がテーブル名になる(この場合だと Users テーブルが作成される)
}
}
■ 作成したコンテキストファイルをDI コンテナーに追加してEntity Framework Core として使用できるようにする
次に、Startup.cs の ConfigureServices メソッドに 先ほど作成したコンテキストを追加します
services.AddDbContext<Context>(options =>
options.UseSqlServer("Server=(localdb)\\mssqllocaldb;Database=CsvDownload;Trusted_Connection=True;MultipleActiveResultSets=true"));services.AddDbContext&lt;Context&gt;(options =&gt; options.UseSqlServer("Server=(localdb)\\mssqllocaldb;Database=CsvDownload;Trusted_Connection=True;MultipleActiveResultSets=true"));
※DBの接続文字列(UseSqlServerの部分)は任意で入力してください。特にこだわりがなければ、上記の記述でLocal環境にCsvDownload DBが作成されます。
■ マイグレーションファイルを作成する
これで、準備が整いましたので、次に Users テーブルを作成するためのマイグレーションファイルを作成します。
こちらはコンソールからコマンドを実行するだけで簡単に作成ができます。
[ツール] から [パッケージマネージャーコンソール] を開く
コンソールを開いたら以下のコマンドを実行する
PM> Add-Migration CreateTableUsers
※Add-Migration の後ろはマイグレーション名です。任意で設定してください。
これでMigration フォルダが作成されその中にマイグレーションファイルとマイグレーションのスナップショットファイルが作成されます。
■ マイグレーションを実行する
マイグレーションファイルを作成したときと同様、コンソールでコマンドを実行します。
マイグレーションを実行するコマンドは以下となります。
PM> Update-Database
成功すると DB が作成され Users テーブルが作成されます。
※[表示] ⇒ [SQL Server オブジェクト エクスプローラー] から確認ができます。
■ データを挿入する
これでテーブルが作成されましたので、あとは適当にデータを挿入してください。
※ [SQL Server オブジェクト エクスプローラー]からテーブルを選択して、[データを表示] をクリックすると テーブル内のデータが表示されるので、そこから直接挿入することが可能です。
↓
CSV ダウンロード機能を実装する
お待たせしました… ここからがやっと本題になります。
先ほど挿入したUsers テーブルのデータをCSVダウンロードできるようにしましょう。
■ CsvHelper パッケージをインストールする
まず、CSV形式でダウンロードするために必要な、CsvHelper というパッケージをインストールします
[ツール] ⇒ [NuGet パッケージマネージャー] ⇒ [ソリューションの NuGet パッケージの管理] の順に選択します
CsvHelper と 入力すると [CsvHelper] が出てくるので、選択してインストールします
■ CSVダウンロードボタンを設置する
今回はデフォルトで用意されている Home 画面にボタンを設置しましょう。
[View] フォルダ ⇒ [Home] ⇒ [index.cshtml] を開く
以下のように View ファイルに CSV ダウンロードボタンを a タグで追加しましょう
@{
ViewData["Title"] = "Home Page";
}
<div class="text-center">
<h1 class="display-4">Welcome</h1>
<p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
@*CSV ダウンロードボタンを追加する*@
<a asp-action="CsvDownload" class="btn btn-primary">ユーザー CSVダウンロード</a>
</div>
※a タグに asp-action で Controller のアクションを指定することで、自動的に href 属性を補完してくれます。
■ CSV ダウンロード 処理を実装する
ボタンを設置しましたので、最後にCSV ダウンロード処理を実装します。
上記で Action を CsvDownload としましたので、HomeController に CsvDownload アクション を追加して、その中でCSVダウンロード処理を実装していきましょう。
[Controllers] フォルダ ⇒ [HomeController.cs] を開く
以下のように CsvDownload アクションを追加します。
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using CsvDownload.Models;
// Usingを追加する
using System.IO;
using CsvHelper;
using System.Globalization;
namespace CsvDownload.Controllers
{
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
private readonly Context _context;
public HomeController(ILogger<HomeController> logger, Context context)
{
_logger = logger;
// コンテキストをコンストラクタで定義する
_context = context;
}
public IActionResult Index()
{
return View();
}
public IActionResult Privacy()
{
return View();
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
/// <summary>
/// CSVダウンロード
/// </summary>
/// <returns>CSVファイル</returns>
public FileContentResult CsvDownload()
{
// CSV ファイル名
string csvFileName = "ユーザーデータ.csv";
// メモリを確保する
using (var memory = new MemoryStream())
using (var writer = new StreamWriter(memory))
using (var csv = new CsvWriter(writer, new CultureInfo(0x0411, false)))
{
// コンテキストを使用してUsers テーブルのデータを取得する
List<User> users = _context.Users.ToList();
// 取得したデータを記録する
csv.WriteRecords(users);
writer.Flush();
// CSVファイルとして出力する
return File(memory.ToArray(), "text/csv", csvFileName);
}
}
}
}
■ 動作確認
これで、一通り実装ができましたので、最後に動作確認をしましょう。
ビルドしてホーム画面を開きます。
[ユーザー CSVダウンロード] ボタンが表示されているので、これをクリックするとCSVファイルがダウンロードされます。
ファイルを開くと以下のようにUsers テーブルのデータが登録されていることが確認できます。
これでCSVファイルのダウンロードができるようになりました。
以上が大まかな処理の流れとなります。
備考
■ 一部カラムを取得しないようにしたい
ID のようにCSVダウンロードで必要ないカラムを出力したくない場合があると思います。
そんな時は Model クラスの 出力したくないカラム(プロパティ)に [ignore] 属性(using CsvHelper.Configuration.Attributes; を追加する必要あり)を付与することで対応が可能です。
using CsvHelper.Configuration.Attributes;
namespace CsvDownload.Models
{
/// <summary>
/// Users テーブルのモデルクラス
/// </summary>
public class User
{
[Ignore]
public int Id { get; set; } // ID プライマリーキー
public string Name { get; set; } // 名前
public int Age { get; set; } // 年齢
public float Height { get; set; } // 身長
public float Weight { get; set; } // 体重
}
}
これでファイルをダウンロードするとIDカラムが出力されないようになります。
■ ヘッダー名を変更したい
現状ヘッダーは Model のプロパティ名がそのまま出力されていますが、こちらも変更することが可能です。
方法は、変更したいプロパティに[Name] 属性を付与するだけです。
using CsvHelper.Configuration.Attributes;
namespace CsvDownload.Models
{
/// <summary>
/// Users テーブルのモデルクラス
/// </summary>
public class User
{
[Ignore]
public int Id { get; set; } // ID プライマリーキー
[Name("名前")]
public string Name { get; set; } // 名前
[Name("年齢")]
public int Age { get; set; } // 年齢
[Name("身長")]
public float Height { get; set; } // 身長
[Name("体重")]
public float Weight { get; set; } // 体重
}
}
これでファイルをダウンロードするとヘッダーが変更されていることが確認できます。
まとめ
いかがでしたでしょうか。
このようにCSVダウンロード機能は、管理システム等ではよく必要とされる機能だと思いますので、少しでも参考になれば幸いでございます。
では、以上となります。
ありがとうございました!