(この記事は2022年7月5日が最終更新日です。)
自己紹介
この記事の作成はKazuが行っています。
本業ではエンジニアとして働きつつWebサービス開発を行っております。
副業でWebエンジニア・デザインを行っています。
エンジニアに欠かせないのが学習という名の自己投資です。
いろいろな学習方法があって正直どれを選べばよいのか悩みますよね・・・
いくつもある学習方法の中から私がオススメするのはUdemy!!
購入したコースが満足いく内容でなければ返金もしてくれるので損はありません。
Udemyを試してみる!本記事は以下の続き、応用編です。
本記事の内容はチュートリアルで作成した映画の情報をCSV出力する実装です。
CSV出力は何かと業務で利用頻度が高いと思い、議事録として。
CSV出力する方法

それではやっていきましょう。
今回はチュートリアルで作成した、データベースから値を取得するのでDB接続などの手順は割愛します。冒頭で紹介した記事の続きです。まだの方はそちらを先に読んでください。
モデルを作成
Modelsフォルダを右クリックしCsvOut.cs を作成します。


CsvOut.cs のコードは以下のように修正します。
using System.Collections.Generic;
using System.Text;
namespace MvcMovie.Models
{
public class CsvOut
{
// ヘッダー
private static string[] headerArray = { "Id", "Title", "ReleaseDate", "Genre", "Price" };
// ヘッダーとCSVデータ作成
public static string CreateCsv(List<Movie> memberList)
{
var sb = new StringBuilder();
// ヘッダーの作成
sb.AppendLine(CreateCsvHeader(headerArray));
// CSVデータの作成
memberList.ForEach(x => sb.AppendLine(CreateCsvData(x)));
return sb.ToString();
}
// ヘッダー作成
private static string CreateCsvHeader(string[] headerArray)
{
var sb = new StringBuilder();
foreach (var header in headerArray)
{
sb.Append($@"""{header}"",");
}
// 最後のカンマのみ削除
return sb.Remove(sb.Length - 1, 1).ToString();
}
// CSVデータ作成
private static string CreateCsvData(Movie m)
{
var sb = new StringBuilder();
sb.Append(string.Format($@"""{m.Id}"","));
sb.Append(string.Format($@"""{m.Title}"","));
sb.Append(string.Format($@"""{m.ReleaseDate}"","));
sb.Append(string.Format($@"""{m.Genre}"","));
sb.Append(string.Format($@"""{m.Price}"","));
return sb.ToString();
}
}
}
コントローラーを作成
続いて、コントローラーの処理を修正していきます。
チュートリアルで作成した、MoviesController.cs を以下のように修正します。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.EntityFrameworkCore;
using MvcMovie.Data;
using MvcMovie.Models;
using System.Text;
namespace MvcMovie.Controllers
{
public class MoviesController : Controller
{
private readonly MvcMovieContext _context;
public MoviesController(MvcMovieContext context)
{
_context = context;
}
// GET: Movies
public async Task<IActionResult> Index(string movieGenre, string searchString)
{
// Use LINQ to get list of genres.
IQueryable<string> genreQuery = from m in _context.Movie
orderby m.Genre
select m.Genre;
var movies = from m in _context.Movie
select m;
if (!string.IsNullOrEmpty(searchString))
{
movies = movies.Where(s => s.Title!.Contains(searchString));
}
if (!string.IsNullOrEmpty(movieGenre))
{
movies = movies.Where(x => x.Genre == movieGenre);
}
var movieGenreVM = new MovieGenreViewModel
{
Genres = new SelectList(await genreQuery.Distinct().ToListAsync()),
Movies = await movies.ToListAsync()
};
return View(movieGenreVM);
}
// GET: Movies/Details/5
public async Task<IActionResult> Details(int? id)
{
if (id == null || _context.Movie == null)
{
return NotFound();
}
var movie = await _context.Movie
.FirstOrDefaultAsync(m => m.Id == id);
if (movie == null)
{
return NotFound();
}
return View(movie);
}
// GET: Movies/Create
public IActionResult Create()
{
return View();
}
// POST: Movies/Create
// To protect from overposting attacks, enable the specific properties you want to bind to.
// For more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("Id,Title,ReleaseDate,Genre,Price,Rating")] Movie movie)
{
if (ModelState.IsValid)
{
_context.Add(movie);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
return View(movie);
}
// GET: Movies/Edit/5
public async Task<IActionResult> Edit(int? id)
{
if (id == null || _context.Movie == null)
{
return NotFound();
}
var movie = await _context.Movie.FindAsync(id);
if (movie == null)
{
return NotFound();
}
return View(movie);
}
// POST: Movies/Edit/5
// To protect from overposting attacks, enable the specific properties you want to bind to.
// For more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("Id,Title,ReleaseDate,Genre,Price,Rating")] Movie movie)
{
if (id != movie.Id)
{
return NotFound();
}
if (ModelState.IsValid)
{
try
{
_context.Update(movie);
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!MovieExists(movie.Id))
{
return NotFound();
}
else
{
throw;
}
}
return RedirectToAction(nameof(Index));
}
return View(movie);
}
// GET: Movies/Delete/5
public async Task<IActionResult> Delete(int? id)
{
if (id == null || _context.Movie == null)
{
return NotFound();
}
var movie = await _context.Movie
.FirstOrDefaultAsync(m => m.Id == id);
if (movie == null)
{
return NotFound();
}
return View(movie);
}
// POST: Movies/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
{
if (_context.Movie == null)
{
return Problem("Entity set 'MvcMovieContext.Movie' is null.");
}
var movie = await _context.Movie.FindAsync(id);
if (movie != null)
{
_context.Movie.Remove(movie);
}
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
private bool MovieExists(int id)
{
return (_context.Movie?.Any(e => e.Id == id)).GetValueOrDefault();
}
//CSV処理 start
public async Task<IActionResult> csvDown(string download)
{
if (download == "download")
{
var members = from m in _context.Movie
select m;
// リストを作成
var memberList = await members.ToListAsync();
// CSV生成
var csvString = CsvOut.CreateCsv(memberList);
var fileName = DateTime.Now.ToString("yyyyMMddHHmmss") + "_movies.csv";
// ダウンロードする文字列をbyteデータにする
var csvData = Encoding.UTF8.GetBytes(csvString);
// CSVファイルダウンロード
return File(csvData, "text/csv", fileName);
}
return View();
}
//CSV処理 end
}
}
ビューにダウンロードボタンを追加
Movies/Index.cshtml に以下の処理を追記
@using (Html.BeginForm("csvDown", "Movies", FormMethod.Get))
{
<button class="btn btn-secondary" value="download" name="download" type="submit">CSV出力(DB)</button>
}
アプリをテストする
テストをする前に、デバックした際に最初の画面の設定を変えておきます。
Program.csの内容を少し修正します。
【修正前】
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
【修正後】
app.MapControllerRoute(
name: "default",
pattern: "{controller=Movies}/{action=Index}/{id?}");
Controllerの値を変更しています。
それではデバックしてCSVがダウンロードされることを確認してください。
学習方法
「Udemy」公式サイト
コメント