web-dev-qa-db-ja.com

OpenXML Format SDKを使用してスプレッドシートからデータを読み取るにはどうすればよいですか?

Open XML SDK 2.0を使用して、Excel2007ワークブックの単一のワークシートからデータを読み取る必要があります。これを行うための基本的なガイドラインを探すのに多くの時間を費やしましたが、スプレッドシートの作成に関するヘルプしか見つかりませんでした。

このSDKを使用して、ワークシートの行を反復処理してから、各行のセルを反復処理するにはどうすればよいですか?

16
ProfK

これを行う方法は、Linqを使用することです。 SDKの使用から、純粋なOpen XML(SDKなし)の使用まで、このテーマに関するサンプルはたくさんあります。を見てみましょう:

13
Todd Main

もう1つの答えは、メタ回答のように見えました。 LINQを使用すると、分離されたドキュメントパーツで機能するため、私はこれに苦労しています。次のコードには、セルから値を取得し、可能な文字列ルックアップを解決するラッパー関数が含まれています。

public void ExcelDocTest()
{
    Debug.WriteLine("Running through sheet.");
    int rowsComplete = 0;

    using (SpreadsheetDocument spreadsheetDocument =
                    SpreadsheetDocument.Open(@"path\to\Spreadsheet.xlsx", false))
    {
        WorkbookPart workBookPart = spreadsheetDocument.WorkbookPart;

        foreach (Sheet s in workBookPart.Workbook.Descendants<Sheet>())
        {
            WorksheetPart wsPart = workBookPart.GetPartById(s.Id) as WorksheetPart;
            Debug.WriteLine("Worksheet {1}:{2} - id({0}) {3}", s.Id, s.SheetId, s.Name,
                wsPart == null ? "NOT FOUND!" : "found.");

            if (wsPart == null)
            {
                continue;
            }

            Row[] rows = wsPart.Worksheet.Descendants<Row>().ToArray();

            //assumes the first row contains column names 
            foreach (Row row in wsPart.Worksheet.Descendants<Row>())
            {
                rowsComplete++;

                bool emptyRow = true;
                List<object> rowData = new List<object>();
                string value;

                foreach (Cell c in row.Elements<Cell>())
                {
                    value = GetCellValue(c);
                    emptyRow = emptyRow && string.IsNullOrWhiteSpace(value);
                    rowData.Add(value);
                }

                Debug.WriteLine("Row {0}: {1}", row,
                    emptyRow ? "EMPTY!" : string.Join(", ", rowData));
            }
        }

    }
    Debug.WriteLine("Done, processed {0} rows.", rowsComplete);
}

public static string GetCellValue(Cell cell)
{
    if (cell == null)
        return null;
    if (cell.DataType == null)
        return cell.InnerText;

    string value = cell.InnerText;
    switch (cell.DataType.Value)
    {
        case CellValues.SharedString:
            // For shared strings, look up the value in the shared strings table.
            // Get worksheet from cell
            OpenXmlElement parent = cell.Parent;
            while (parent.Parent != null && parent.Parent != parent
                    && string.Compare(parent.LocalName, "worksheet", true) != 0)
            {
                parent = parent.Parent;
            }
            if (string.Compare(parent.LocalName, "worksheet", true) != 0)
            {
                throw new Exception("Unable to find parent worksheet.");
            }

            Worksheet ws = parent as Worksheet;
            SpreadsheetDocument ssDoc = ws.WorksheetPart.OpenXmlPackage as SpreadsheetDocument;
            SharedStringTablePart sstPart = ssDoc.WorkbookPart.GetPartsOfType<SharedStringTablePart>().FirstOrDefault();

            // lookup value in shared string table
            if (sstPart != null && sstPart.SharedStringTable != null)
            {
                value = sstPart.SharedStringTable.ElementAt(int.Parse(value)).InnerText;
            }
            break;

        //this case within a case is copied from msdn. 
        case CellValues.Boolean:
            switch (value)
            {
                case "0":
                    value = "FALSE";
                    break;
                default:
                    value = "TRUE";
                    break;
            }
            break;
    }
    return value;
}

編集:GetCellValue()の修正に感謝 @ Nitin-Jadhav

31
saarp