プログラムでExcelファイルのデータを扱う
プログラム上で「ファイルを扱う」というと、一昔前までは「テキストファイル」・「バイナリファイル」がほとんどで、人間が用意するデータの多くは「テキストファイル」でした。
ですが、今は普通にExcelファイルを扱うことも多くなり、プログラム上からもExcelファイルへの読み書きが必要となることもあります。
Excelファイルを.NET Framework上で扱うには、COMを使用する方法が多いのですが、今回はCOM以外の方法でExcelファイルを読み取る処理のテストを行ってみました。
公開されているExcelDataReaderというモジュールを使う
今回は、GitHubに公開されているExcelDataReaderというモジュールを使用してみました。
GitHubのページから、[Download ZIP]ボタンを押して、ファイルをダウンロードします。

ダウンロードしたzipファイルを解凍し、Excelファイルを読み取るためのプログラムの参照設定に追加します。
このGitHubのサイトにもサンプルコードはあるのですが、コメントや説明が英語だけだったことと、読み込んだ後の処理がなかったので、検証コードを作ってみました。
テストなので簡単なデータファイル(test.xlsx)をExcel 2007で作りました。
画像のようなデータを”Sheet1″に入力

B列とC列は、意図して空白の列を追加しました。
また、E列に10行目だけ”End”というデータも入力しておきました。
検証してみる
今回の検証のために用意したコードです。
注意:今回のコードは、ExcelのXML形式(*.xlsx)用ファイルのコードです。
このコードで昔(Excel 2007より昔のExcel)のExcel(*.xls)ファイルは扱えません。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Data;
using Excel;
namespace ExcelReadTest
{
class Program
{
static void Main(string[] args)
{
// 現在実行しているアセンブリのファイル情報を取得する
string filePath = "";
filePath = @".\test.xlsx";
if (!System.IO.File.Exists(filePath))
{
// ファイルが存在しない
return;
}
System.IO.FileStream stream = System.IO.File.Open(filePath, FileMode.Open, FileAccess.Read);
// Excelファイル読み込む(2007 format; *.xlsx)
Excel.IExcelDataReader excelReader = Excel.ExcelReaderFactory.CreateOpenXmlReader(stream);
System.Data.DataSet result = null;
result = excelReader.AsDataSet();
// Excelファイルを閉じる
excelReader.Close();
foreach (System.Data.DataTable table in result.Tables)
{
// 'table' --> Excelの1シート
// 'table.TableName' --> Excelのシート名
if (table.TableName == "Sheet1")
{
// 'table.Rows' --> Excelのシート内の行データ
foreach (System.Data.DataRow row in table.Rows)
{
// 'table.Rows.ItemArray' --> Excelののシート内1行内の列データ
// NOTE: シート内で1番右にデータが存在するセルまでの数分存在する
StringBuilder sb = new StringBuilder();
foreach (object item in row.ItemArray)
{
if (0 < item.ToString().Length)
{
// 文字列が何もない(セルの文字列)
sb.Append(item.ToString());
}
else
{
// 文字列が何もない(空白セル)
sb.Append("(n/a)");
}
sb.Append(" ");
}
// コンソールに表示します
Console.WriteLine(sb.ToString());
}
break;
}
}
Console.ReadKey();
}
}
}
このコードでは、27行目から35行目の間で
- Excelファイルを開く
- System.Data.DataSetでファイルデータを取得する
- Excelファイルを閉じる
ことで、一気にファイル内のデータを取得して、Excelファイルは閉じています。
そこから、読み取ったデータに対して、必要な処理を行います。
このプログラム上でのExcelファイルデータは、
Sheet –> Row –> (Row内の)Column
という構造でデータが保持されており、変数名では
37行目の変数’table’ ・・・ ExcelのSheetに相当
44行目の変数’row’ ・・・ ExcelのRowに相当(行単位のデータで1行分のデータを持っています。)
49行目の変数’item’ ・・・ ExcelのColumnに相当(列です。こちらはある行のある列にあるセルのデータを持っています。)
となっています。
実行した結果
このコードをビルドして実行すると下記のように表示されます。

ExcelファイルのB列とC列はデータを入力していませんが、D列にはデータを入力しているので、この2列には「空データである」ことで、データとしては認識できるのはうなずけます。
このプログラムでは「空データである」ことが判るように、データがない場合は”(n/a)”という文字列を表示するようにしています。
見ていただくとわかるのですが、先頭行から横方向のデータは5つあるように認識されています(Excelのほうで、先頭行の5番目の列にはデータは入力していません)。
これは、最終行(先頭列でいうとデータ’10’が入っている列)の5番目の列だけ’End’というデータが入力されているために、先頭行にも5番目の列は「空データである」という情報が用意されていた。ということになります。
まとめ
C#でExcelファイルのデータを読み取るテストを行ってみましたが、今回使用したExcelDataReaderというモジュールは、COMを使用する方法に比べるとかなり使いやすいと言えます。

