次の方法で共有


スプレッドシート ドキュメントで列見出しを取得する

このトピックでは、Open XML SDK for Office のクラスを使用して、プログラムによってスプレッドシート ドキュメント内の列見出しを取得する方法について説明します。

spreadsheetML ドキュメントの基本的な構造

SpreadsheetMLドキュメントの基本的なドキュメント構造は、ブック内のワークシートを参照するSheets要素とSheet要素で構成されます。 ワークシートごとに、それぞれの XML ファイルが作成されます。 たとえば、MySheet1 と MySheet2 という名前の 2 つのワークシートがあるWorkbookSpreadsheetMLは、Workbook.xml ファイルにあり、次のコード例に示されています。

    <?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 ファイルには、セル テーブルを表 SheetData 1 つ以上のブロック レベル要素が含まれており、1 つ以上の Row 要素が含まれています。 rowには、1 つ以上のCell要素が含まれています。 各セルには、セルの値を表す CellValue 要素が含まれています。 たとえば、セル A1 の値が 100 しかないブックの最初のワークシートの SpreadsheetML は、Sheet1.xml ファイルにあり、次のコード例に示されています。

    <?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 を使用すると、 SpreadsheetML 要素に対応する厳密に型指定されたクラスを使用するドキュメント構造とコンテンツを作成できます。 これらのクラスは、 DocumentFormat.OpenXML.Spreadsheet 名前空間にあります。 次の表に、 workbooksheetssheetworksheetsheetData の各要素に対応するクラスのクラス名を示します。

SpreadsheetML の要素 Open XML SDK クラス 説明
<workbook/> DocumentFormat.OpenXML.Spreadsheet.Workbook メイン ドキュメント パーツのルート要素。
<sheets/> DocumentFormat.OpenXML.Spreadsheet.Sheets ISO/IEC 29500 の仕様で規定されている、シート、ファイル バージョン、その他のブロック レベル構造のコンテナー。
<sheet/> DocumentFormat.OpenXml.Spreadsheet.Sheet シート定義ファイルを指し示すシート。
<worksheet/> DocumentFormat.OpenXML.Spreadsheet。 Worksheet シート データが含まれているシート定義ファイル。
<sheetData/> DocumentFormat.OpenXML.Spreadsheet.SheetData セルの表。行ごとにグループ化されています。
<row/> DocumentFormat.OpenXml.Spreadsheet.Row セルの表内の行。
<c/> DocumentFormat.OpenXml.Spreadsheet.Cell 行内のセル。
<v/> DocumentFormat.OpenXml.Spreadsheet.CellValue セルの値。

サンプル コードの動作のしくみ

このハウツーのコードは、 GetColumnHeadingGetColumnNameGetRowIndexの 3 つのメソッド (Visual Basic の関数) で構成されます。 最後の 2 つのメソッドは、 GetColumnHeading メソッド内から呼び出されます。

GetColumnName メソッドは、セル名をパラメーターとして受け取ります。 セル名を解析し、セル名の列名部分と一致する正規表現を作成することで、列名を取得します。 正規表現の詳細については、「正規表現言語要素」をご覧ください。

// 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;

GetRowIndex メソッドは、セル名をパラメーターとして受け取ります。 セル名を解析し、セル名の行インデックス部分と一致する正規表現を作成することで、行インデックスを取得します。

// 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);

GetColumnHeading メソッドでは、3 つのパラメーター、ソース スプレッドシート ファイルへの完全なパス、指定した列を含むワークシートの名前、見出しを取得する列内のセルの名前を使用します。

コードは、 GetColumnName メソッドを呼び出して、指定したセルの列の名前を取得します。 また、このコードでは、列内のセルを取得し、 GetRowIndex メソッドを使用して行ごとに並べ替えます。

// 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) ?? 0);

指定した列が存在する場合は、 First メソッドを使用して列の最初のセルを取得します。 最初のセルには見出しが含まれています。 それ以外の場合、指定した列が存在せず、 メソッドは を返します null / Nothing

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

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

セルの内容が SharedStringTablePart オブジェクトに格納されている場合は、共有文字列項目を取得し、 Parse メソッドを使用して列見出しの内容を返します。 セルの内容が SharedStringTable オブジェクトにない場合は、セルの内容を返します。

// 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 is not null && headCell.DataType.Value == CellValues.SharedString && int.TryParse(headCell.CellValue?.Text, out int index))
{
    SharedStringTablePart shareStringPart = document.WorkbookPart.GetPartsOfType<SharedStringTablePart>().First();
    SharedStringItem[] items = shareStringPart.SharedStringTable.Elements<SharedStringItem>().ToArray();

    return items[index].InnerText;
}
else
{
    return headCell.CellValue?.Text;
}

サンプル コード

以下は、C# および Visual Basic の完全なサンプル コードです。

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 is null || sheets.Count() == 0)
        {
            // The specified worksheet does not exist.
            return null;
        }

        string? id = sheets.First().Id;

        if (id is null)
        {
            // The worksheet does not have an ID.
            return null;
        }

        WorksheetPart worksheetPart = (WorksheetPart)document.WorkbookPart!.GetPartById(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) ?? 0);

        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 is not null && headCell.DataType.Value == CellValues.SharedString && int.TryParse(headCell.CellValue?.Text, out int index))
        {
            SharedStringTablePart shareStringPart = document.WorkbookPart.GetPartsOfType<SharedStringTablePart>().First();
            SharedStringItem[] items = shareStringPart.SharedStringTable.Elements<SharedStringItem>().ToArray();

            return items[index].InnerText;
        }
        else
        {
            return headCell.CellValue?.Text;
        }
    }
}
// Given a cell name, parses the specified cell to get the column name.
static string GetColumnName(string? cellName)
{
    if (cellName is null)
    {
        return string.Empty;
    }

    // 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.
static uint? GetRowIndex(string? cellName)
{
    if (cellName is null)
    {
        return null;
    }

    // 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);
}

関連項目

Open XML SDK クラス ライブラリ リファレンス