分析和阅读大型电子表格文档
本主题演示如何使用 Open XML SDK for Office 中的类以编程方式读取大型 Excel 文件。 有关文档的基本结构 SpreadsheetML
的详细信息,请参阅 SpreadsheetML 文档的结构。
注意
有兴趣开发跨多个平台扩展 Office 体验的解决方案吗? 查看新的 Office 外接程序模型。 与VSTO外接程序和解决方案相比,Office外接程序占用的空间较小,您可以使用几乎任何Web编程技术(例如HTML5,JavaScript,CSS3和XML)来构建它们。
分析 Open XML 文件的方法
Open XML SDK 提供两种分析 Open XML 文件的方法。 可以使用 SDK 文档对象模型 (DOM) 或 Simple API for XML (SAX) 读取和写入功能。 SDK DOM 设计为使您可以使用强类型类轻松查询和分析 Open XML 文件。
但是,DOM 方法需要将整个 Open XML 部件加载到内存中,这在处理非常大的文件时可能会导致 Out of Memory
异常。 使用 SAX 方法,可以通过 OpenXMLReader 一次一个元素地读取文件中的 XML,而无需将整个文件加载到内存中。 当需要处理非常大的文件时,可考虑使用 SAX。
以下代码段用来通过 DOM 方法读取大型 Excel 文件。
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();
}
}