[方法] スプレッドシート ドキュメントの列見出しを取得する (Open XML SDK)How to: Get a column heading in a spreadsheet document (Open XML SDK)

このトピックでは、Open XML SDK 2.5 for Office のクラスを使用して、プログラムによってスプレッドシート ドキュメントの列見出しを取得する方法を説明します。This topic shows how to use the classes in the Open XML SDK 2.5 for Office to retrieve a column heading in a spreadsheet document programmatically.

このトピックのコードをコンパイルするには、次のアセンブリ ディレクティブが必要です。The following assembly directives are required to compile the code in this topic.

    using System.Collections.Generic;
    using System.Linq;
    using DocumentFormat.OpenXml.Packaging;
    using DocumentFormat.OpenXml.Spreadsheet;
    using System.Text.RegularExpressions;
    Imports System.Collections.Generic
    Imports System.Linq
    Imports DocumentFormat.OpenXml.Packaging
    Imports DocumentFormat.OpenXml.Spreadsheet
    Imports System.Text.RegularExpressions

SpreadsheetDocument オブジェクトを作成するCreate a SpreadsheetDocument Object

Open XML SDK では、SpreadsheetDocument クラスは Excel ドキュメント パッケージを表します。Excel ドキュメントを作成するには、 SpreadsheetDocument クラスのインスタンスを作成して、パーツを設定します。少なくとも、ドキュメントのコンテナーとなるブック パーツと、ワークシート パーツが 1 つずつ必要です。テキストはパッケージ内で SpreadsheetML マークアップを使用して XML として表されます。In the Open XML SDK, the SpreadsheetDocument class represents an Excel document package. To create an Excel document, you create an instance of the SpreadsheetDocument class and populate it with parts. At a minimum, the document must have a workbook part that serves as a container for the document, and at least one worksheet part. The text is represented in the package as XML using SpreadsheetML markup.

ドキュメントからクラス インスタンスを作成するには、Open() オーバーロード メソッドのいずれかを呼び出します。To create the class instance from the document you call one of the Open() overload methods. この例では、ファイルを読み取り専用アクセスで開く必要があります。In this example, you need to open the file for read access only. したがって、Open(String, Boolean) メソッドを使用でき、ブール値のパラメーターを false に設定します。Therefore, you can use the Open(String, Boolean) method, and set the Boolean parameter to false.

次のコード例では、Open メソッドを呼び出し、filepath で指定されているファイルを読み取り専用アクセスで開いています。The following code example calls the Open method to Open the file specified by the filepath for read-only access.

    // Open file as read-only.
    using (SpreadsheetDocument document = SpreadsheetDocument.Open(docName, false))
    ' Open the document as read-only.
    Dim document As SpreadsheetDocument = SpreadsheetDocument.Open(docName, False)

using ステートメントを、通常の .Open、.Save、.Close シーケンスの代わりに使用することをお勧めします。このステートメントを使用すると、閉じかっこに達したときに Dispose メソッド (リソースをクリーンアップするために Open XML SDK で使用される内部メソッド) が自動的に呼び出されます。using ステートメントに続くブロックは、using ステートメントで作成または指定されたオブジェクト (この例では mySpreadsheet****) のスコープを設定します。The using statement provides a recommended alternative to the typical .Open, .Save, .Close sequence. It ensures that the Dispose method (internal method used by the Open XML SDK to clean up resources) is automatically called when the closing brace is reached. The block that follows the using statement establishes a scope for the object that is created or named in the using statement, in this case mySpreadsheet.

SpreadsheetML ドキュメントの基本構造Basic Structure of a SpreadsheetML Document

SpreadsheetML ドキュメントの基本構造は、Sheets 要素と Sheet 要素で構成されます。これらの要素は、ブック内のワークシートを参照します。The basic document structure of a SpreadsheetML document consists of the Sheets and Sheet elements, which reference the worksheets in the Workbook. ワークシートごとに、それぞれの XML ファイルが作成されます。A separate XML file is created for each Worksheet. たとえば、MySheet1 と MySheet2 という名前の 2 つのワークシートがあるブックの SpreadsheetML は Workbook.xml ファイル内にあり、次のコード例のように示されます。For example, the SpreadsheetML for a workbook that has two worksheets name MySheet1 and MySheet2 is located in the Workbook.xml file and is shown in the following code example.

    <?xml version="1.0" encoding="UTF-8" standalone="yes" ?> 
    <workbook xmlns=http://schemas.openxmlformats.org/spreadsheetml/2006/main xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
        <sheets>
            <sheet name="MySheet1" sheetId="1" r:id="rId1" /> 
            <sheet name="MySheet2" sheetId="2" r:id="rId2" /> 
        </sheets>
    </workbook>

ワークシート XML ファイルには、1 つ以上のブロック レベル要素 (SheetData など) が含まれます。The worksheet XML files contain one or more block level elements such as SheetData. sheetData はセルのテーブルを表しており、1 つ以上の Row 要素が含まれます。sheetData represents the cell table and contains one or more Row elements. row には、1 つ以上の Cell 要素が含まれます。A row contains one or more Cell elements. セルにはそれぞれ、セルの値を表す CellValue 要素が含まれています。Each cell contains a CellValue element that represents the value of the cell. たとえば、ブックにある最初のワークシートの SpreadsheetML が Sheet1.xml ファイル内に存在するとします。セル A1 に値 100 のみがある場合、SpreadsheetML は次のコード例のように示されます。For example, the SpreadsheetML for the first worksheet in a workbook, that only has the value 100 in cell A1, is located in the Sheet1.xml file and is shown in the following code example.

    <?xml version="1.0" encoding="UTF-8" ?> 
    <worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
        <sheetData>
            <row r="1">
    <c r="A1">
        <v>100</v> 
    </c>
            </row>
        </sheetData>
    </worksheet>

Open XML SDK 2.5 を使用すると、 SpreadsheetML 要素に対応する厳密に型指定されたクラスを使用してドキュメント構造とコンテンツを作成できます。これらのクラスは DocumentFormat.OpenXML.Spreadsheet 名前空間にあります。次の表に、 workbooksheetssheetworksheet、および sheetData の各要素に対応するクラスのクラス名を示します。Using the Open XML SDK 2.5, you can create document structure and content that uses strongly-typed classes that correspond to SpreadsheetML elements. You can find these classes in the DocumentFormat.OpenXML.Spreadsheet namespace. The following table lists the class names of the classes that correspond to the workbook, sheets, sheet, worksheet, and sheetData elements.

SpreadsheetML の要素SpreadsheetML Element Open XML SDK 2.5 のクラスOpen XML SDK 2.5 Class 説明Description
ブックworkbook ブックWorkbook メイン ドキュメント パーツのルート要素。The root element for the main document part.
シートsheets DocumentFormat.OpenXml.Spreadsheet.SheetsDocumentFormat.OpenXml.Spreadsheet.Sheets ISO/IEC 29500 の仕様で規定されている、シート、ファイル バージョン、その他のブロック レベル構造のコンテナー。The container for the block level structures such as sheet, fileVersion, and others specified in the ISO/IEC 29500 specification.
シートsheet DocumentFormat.OpenXml.Spreadsheet.SheetDocumentFormat.OpenXml.Spreadsheet.Sheet シート定義ファイルを指し示すシート。A sheet that points to a sheet definition file.
ワークシートworksheet DocumentFormat.OpenXml.Spreadsheet.WorksheetDocumentFormat.OpenXml.Spreadsheet.Worksheet シート データが含まれているシート定義ファイル。A sheet definition file that contains the sheet data.
sheetDatasheetData DocumentFormat.OpenXml.Spreadsheet.SheetDataDocumentFormat.OpenXml.Spreadsheet.SheetData セルの表。行ごとにグループ化されています。The cell table, grouped together by rows.
row DocumentFormat.OpenXml.Spreadsheet.RowDocumentFormat.OpenXml.Spreadsheet.Row セルの表内の行。A row in the cell table.
cc DocumentFormat.OpenXml.Spreadsheet.CellDocumentFormat.OpenXml.Spreadsheet.Cell 行内のセル。A cell in a row.
vv DocumentFormat.OpenXml.Spreadsheet.CellValueDocumentFormat.OpenXml.Spreadsheet.CellValue セルの値。The value of a cell

サンプル コードの動作のしくみHow the Sample Code Works

この例のコードは、3 つのメソッド (Visual Basic では関数) GetColumnHeadingGetColumnName、および GetRowIndex で構成されています。最後の 2 つのメソッドは、 GetColumnHeading メソッド内から呼び出されます。The code in this how-to consists of three methods (functions in Visual Basic): GetColumnHeading, GetColumnName, and GetRowIndex. The last two methods are called from within the GetColumnHeading method.

GetColumnName メソッドは、パラメーターとしてセル名を受け取ります。The GetColumnName method takes the cell name as a parameter. セル名を解析し、セル名の列名部分と一致する正規表現を作成することで、列名を取得します。It parses the cell name to get the column name by creating a regular expression to match the column name portion of the cell name. 正規表現の詳細については、「正規表現言語要素」をご覧ください。For more information about regular expressions, see Regular Expression Language Elements.

    // Create a regular expression to match the column name portion of the cell name.
    Regex regex = new Regex("[A-Za-z]+");
    Match match = regex.Match(cellName);

    return match.Value;
    ' Create a regular expression to match the column name portion of the cell name.
    Dim regex As Regex = New Regex("[A-Za-z]+")
    Dim match As Match = regex.Match(cellName)
    Return match.Value

GetRowIndex メソッドは、パラメーターとしてセル名を受け取ります。セル名を解析し、セル名の行インデックス部分と一致する正規表現を作成することで、行インデックスを取得します。The GetRowIndex method takes the cell name as a parameter. It parses the cell name to get the row index by creating a regular expression to match the row index portion of the cell name.

    // Create a regular expression to match the row index portion the cell name.
    Regex regex = new Regex(@"\d+");
    Match match = regex.Match(cellName);

    return uint.Parse(match.Value);
    ' Create a regular expression to match the row index portion the cell name.
    Dim regex As Regex = New Regex("\d+")
    Dim match As Match = regex.Match(cellName)
    Return UInteger.Parse(match.Value)

GetColumnHeading メソッドは 3 つのパラメーターを使用します。ソース スプレッドシートへの完全なパス、指定した列を含むワークシートの名前、および見出しを取得する列のセルの名前です。The GetColumnHeading method uses three parameters, the full path to the source spreadsheet file, the name of the worksheet that contains the specified column, and the name of a cell in the column for which to get the heading.

コードは、 GetColumnName メソッドを呼び出して、指定されたセルの列の名前を取得します。また、列のセルを取得し、 GetRowIndex メソッドを使用して取得したセルの行インデックスを取得します。The code gets the name of the column of the specified cell by calling the GetColumnName method. The code also gets the cells in the column and orders them by row using the GetRowIndex method.

    // Get the column name for the specified cell.
    string columnName = GetColumnName(cellName);

    // Get the cells in the specified column and order them by row.
    IEnumerable<Cell> cells = worksheetPart.Worksheet.Descendants<Cell>().
        Where(c => string.Compare(GetColumnName(c.CellReference.Value), 
            columnName, true) == 0)
    ' Get the column name for the specified cell.
    Dim columnName As String = GetColumnName(cellName)

    ' Get the cells in the specified column and order them by row.
    Dim cells As IEnumerable(Of Cell) = worksheetPart.Worksheet.Descendants(Of Cell)().Where(Function(c) _
        String.Compare(GetColumnName(c.CellReference.Value), columnName, True) = 0).OrderBy(Function(r) GetRowIndex(r.CellReference))

指定した列が存在する場合、IEnumerable(T).First メソッドを使用して、列の最初のセルを取得します。最初のセルには、見出しが含まれています。If the specified column exists, it gets the first cell in the column using the IEnumerable(T).First method. The first cell contains the heading.

    // Get the first cell in the column.
    Cell headCell = cells.First();
    ' Get the first cell in the column.
    Dim headCell As Cell = cells.First()

セルの内容が SharedStringTablePart オブジェクトに格納されている場合は、共有文字列項目を取得し、M:System.Int32.Parse(System.String) メソッドを使用して列見出しの内容を返します。If the content of the cell is stored in the SharedStringTablePart object, it gets the shared string items and returns the content of the column heading using the M:System.Int32.Parse(System.String) method. セルの内容が SharedStringTable オブジェクトにない場合は、セルの内容を返します。If the content of the cell is not in the SharedStringTable object, it returns the content of the cell.

    // If the content of the first cell is stored as a shared string, get the text of the first cell
    // from the SharedStringTablePart and return it. Otherwise, return the string value of the cell.
    if (headCell.DataType != null && headCell.DataType.Value == 
        CellValues.SharedString)
    {
        SharedStringTablePart shareStringPart = document.WorkbookPart.
    GetPartsOfType<SharedStringTablePart>().First();
        SharedStringItem[] items = shareStringPart.
    SharedStringTable.Elements<SharedStringItem>().ToArray();
        return items[int.Parse(headCell.CellValue.Text)].InnerText;
    }
    else
    {
        return headCell.CellValue.Text;
    }
    ' If the content of the first cell is stored as a shared string, get the text of the first cell
    ' from the SharedStringTablePart and return it. Otherwise, return the string value of the cell.
    If ((Not (headCell.DataType) Is Nothing) AndAlso (headCell.DataType.Value = CellValues.SharedString)) Then
        Dim shareStringPart As SharedStringTablePart = document.WorkbookPart.GetPartsOfType(Of SharedStringTablePart)().First()
        Dim items() As SharedStringItem = shareStringPart.SharedStringTable.Elements(Of SharedStringItem)().ToArray()
        Return items(Integer.Parse(headCell.CellValue.Text)).InnerText
    Else
        Return headCell.CellValue.Text
    End If

サンプル コードSample Code

次のコード例では、列の名前を使用して列見出しを取得する方法を示します。"Sheet4.xlsx" ファイルを使用する次の例のような呼び出しを使用して、 GetColumnHeading メソッドを呼び出すことができます。The following code example shows how to retrieve the column heading using the name of the column. You can call the GetColumnHeading method by using a call like the following example that uses the file "Sheet4.xlsx."

    string docName = @"C:\Users\Public\Documents\Sheet4.xlsx";
    string worksheetName = "Sheet1";
    string cellName = "B2";
    string s1 = GetColumnHeading(docName, worksheetName, cellName);
    Dim docName As String = "C:\Users\Public\Documents\Sheet4.xlsx"
    Dim worksheetName As String = "Sheet1"
    Dim cellName As String = "B2"
    Dim s1 As String = GetColumnHeading(docName, worksheetName, cellName)

以下に、C# と Visual Basic による完全なサンプル コードを示します。Following is the complete sample code in both C# and Visual Basic.

    // Given a document name, a worksheet name, and a cell name, gets the column of the cell and returns
    // the content of the first cell in that column.
    public static string GetColumnHeading(string docName, string worksheetName, string cellName)
    {
        // Open the document as read-only.
        using (SpreadsheetDocument document = SpreadsheetDocument.Open(docName, false))
        {
    IEnumerable<Sheet> sheets = document.WorkbookPart.Workbook.Descendants<Sheet>().Where(s => s.Name == worksheetName);
    if (sheets.Count() == 0)
    {
        // The specified worksheet does not exist.
        return null;
    }

    WorksheetPart worksheetPart = (WorksheetPart)document.WorkbookPart.GetPartById(sheets.First().Id);

    // Get the column name for the specified cell.
    string columnName = GetColumnName(cellName);

    // Get the cells in the specified column and order them by row.
    IEnumerable<Cell> cells = worksheetPart.Worksheet.Descendants<Cell>().Where(c => string.Compare(GetColumnName(c.CellReference.Value), columnName, true) == 0)
        .OrderBy(r => GetRowIndex(r.CellReference));

    if (cells.Count() == 0)
    {
        // The specified column does not exist.
        return null;
    }

    // Get the first cell in the column.
    Cell headCell = cells.First();

    // If the content of the first cell is stored as a shared string, get the text of the first cell
    // from the SharedStringTablePart and return it. Otherwise, return the string value of the cell.
    if (headCell.DataType != null && headCell.DataType.Value == CellValues.SharedString)
    {
        SharedStringTablePart shareStringPart = document.WorkbookPart.GetPartsOfType<SharedStringTablePart>().First();
        SharedStringItem[] items = shareStringPart.SharedStringTable.Elements<SharedStringItem>().ToArray();
        return items[int.Parse(headCell.CellValue.Text)].InnerText;
    }
    else
    {
        return headCell.CellValue.Text;
    }
        }
    }
    // Given a cell name, parses the specified cell to get the column name.
    private static string GetColumnName(string cellName)
    {
        // Create a regular expression to match the column name portion of the cell name.
        Regex regex = new Regex("[A-Za-z]+");
        Match match = regex.Match(cellName);

        return match.Value;
    }

    // Given a cell name, parses the specified cell to get the row index.
    private static uint GetRowIndex(string cellName)
    {
        // Create a regular expression to match the row index portion the cell name.
        Regex regex = new Regex(@"\d+");
        Match match = regex.Match(cellName);

        return uint.Parse(match.Value);
    }
    ' Given a document name, a worksheet name, and a cell name, gets the column of the cell and returns
    ' the content of the first cell in that column.
    Public Function GetColumnHeading(ByVal docName As String, ByVal worksheetName As String, ByVal cellName As String) As String
        ' Open the document as read-only.
        Dim document As SpreadsheetDocument = SpreadsheetDocument.Open(docName, False)

        Using (document)
    Dim sheets As IEnumerable(Of Sheet) = document.WorkbookPart.Workbook.Descendants(Of Sheet)().Where(Function(s) s.Name = worksheetName)
    If (sheets.Count() = 0) Then
        ' The specified worksheet does not exist.
        Return Nothing
    End If

    Dim worksheetPart As WorksheetPart = CType(document.WorkbookPart.GetPartById(sheets.First.Id), WorksheetPart)

    ' Get the column name for the specified cell.
    Dim columnName As String = GetColumnName(cellName)

    ' Get the cells in the specified column and order them by row.
    Dim cells As IEnumerable(Of Cell) = worksheetPart.Worksheet.Descendants(Of Cell)().Where(Function(c) _
        String.Compare(GetColumnName(c.CellReference.Value), columnName, True) = 0).OrderBy(Function(r) GetRowIndex(r.CellReference))

    If (cells.Count() = 0) Then
        ' The specified column does not exist.
        Return Nothing
    End If

    ' Get the first cell in the column.
    Dim headCell As Cell = cells.First()

    ' If the content of the first cell is stored as a shared string, get the text of the first cell
    ' from the SharedStringTablePart and return it. Otherwise, return the string value of the cell.
    If ((Not (headCell.DataType) Is Nothing) AndAlso (headCell.DataType.Value = CellValues.SharedString)) Then
        Dim shareStringPart As SharedStringTablePart = document.WorkbookPart.GetPartsOfType(Of SharedStringTablePart)().First()
        Dim items() As SharedStringItem = shareStringPart.SharedStringTable.Elements(Of SharedStringItem)().ToArray()
        Return items(Integer.Parse(headCell.CellValue.Text)).InnerText
    Else
        Return headCell.CellValue.Text
    End If

        End Using
    End Function

    ' Given a cell name, parses the specified cell to get the column name.
    Private Function GetColumnName(ByVal cellName As String) As String
        ' Create a regular expression to match the column name portion of the cell name.
        Dim regex As Regex = New Regex("[A-Za-z]+")
        Dim match As Match = regex.Match(cellName)
        Return match.Value
    End Function

    ' Given a cell name, parses the specified cell to get the row index.
    Private Function GetRowIndex(ByVal cellName As String) As UInteger
        ' Create a regular expression to match the row index portion the cell name.
        Dim regex As Regex = New Regex("\d+")
        Dim match As Match = regex.Match(cellName)
        Return UInteger.Parse(match.Value)
    End Function

関連項目See also

その他のリソースOther resources

Open XML SDK 2.5 クラス ライブラリ リファレンスOpen XML SDK 2.5 class library reference

統合言語クエリ (LINQ: Language-Integrated Query)Language-Integrated Query (LINQ)

ラムダ式Lambda Expressions

ラムダ式 (C# プログラミング ガイド)Lambda Expressions (C# Programming Guide)