C#

C#でExcelのデータを取得する

更新日:

プログラムでExcelファイルのデータを扱う

プログラム上で「ファイルを扱う」というと、一昔前までは「テキストファイル」・「バイナリファイル」がほとんどで、人間が用意するデータの多くは「テキストファイル」でした。

ですが、今は普通にExcelファイルを扱うことも多くなり、プログラム上からもExcelファイルへの読み書きが必要となることもあります。

Excelファイルを.NET Framework上で扱うには、COMを使用する方法が多いのですが、今回はCOM以外の方法でExcelファイルを読み取る処理のテストを行ってみました。

 

公開されているExcelDataReaderというモジュールを使う

今回は、GitHubに公開されているExcelDataReaderというモジュールを使用してみました。

ExcelDataReaderのGitHub

GitHubのページから、[Download ZIP]ボタンを押して、ファイルをダウンロードします。

 

GitHubの画面1

 

ダウンロードしたzipファイルを解凍し、Excelファイルを読み取るためのプログラムの参照設定に追加します。

 

このGitHubのサイトにもサンプルコードはあるのですが、コメントや説明が英語だけだったことと、読み込んだ後の処理がなかったので、検証コードを作ってみました。

テストなので簡単なデータファイル(test.xlsx)をExcel 2007で作りました。

画像のようなデータを"Sheet1"に入力

テスト用データ(シート1)

 

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に相当(列です。こちらはある行のある列にあるセルのデータを持っています。)

となっています。

 

実行した結果

このコードをビルドして実行すると下記のように表示されます。

 

実行結果1

ExcelファイルのB列とC列はデータを入力していませんが、D列にはデータを入力しているので、この2列には「空データである」ことで、データとしては認識できるのはうなずけます。

このプログラムでは「空データである」ことが判るように、データがない場合は"(n/a)"という文字列を表示するようにしています。

 

見ていただくとわかるのですが、先頭行から横方向のデータは5つあるように認識されています(Excelのほうで、先頭行の5番目の列にはデータは入力していません)。

これは、最終行(先頭列でいうとデータ'10'が入っている列)の5番目の列だけ'End'というデータが入力されているために、先頭行にも5番目の列は「空データである」という情報が用意されていた。ということになります。

 

まとめ

C#でExcelファイルのデータを読み取るテストを行ってみましたが、今回使用したExcelDataReaderというモジュールは、COMを使用する方法に比べるとかなり使いやすいと言えます。

 

 

 

 

-C#

Copyright© プログラミングテクニック集キヤミー , 2020 All Rights Reserved.