2015-06-30 3 views
1

Я использую эту статью, чтобы прочитать очень большой файл Excel, используя SAX-подход.Чтение очень большого файла excel

https://msdn.microsoft.com/en-us/library/office/gg575571.aspx

Не может значение хранить в DataTable или память из-за клиентскую машину, не имея достаточно памяти. Попытка читать и сразу же значения хранить в базе данных:

// The SAX approach. 

static void ReadExcelFileSAX(string fileName) 
{ 
     using (SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Open(fileName, false)) 
    { 

     WorkbookPart workbookPart = spreadsheetDocument.WorkbookPart; 
     WorksheetPart worksheetPart = workbookPart.WorksheetParts.First(); 

     OpenXmlReader reader = OpenXmlReader.Create(worksheetPart); 
     string text; 
     while (reader.Read()) 
     { 
      if (reader.ElementType == typeof(CellValue)) 
      { 
       text = reader.GetText(); 
       Console.Write(text + " "); 
      } 
     } 
     Console.WriteLine(); 
     Console.ReadKey(); 
    } 
} 

Например, когда я прочитал этот Excel файл:

Test 1 
22 
345345 
345345435 
2333 
333333 
4444 
4444444 
324324 
99999 

я получаю этот выход:

Blank 
22 
Blank 
345345 
Blank 
etc 

у меня нет идея, откуда берутся пробелы. Пытался поставить там утверждение if там для проверки пробелов, то я пропустил последнее значение 99999.

Этот читатель кажется настолько ограниченным. Было бы очень благодарно за предложение, я имею в виду что угодно!

+0

Почему не разобрать и сохранить файл, добив строки? 1000 строк за раз должны быть в порядке? –

ответ

1

OpenXmlReader рассматривает начальный и конечный элементы как самостоятельные элементы. Их можно дифференцировать, проверяя свойства IsStartElement и IsEndElement.

Ваши пустые значения обусловлены конечными элементами, где GetText возвращает пустую строку.

У вас есть 2 варианта исправить это. Во-первых, вы можете проверить IsStartElement в цикле:

while (reader.Read()) 
{ 
    if (reader.ElementType == typeof(CellValue) 
     && reader.IsStartElement) 
    { 
     text = reader.GetText(); 
     Console.WriteLine(text + " "); 
    } 
} 

В качестве альтернативы вы можете использовать метод LoadCurrentElement загрузить весь элемент, потребляя как начало и конец вы получали раньше:

while (reader.Read()) 
{ 
    if (reader.ElementType == typeof(CellValue)) 
    { 
     CellValue cellVal = (CellValue)reader.LoadCurrentElement(); 
     Console.WriteLine(cellVal.Text); 
    } 
}