使用ClosedXML读取XLSX文件时如何优化内存使用

3
我有一个包含约30列和130,000行的XLSX表格。
过去我使用OleDb数据读取器来解析这样的文件,但在读取混合单元格数据类型的未知Excel文件时会出现问题。
我发现了ClosedXML,但它的问题是内存使用量比OleDb高得多。我可能遗漏了什么,但似乎在访问单个单元格之前必须加载整个工作簿,当我想要读取一个单元格时,我的内存使用量会增加约500MB:
        using (XLWorkbook workBook = new XLWorkbook(_path))
        {
            IXLWorksheet workSheet = workBook.Worksheet(tableName);
            Console.WriteLine(workSheet.Cell(1, 1).Value);
        }

有没有什么方法可以优化这个问题?

  • 延迟加载单元格?
  • 减少加载的单元格属性,只加载感兴趣的属性?
  • 还有其他什么方法吗?

如果没有优化的选项,您能推荐其他的框架/库吗?

谢谢。


请编辑问题,将其限制为具有足够细节以确定充分答案的特定问题。 - Community
3个回答

1

内存使用可能会很难避免,这取决于文件中数据的类型。在内部,Excel 文件使用 "共享字符串" 表来存储每个字符串的单个副本,并从工作表数据中通过索引引用这些字符串。我想大多数库都会在读取任何工作表数据之前加载整个共享字符串表。如果您的文件有很多唯一的字符串,加载整个共享字符串表可能需要一些时间和内存。

ClosedXML 是读取 Excel 数据最低效的库之一。如 Francois 所提到的,这可能并不令人惊讶,因为该库旨在支持其他库不支持的深度功能。

如果您只想要数据读取功能,可以看看我维护的库:Sylvan.Data.Excel。它非常易于使用,是 .NET 中最快速的 Excel 数据读取库。在这个特定的基准测试中,Sylvan 比 ClosedXML 快了 10 倍以上,并且使用的内存只是其一小部分。


0
如@MarkPflug所提到的,大多数库将整个sharedString加载到RAM中。正因为如此,它会占用大量内存。
如果sharedString的大小超过20MB,XlsxHelper不会将其加载到RAM中。由于这种实现方式,它对于小型Xlsx文件来说速度快,对于大型文件来说内存效率高。
这里是源代码Nuget的链接。
免责声明:我是XlsxHelper的作者。

0
似乎整个工作簿必须在访问单个单元格之前加载,这是正确的。这是ClosedXML的设计行为。它意味着需要更高的内存使用来促进更强大的单元格操作。如果内存使用是您的问题,我建议尝试使用不同的库,比如EPPlus。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接