Analisar e ler um documento de folha de cálculo grande
Este tópico mostra como utilizar as classes no SDK Open XML para o Office para ler programaticamente um ficheiro grande do Excel. Para obter mais informações sobre a estrutura básica de um SpreadsheetML
documento, veja Estrutura de um documento de Folha de CálculoML.
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 Open XML inteiras para a memória, o que pode causar uma exceção Out of Memory
quando estiver a trabalhar com ficheiros 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();
}
}