Анализ и чтение большого документа электронной таблицы
В этом разделе показано, как использовать классы в пакете SDK Open XML для Office для программного чтения большого файла Excel. Дополнительные сведения об основной SpreadsheetML
структуре документа см. в разделе Структура документа SpreadsheetML.
Примечание.
Хотите создавать решения, которые расширяют возможности Office на разнообразных платформах? Ознакомьтесь с новой моделью надстроек Office. Надстройки Office занимают меньше места по сравнению с надстройками и решениями VSTO, и вы можете создавать их, используя практически любую технологию веб-программирования, например HTML5, JavaScript, CSS3 и XML.
Подходы к анализу файлов Open XML
Пакет Open XML SDK обеспечивает два подхода к анализу файлов Open XML. Можно использовать функции чтения и записи объектной модели документов SDK (DOM) или программного интерфейса Simple API для XML (SAX). Объектная модель SDK DOM предназначена для простой обработки файлов Open XML с помощью строго типизированных классов.
Однако подход DOM требует загрузки всех частей Open XML в память, что может вызвать Out of Memory
исключение при работе с очень большими файлами. При использовании SAX можно применять OpenXMLReader для чтения XML в файле по одному элементу за раз, не загружая весь файл в память. SAX следует использовать при обработке очень больших файлов.
Следующий фрагмент кода используется для чтения большого файла Excel с помощью объектной модели DOM.
WorkbookPart workbookPart = spreadsheetDocument.WorkbookPart ?? spreadsheetDocument.AddWorkbookPart();
WorksheetPart worksheetPart = workbookPart.WorksheetParts.First();
SheetData sheetData = worksheetPart.Worksheet.Elements<SheetData>().First();
string? text;
foreach (Row r in sheetData.Elements<Row>())
{
foreach (Cell c in r.Elements<Cell>())
{
text = c?.CellValue?.Text;
Console.Write(text + " ");
}
}
Указанный ниже пример кода выполняет ту же задачу, что и предыдущий (чтение большого файла Excel), но при этом используется подход SAX. Это рекомендуемый подход для чтения очень больших файлов.
WorkbookPart workbookPart = spreadsheetDocument.WorkbookPart ?? spreadsheetDocument.AddWorkbookPart();
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 + " ");
}
}
Пример кода
Можно представить ситуацию, когда пользователь работает в финансовой организации, обрабатывающей очень большие таблицы Excel. Эти таблицы обновляются ежедневно, и их размер может быстро достичь сотен мегабайт. Требуется решение для чтения и извлечения нужных данных из каждой таблицы. Указанный ниже пример кода содержит два метода, соответствующих каждому из двух подходов, DOM и SAX. Последний способ позволяет избежать исключений нехватки памяти при работе с очень большими файлами. Можно вызвать каждый из методов в коде последовательно или отдельно, закомментировав вызов ненужного метода.
// Comment one of the following lines to test the method separately.
ReadExcelFileDOM(args[0]); // DOM
ReadExcelFileSAX(args[0]); // SAX
Ниже приведен полный пример кода на языках C# и Visual Basic.
// The DOM approach.
// Note that the code below works only for cells that contain numeric values
static void ReadExcelFileDOM(string fileName)
{
using (SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Open(fileName, false))
{
WorkbookPart workbookPart = spreadsheetDocument.WorkbookPart ?? spreadsheetDocument.AddWorkbookPart();
WorksheetPart worksheetPart = workbookPart.WorksheetParts.First();
SheetData sheetData = worksheetPart.Worksheet.Elements<SheetData>().First();
string? text;
foreach (Row r in sheetData.Elements<Row>())
{
foreach (Cell c in r.Elements<Cell>())
{
text = c?.CellValue?.Text;
Console.Write(text + " ");
}
}
Console.WriteLine();
Console.ReadKey();
}
}
// The SAX approach.
static void ReadExcelFileSAX(string fileName)
{
using (SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Open(fileName, false))
{
WorkbookPart workbookPart = spreadsheetDocument.WorkbookPart ?? spreadsheetDocument.AddWorkbookPart();
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();
}
}