【问题标题】:System.OutOfMemoryException while writing to excel写入 excel 时出现 System.OutOfMemoryException
【发布时间】:2014-10-07 13:48:36
【问题描述】:
        Public Function GenerateReportAsExcel()
        Dim workbook = WorkbookFactory.Create(template)
        template.Close()
        Dim worksheet = workbook.GetSheetAt(0)

    //           Writing record to worksheet


        Dim workbookStream = New MemoryStream()
        workbookStream.Flush()
        workbookStream.Position = 0
        workbook.Write(workbookStream)  //throws error if the rocord is more then 500000...runs fine for 400000 

        Return New MemoryStream(workbookStream.ToArray())
    End Function

WorkbookFactory 正在使用 NPOI.SS.UserModel ....

有没有办法增加内存流容量?我在将 500000 条记录写入 excel 时收到 System.OutOfMemoryException,但最多 400000 条记录工作正常。 我发现了几个类似的问题,但没有得到任何可靠的解决方案...... 有人建议使用

workbookStream.Flush() 工作簿流位置 = 0 但没有任何帮助....

感谢您的关心..

【问题讨论】:

  • 我看到发生了一些复制(看起来你最终在内存中有 3 个副本 - 来自工厂的副本,你放在第一个内存流中的副本,然后在你排列它时再次复制. 注释掉的中间发生了什么?某些东西创建垃圾的速度比 GC 收集它的速度更快,或者创建了无法收集的垃圾,例如不调用 dispose,或者您正在使用一个内存数据结构,只是没有' t 适合 IIS 允许的空间(很小,例如每个请求 800MB)
  • 400000 条记录时 woorkBookstream 有多大(又名 Length 属性)?
  • 请稍等,让我检查一下...
  • @MatthewMartin Dim masterRow = worksheet.CreateRow(RowMasterId) masterRow.CreateCell(ColumnOneCriteria, CellType.STRING).SetCellValue(masterName)....这就是我向工作表添加列的方式..我正在添加至少 80 个这样的列...
  • 我猜测 excel 文档是由一个完全在内存中的数据结构表示的。这发生在完全保存在内存中的数据集、XML 和任何其他大数据结构中。就像您创建了一堆 1GB 字符串一样,最终您没有足够的空间将其保存在内存中。然后您必须切换到流式 API,以确保您永远不会在内存中拥有整个对象图。

标签: asp.net-mvc vb.net excel out-of-memory memorystream


【解决方案1】:

你在什么环境下运行? 如果它是 32 位的,你会在 aprox 处得到 OutOfMemoryException。 500meg 内存流。

    static void Main(string[] args)
    {
        var buffer = new byte[1024 * 1024];
        Console.WriteLine(IntPtr.Size);
        using (var memoryStream = new MemoryStream())
        {
            for (var i = 0; i < 100000000; i++)
            {
                try
                {
                    memoryStream.Write(buffer, 0, 1024);
                }
                catch (OutOfMemoryException e)
                {
                    Console.WriteLine("Out of memory at {0} meg", i);
                    break;
                }
            }
        }
        Console.ReadKey();
    }

如果您在 64 位操作系统上运行,请确保您在构建时关闭了“首选 32 位”开关。 关闭项目属性中的开关:

我建议在这里使用 FileStream 而不是 MemoryStream。

【讨论】:

    【解决方案2】:

    下面的代码什么都没加,你可以放手:

        workbookStream.Flush()       ' Does nothing
        workbookStream.Position = 0  ' Does nothing
    

    但剩下的就是记忆问题了。您需要更多的工作内存 (RAM) 才能完成您想做的事情。因此,如果您将 RAM 内存添加到机器上,您应该很高兴......除非您有一台 32 位机器并且遇到 3GB 的实际 RAM 限制。在这种情况下,您需要升级到不存在此内存限制的 64 位计算机。

    但如果您正在生成 Excel 文件,您可能希望查看 ClosedXML 而不是使用 Excel 对象模型。这是一个在您的机器上不需要 Excel 的库。看看http://www.campusmvp.net/blog/generating-excel-files-like-a-pro-with-closedxml

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-06-27
      • 1970-01-01
      • 1970-01-01
      • 2013-08-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多