プログラムで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を使用する方法に比べるとかなり使いやすいと言えます。