C#でExcelのセルから値を取得する (Open XML)

C#から Microsoft Office のエクセルファイルを操作したい事は意外とあると思います。

エクセルを操作するライブラリはいくつかありますが Open XML SDK というライブラリを使って操作してみます。

 

ここではエクセルファイルの中から特定のセルのデータを取得する方法について解説します。


セルの値を取得

以下のサンプルではエクセルファイル内の特定のセルに格納されたデータをコンソールへ書き出しています。

using System;
using System.Data;
using System.Linq;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;


namespace ConsoleApplication1
{
    class Program
    {
        static void Main()
        {
            var fileName = @"c:\myspace\test.xlsx";
            var cellReference = "B3";

            using (SpreadsheetDocument document = SpreadsheetDocument.Open(fileName, true))
            {
                Sheets sheets = document.WorkbookPart.Workbook.Sheets;
                Sheet  sheet  = sheets.Elements<Sheet>().Where(s => s.Name == "Sheet3").FirstOrDefault();
                if (null != sheet)
                {
                    WorksheetPart worksheetPart = (WorksheetPart)document.WorkbookPart.GetPartById(sheet.Id);
                    Worksheet     worksheet     = worksheetPart.Worksheet;
                    Cell          cell          = worksheet.Descendants<Cell>().Where(c => c.CellReference == cellReference).FirstOrDefault();
                    if (null != cell)
                    {
                        string text = cell.InnerText;
                        switch (cell.DataType.Value)
                        {
                            case CellValues.SharedString:
                                int index = int.Parse(cell.InnerText);
                                SharedStringTablePart ssTablePart = document.WorkbookPart.GetPartsOfType<SharedStringTablePart<().FirstOrDefault();
                                text = ssTablePart.SharedStringTable.ElementAt(index).InnerText;
                                break;

                            case CellValues.Boolean:
                                if ("0" == cell.InnerText)
                                    text = "FALSE";
                                else
                                    text = "TRUE";
                                break;
                        }
                        System.Console.WriteLine(text);
                    }
                }
            }
        }
    }
}

エクセルファイルを開く (18行目)

SpreadsheetDocument クラスの Open メソッドを使ってエクセルファイルを開きます。

エクセルファイルを操作し終わったらリソース開放が行われるよう using を使いましょう。

シートの名称からシート情報を取得する (20~21行目)

サンプルでは「Sheet3」という名前のシートにあるデータを取得しようとしています。

それぞれのシートの名称などのシート情報は Sheet クラスで管理されています。

データが格納されたワークシートを取得する (24~25行目)

Sheetクラスが管理するのはシート情報のみでデータが格納されているわけでは在りません。

データを管理しているのは Worksheet クラスです。

Sheetクラスの Id を使って紐づく Worksheet オブジェクトを取得します。

行列番号でセルを取得する (26行目)

Worksheet クラスの Descendants メソッドを使うと、ワークシート内の子孫要素にアクセスできます。

セルを管理する Cell クラスの CellReference が行列番号(A1形式)となるので一致するセルを探します。

セルの値を取得する (29~44行目)

セルの値は Cell クラスの InnnerText プロパティに格納されています。

基本的にはこの値が目的の値となりますが、データの型によってはもうひと作業必要です。

 

データ型は Cell クラスの DataType プロパティで判断できますが、型には「SharedString」というものがあります。

エクセルには共有文字テーブルというものがあり、何度も同じデータが使われる場合にはこのテーブルに値を記録しておいて、セルの値にはテーブルのインデックス番号だけ格納しておくというものです。

 

データ型が「SharedString」の場合は、共有文字テーブルから値を取ってくる必要があります。

 

また、データ型が「Boolean」の場合は、数値で格納されているので 0 なら false といった判断が必要になります。