Поделиться через


Анализ и чтение большого документа электронной таблицы

В этом разделе показано, как использовать классы в пакете 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();
    }
}

См. также

Структура документа SpreadsheetML