gpt4 book ai didi

c# - 与文档相反,OpenXML 无助于读取大型 Excel 文件

转载 作者:太空宇宙 更新时间:2023-11-03 21:23:30 25 4
gpt4 key购买 nike

documentation说:

The following code segment is used to read a very large Excel 
file using the DOM approach.

然后举个例子。我用它来实现读取一个700K行的比较大的文件。我现在有这段代码:

using (SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Open(path, false)) 
{
WorkbookPart workbookPart = spreadsheetDocument.WorkbookPart;
WorksheetPart worksheetPart = workbookPart.WorksheetParts.First();
SheetData sheetData = worksheetPart.Worksheet.Elements<SheetData>().First();
// no other code
}

当我启动我的程序时,我发现它很快就用完了内存(>1G)——仅仅五秒钟。并且调试器指向这行代码:

SheetData sheetData = worksheetPart.Worksheet.Elements<SheetData>().First();

所以,我需要知道 OpenXML 是否真的有助于读取大文件。如果没有,还有哪些替代方案(Interop 没有帮助 - 我已经检查过了)。

编辑

一个额外的神秘事物。我现在得到的这段代码:

OpenXmlReader reader = OpenXmlReader.Create(worksheetPart);
while (reader.Read())
{
if (reader.ElementType == typeof(Row))
{
count++;
}
}

给我 count 变量超过一百万行。但是,我在第一张纸上有 14K,在第二张纸上有 700K。这很奇怪。因此,我的额外问题是如何使用 SAX 方法仅解析包含数据的行。以及在 OpenXML 上读取大型 Excel 文件的最后一个谜。这里面的一个人thread说:“原来工作表由于某种原因被向后枚举(所以我的三张纸中的第一张实际上是索引 3”。所以,我最后一个额外的问题是如何获得你想要的工作表。此时我使用这个代码:

WorkbookPart workbookPart = spreadsheetDocument.WorkbookPart;
WorksheetPart worksheetPart = workbookPart.WorksheetParts.First();

但考虑到所说的话,我不确定在我的情况下我是否真的会得到第一个工作表。

最佳答案

您似乎有几个问题,我会尝试一一解决。

So, I need to know whether OpenXML really helps to read large files. And, if not, what are the alternatives (Interop does not help - I've already checked it).

是的,OpenXml SDK 非常适合读取大文件,但您可能需要使用 SAX 方法而不是 DOM 方法。来自您引用的同一文档:

However, the DOM approach requires loading entire Open XML parts into memory, which can cause an Out of Memory exception when you are working with really large files.... Consider using SAX when you need to handle very large files.

DOM 方法将整个工作表加载到内存中,这对于大工作表可能会导致内存不足异常。使用 SAX 方法,您可以依次读取每个元素,从而大大减少内存消耗。

So, my extra question is how to parse only rows with data using SAX approach

使用 SDK 仅获取包含数据的行(或至少是 XML 中存在的行)。您似乎已经将此作为一个单独的问题提出,我已经更详细地回答了这个问题,但本质上您是在使用问题中的代码看到每个行元素的开始和结束。看我对你的回答 Why does OpenXML read rows twice有关详细信息的问题。

So, my final extra question is how to get the sheet you want.

您需要按名称找到 Sheet,它是 Workbook 的后代。一旦你有了它,你就可以使用它的 Id 来获取 WorksheetPart:

using (SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Open(filename, false))
{
WorkbookPart workbookPart = spreadsheetDocument.WorkbookPart;

Sheet sheet = workbookPart.Workbook.Descendants<Sheet>().Where(s => s.Name == sheetName).First();
if (sheet != null)
{
WorksheetPart worksheetPart = workbookPart.GetPartById(sheet.Id) as WorksheetPart;

//read worksheetPart...
}
}

关于c# - 与文档相反,OpenXML 无助于读取大型 Excel 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28897549/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com