3

我在 ASP.NET 应用程序中使用 NPOI 1.2.3.0 将相当大的 SQL 查询的结果导出到 Excel 2003 XLS 文件。

简而言之,查询结果被填充到 ADO.NET DataTable 中。然后,我有一个循环遍历 DataTable 中的行的例程,并为每一行添加一行到 NPOI 电子表格。它足够智能,一旦单个工作表的行数超过 65,000 行,就会创建一个新工作表,并且从新工作表的第一行开始,这些行会继续存在。

这种方法适用于我的一些较小的数据库查询,例如 30,000 行和 50 列,但我有一个查询,它返回 125,000 行以北,大约有 50 列,其中许多包含大量文本。

我能够毫无问题地构建电子表格,但是当我尝试将生成的电子表格流式传输到浏览器时,我OutOfMemoryException在调用HSSFWorkbook类的Write方法时得到了一个。(在内部,当 Write 方法调用类的GetBytes方法时会发生错误。)

如果我在调用 Write 方法之前运行调试器并停止,我会看到工作簿的 Size 属性返回一个(大约)6500 万的值。

CodePlex 的 NPOI 项目中记录了此错误 - 请参阅标题为内存不足问题的讨论- 但遗憾的是,没有找到解决方案。

为了完整起见,这里是引发异常的代码(具体来说,它是workbook.Write在线引发的)。

Using exportData As New MemoryStream()
    workbook.Write(exportData)

    Response.ContentType = "application/vnd.ms-excel"
    Response.AddHeader("Content-Disposition", "Attachment;Filename=" & saveAsName)
    Response.Clear()
    Response.BinaryWrite(exportData.GetBuffer())
    Response.End()
End Using

谢谢!

4

2 回答 2

1

在这种情况下我会做什么,记住 FileStream 对象不会导致错误,并且错误是由 32 位的 512MB 容量限制和 64 位的 2GB 限制引起的,尝试将文件写入 memoryStream,catch如果遇到错误,则返回到较大文件的 FileStream。

这里有一个明显的性能折衷,但如果您的用户正在下载 > 2GB 的文件,他们可能会认为这会慢一些:-)

有兴趣知道这是否适合您。

谢谢,戴夫

于 2011-06-07T22:04:50.840 回答
0

NPOI 不仅使用 MemoryStream,还使用字节数组。主要原因是字节数组。但到目前为止,NPOI 必须使用字节数组。目前还没有改变这一点的计划。给您造成的任何不便,请原谅。

于 2012-08-04T23:33:48.430 回答