Есть ли SAX способ перебирать строки OpenXML? - PullRequest
2 голосов
/ 06 июля 2011

Я анализирую большой файл, используя подход SAX, предложенный для: Анализ и чтение больших файлов Excel с помощью Open XML SDK

Это моя модифицированная версия (для простоты получаем только номер строки)

using (SpreadsheetDocument myDoc = SpreadsheetDocument.Open("BigFile.xlsx", true))
{
    WorkbookPart workbookPart = myDoc.WorkbookPart;
    WorksheetPart worksheetPart = workbookPart.WorksheetParts.First();

    OpenXmlReader reader = OpenXmlReader.Create(worksheetPart);
    String rowNum;
    while (reader.Read())
    {
        if (reader.ElementType == typeof(Row))
        {
            if (reader.HasAttributes)
                rowNum = reader.Attributes.First(a => a.LocalName == "r").Value
        }
    }
}

Проблема заключается в том, что этот цикл проходит через каждый элемент / ячейку / столбец / что угодно и действует только тогда, когда тип элемента - Row.

Есть ли SAX способ зацикливаться только на строках, а не на каждом элементе на листе?

Спасибо

1 Ответ

2 голосов
/ 07 июля 2011

Ключ заключается в использовании методов считывателя Skip() и ReadNextSibling() ...

 using (SpreadsheetDocument myDoc = SpreadsheetDocument.Open("BigFile.xlsx", true))
 {
     WorkbookPart workbookPart = myDoc.WorkbookPart;
     WorksheetPart worksheetPart = workbookPart.WorksheetParts.First();
     OpenXmlReader reader = OpenXmlReader.Create(worksheetPart);
     String rowNum;
     while (reader.Read())
     {
         if (reader.ElementType == typeof(Row))
         {
             do
             {
                 if (reader.HasAttributes)
                     rowNum = reader.Attributes.First(a => a.LocalName == "r").Value;

             } while (reader.ReadNextSibling()); // Skip to the next row
             break; // We just looped through all the rows so no need to continue reading the worksheet
         }

         if (reader.ElementType != typeof(Worksheet)) // Dont' want to skip the contents of the worksheet
             reader.Skip(); // Skip contents of any node before finding the first row.
     }
}
...