【问题标题】:Export to excel in c# results in System.OutOfMemoryException在 c# 中导出到 excel 导致 System.OutOfMemoryException
【发布时间】:2017-09-22 07:21:56
【问题描述】:

我有一个包含 200,000 行的 DataTable。

我想将 DataTable 导出到 excel 文件中。但它给出了System.OutOfMemoryException 错误。

using (ExcelPackage objExcelPackage = new ExcelPackage()) 
{ 
    ExcelWorksheet objWorksheet = 
        objExcelPackage.Workbook.Worksheets.Add("Conversion Data");  
    objWorksheet.Cells["A1"].LoadFromDataTable(FinalResult, true); 
}

【问题讨论】:

  • 请出示您用于导出的相关代码。
  • 使用 (ExcelPackage objExcelPackage = new ExcelPackage()) { ExcelWorksheet objWorksheet = objExcelPackage.Workbook.Worksheets.Add("转换数据"); objWorksheet.Cells["A1"].LoadFromDataTable(FinalResult, true);
  • ExcelPackage 似乎是至少 2 年未更新的第三方库。为什么不使用正确的 OpenXML SDK?
  • 更好的是,为什么不使用 EPPlus?它可以很好地从数据表和集合中加载数据,并使创建 xlsx 文件变得更加容易。
  • 在哪里出现这个错误呢?发布完整的异常,包括调用堆栈。您如何创建该数据表?如果您从没有行的列表或数据表开始并一次添加一个,您可以获得 OOM。每次用完时,集合都会将其内部缓冲区加倍。对于 200K 行,有很多丢弃的缓冲区。内存可能会变得如此碎片化,以至于运行时无法为最新的缓冲区分配内存

标签: c# asp.net .net excel


【解决方案1】:

This answer 提供了一种将数据表拆分为较小块的方法(它是通用的,但适用于数据表),并且由于您需要解决的问题是数据表的大小,因此应该可以使用以下方法:

public static IEnumerable<IEnumerable<T>> ToChunks<T>(this IEnumerable<T> enumerable, int chunkSize)
{
    int itemsReturned = 0;
    var list = enumerable.ToList(); // Prevent multiple execution of IEnumerable.
    int count = list.Count;
    while (itemsReturned < count)
    {
        int currentChunkSize = Math.Min(chunkSize, count - itemsReturned);
        yield return list.GetRange(itemsReturned, currentChunkSize);
        itemsReturned += currentChunkSize;
    }
}

之后,按如下方式使用:

int rowCount = 1;
int chunkSize = 50000;
using (ExcelPackage objExcelPackage = new ExcelPackage()) 
{ 
    ExcelWorksheet objWorksheet = objExcelPackage.Workbook.Worksheets.Add("Conversion Data"); 
    //objWorksheet.Cells["A1"].LoadFromDataTable(FinalResult, true);
    foreach (var smallerTable in FinalResult.AsEnumerable().ToChunks(chunkSize))
    {
        objWorksheet.Cells["A" + rowCount].LoadFromDataTable(smallerTable, true);
        rowCount += chunkSize;
    }

基本上,rowCount 是跟踪 Excel 工作表上添加行的位置,每次迭代后,将插入到 A1、A50001、A100001 等的 1、50001、100001 等。

如果内存仍然有错误,尝试越来越小的chunkSize直到它起作用。

【讨论】:

  • 你为什么认为问题出在数据表的大小上?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多