機能(1) Excelファイルから値を読み取りデータを登録する
それでは、Excelコンポーネントを使用した機能を実装します。はじめに、以下の図のようなExcel2016のファイルをWebアプリケーションにアップロードすると、記載した内容のデータを一括で登録する機能を実装します。
手順
Webアプリケーションにファイルをアップロードするためのフォームを作成します。「Models」フォルダに「UploadModel.cs」クラスを、「Views」の下の「TrainingLogs」フォルダ(※)に「Upload.cshtml」を作成し、次のように記述します。これらの記述はASP.NET MVCにてファイルをアップロードする機能の一般的な実装になりますので、説明を省きます。
※ 「Views」の下の「TrainingLogs」フォルダは、前述の「スキャフォールディング」の手順により生成されたフォルダです。
using System.Web;
namespace Miso.C1ExcelSample.Models
{
public class UploadModel
{
public HttpPostedFileWrapper PostedFile { get; set; }
}
}
@{ ViewBag.Title = "Upload"; }
@model Miso.C1ExcelSample.Models.UploadModel
<h2>Upload</h2>
<form action="/TrainingLogs/Upload" enctype="multipart/form-data" method="post">
@Html.AntiForgeryToken()
@Html.ValidationSummary(excludePropertyErrors: false, message: "", htmlAttributes: new { @class = "text-danger" })
<input type="file" name="@Html.NameFor(m => m.PostedFile)" />
<input type="submit" value="Upload"/>
</form>
<div>
@Html.ActionLink("Back to List", "Index")
</div>
次に、「TrainingLogsController.cs」のクラスの中に、次のようにメソッドを2つ追記します。
[HttpGet]
public ActionResult Upload()
{
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Upload(UploadModel model)
{
//ファイルが送信されているか検証します
if ((model?.PostedFile?.ContentLength ?? 0) == 0)
{
ModelState.AddModelError(nameof(model.PostedFile), "ファイルを送信して下さい。");
return View();
}
Stream stream = model.PostedFile.InputStream;
//C1XLBookオブジェクトを作成し、送信されたExcelファイルを読み込みます。
var excelBook = new C1XLBook();
excelBook.Load(stream, FileFormat.OpenXml);
var logList = new List<TrainingLog>();
//Excelに入力のある行数を取得します
int inputMaxRowCount = excelBook.Sheets[0].Rows.Count;
for(int rowIndex = 0; rowIndex < (inputMaxRowCount - 1); rowIndex += 1)
{
if (rowIndex == 0) continue; //最初の行はヘッダー行なので処理しない
//日付のセルの値を取得します
var dateValue = excelBook.Sheets[0].GetCell(rowIndex, colIndex:0)?.Text;
if (!DateTime.TryParse(dateValue, out DateTime date))
{
//日付でない場合は処理をしない
continue;
}
string name = excelBook.Sheets[0].GetCell(rowIndex, 1)?.Value as string;
double.TryParse(excelBook.Sheets[0].GetCell(rowIndex, 2)?.Text, out double bodyWeight);
int.TryParse(excelBook.Sheets[0].GetCell(rowIndex, 3)?.Text, out int squatCount);
int.TryParse(excelBook.Sheets[0].GetCell(rowIndex, 4)?.Text, out int pushupCount);
int.TryParse(excelBook.Sheets[0].GetCell(rowIndex, 5)?.Text, out int situpCount);
var log = new TrainingLog
{
Date = date, Name = name, BodyWeight = bodyWeight,
SquatCount = squatCount, PushupCount = pushupCount, SitupCount = situpCount,
};
logList.Add(log);
}
//データを保存します
db.TrainingLogs.AddRange(logList);
await db.SaveChangesAsync();
return RedirectToAction("Index");
}
実行例
ここで、Webアプリケーションをデバッグ実行し、URL「/TrainingLogs/Upload」にアクセスして先ほどのExcelファイルをアップロードします。
補足
ここでC# 7の文法に関するコンパイルエラーが発生する場合は、NuGetパッケージ「Microsoft.Net.Compilers」をバージョンアップしてください。執筆時はバージョン2.1にアップデートできます。
Excelファイルをアップロードした後、「TrainingLogs/」でアクセスする一覧画面にて、複数のデータが登録できたことを確認します。

解説
これで機能(1)の実装は完了です。「TrainingLogsController.cs」に追記したUploadメソッドについて補足します。ファイルを送信された時に実行するUploadメソッドが、Excelファイルを読み取り、データを登録する処理を行っている部分です。
このUploadメソッドではまず、C1XLBookオブジェクト(C1.C1Excel名前空間)を生成し、C1XLBook クラスのLoadメソッドにて、送信されたExcelのファイルの内容をロードしています。このLoadメソッドでは、Streamオブジェクト(System.IO名前空間)やファイルパスの指定によりExcelファイルを読み取ることができます。第二引数では、Excelファイルのバージョンを指定しています。
Stream stream = model.PostedFile.InputStream; //C1XLBookオブジェクトを作成し、送信されたExcelファイルを読み込みます。 var excelBook = new C1XLBook(); excelBook.Load(stream, FileFormat.OpenXml);
次に、Excelファイルに入力されている行数の最大値を「excelBook.Sheets[0].Rows.Count」で取得し、入力された行数分ループし、その行に記述されたセルの値を読み取ります。
//Excelに入力のある行数を取得します
int inputMaxRowCount = excelBook.Sheets[0].Rows.Count;
for(int rowIndex = 0; rowIndex < (inputMaxRowCount - 1); rowIndex += 1)
{
if (rowIndex == 0) continue; //最初の行はヘッダー行なので処理しない
//日付のセルの値を取得します
var dateValue = excelBook.Sheets[0].GetCell(rowIndex, colIndex:0)?.Text;
//省略
セルの値は、「excelBook.Sheets[0].GetCell(rowIndex, colIndex:0)?.Text」といったように、行インデックスと列のインデックスを指定して、テキストの値を読み取ります。

