Analisar e ler um documento de planilha grande

Este tópico mostra como usar as classes no Open XML SDK for Office para ler programaticamente um arquivo grande do Excel. Para obter mais informações sobre a estrutura básica de um SpreadsheetML documento, consulte Estrutura de um documento SpreadsheetML.

Observação

Interessado em desenvolver soluções que ampliem a experiência do Office em várias plataformas? Confira o novo modelo de Suplementos do Office. Os suplementos do Office ocupam um pequeno espaço em comparação com os suplementos e as soluções do VSTO, e você pode criá-los usando quase qualquer tecnologia de programação da Web, como o HTML5, JavaScript, CSS3 e XML.


Abordagens de análise de arquivos do Open XML

O SDK do Open XML oferece duas abordagens de análise de arquivos do Open XML. Você pode usar o SDK do DOM Document Object Model () ou Simple API for XML (SAX) leitura e gravação de recursos. O DOM do SDK é projetado para facilitar consultar e analisar arquivos Open XML usando classes fortemente tipadas. No entanto, a abordagem DOM requer o carregamento de partes inteiras do Open XML na memória, o que pode causar uma Out of Memory exceção quando você está trabalhando com arquivos realmente grandes. Usando a abordagem do SAX, você pode empregar uma OpenXMLReader para ler o XML no elemento de um arquivo por vez, sem a necessidade de carregar o arquivo inteiro na memória. Considere usar SAX quando você precisa lidar com arquivos muito grandes.

O seguinte segmento de código é usado para ler um arquivo muito grande do Excel usando a abordagem do 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 + " ");
    }
}

O segmento de código a seguir executa uma tarefa idêntica ao exemplo anterior (lendo um arquivo muito grande do Excel), mas usa a abordagem SAX. Essa é a abordagem recomendada para a leitura de arquivos muito grandes.

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 + " ");
    }
}


Código de exemplo

Você pode imaginar um cenário em que você trabalha para uma empresa financeira que lida com grandes planilhas do Excel. As planilhas são atualizadas diariamente por analistas e podem ser facilmente ampliado para tamanhos exceder centenas de megabytes. Você precisa de uma solução para ler e extrair dados relevantes de cada planilha. O exemplo de código a seguir contém dois métodos que correspondem às duas abordagens, DOM e SAX. A segunda técnica evitará exceções de memória ao usar arquivos muito grandes. Para experimentar, você pode chamá-las em seu código um após o outro ou você pode chamar cada método separadamente, comentar a chamada para aquele que deseja excluir.

// Comment one of the following lines to test the method separately.
ReadExcelFileDOM(args[0]);    // DOM
ReadExcelFileSAX(args[0]);    // SAX

A seguir está um exemplo de código completo em C# e 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();
    }
}

Confira também

Estrutura de um documento SpreadsheetML