【问题标题】:How to process extremely large .xlsx files with C#如何使用 C# 处理超大的 .xlsx 文件
【发布时间】:2020-01-19 13:57:04
【问题描述】:

我需要解决的情况

我的客户有一些非常大的 .xlsx 文件,类似于数据库表(每行是一条记录,列是字段)

我需要帮助他们处理这些文件(搜索、过滤等)。

我指的是其中最小的有 100 万条记录。


我尝试过的:

  • SheetJS 和 NPOI:两个库都只回复一个简单的“文件太大”。
  • EPPlus:最多可以读取数百 K 条记录的文件,但是当面对实际文件时,它只会给我一个 System.OverflowException,我的猜测是它基本上内存不足,因为 200MB xlsx 文件已经占用了我 4GB要读取的内存。
  • 我没有尝试过 Microsoft OleDB,但我宁愿避免使用它,因为我不想仅仅为了工作而购买 Microsoft Office。

由于机密性,我无法共享实际文件,但您可以轻松地创建一个包含 60 个列(名字、姓氏、出生日期等)和大约 100 万条记录的类似结构。

只要您可以读取具有该条件的 .xlsx 文件,删除一半的记录然后写入另一个位置,问题就会解决,而不会遇到内存问题。

  • 时间不是什么大问题。如果需要,用户愿意等待一两个小时才能得到结果。
  • 内存似乎是当前的问题。这是个人要求,客户的机器是一台笔记本电脑,内存上限为 8GB。
  • csv 不是这里的一个选项。我的客户有 .xlsx 输入,需要 .xlsx 输出。
  • 语言选择最好是 JS,Python 的 C#,因为我已经知道如何使用它们创建可执行文件(我们不能告诉会计学习终端,对吗?)。

如果有办法从文件中逐行缓慢读取小块数据,那就太好了,但我发现的解决方案只能同时读取整个文件。

【问题讨论】:

  • 保存为未压缩的 XML,然后使用流阅读器读取,XmlTextReader。假设您在保存 excel 时注意选择的编码,那么存储为 CSV 也应该可以。
  • 谢谢我正在检查读者。 CSV好像不行,我自己做了转换,虽然我特意选择了UTF-8编码,结果文件还是丢字符+_+

标签: c# excel memory-management


【解决方案1】:

为了阅读Excel 文件,我推荐ExcelDataReader。它在读取大文件方面做得很好。我个人试过500k-1M

using (var stream = File.Open("C:\\temp\\input.xlsx", FileMode.Open, FileAccess.Read))
{
    using (var reader = ExcelReaderFactory.CreateReader(stream))
    {
        while (reader.Read())
        {
            for (var i = 0; i < reader.FieldCount; i++)
            {
                var value = reader.GetValue(i)?.ToString();
            }
        }
    }
}

以同样有效的方式写回数据更加棘手。我完成了创建自己的 SwiftExcel 库,它非常快速和高效(有一个与其他 Nuget 库(包括 EPPlus 相比)的性能图表),因为它不使用任何 XML 序列化并将数据直接写入文件:

using (var ew = new ExcelWriter("C:\\temp\\test.xlsx"))
{
    for (var row = 1; row <= 100; row++)
    {
        for (var col = 1; col <= 10; col++)
        {
            ew.Write($"row:{row}-col:{col}", col, row);
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多