EPPlus 大数据集内存不足异常问题

问题描述 投票:0回答:6

系统内存不足异常。我看到内存流仅在保存时刷新。我们有 1.5 - 2GB 数据集。

我正在使用 EPPlus 版本 3.1.3.0

我们在代码中执行以下操作。

我们循环遍历

     --> Create a Package
        --> each table in the datareader
            -->   Add WorkSheet to the Package 
        --> Dispose Each table.
     --> Save the  Package.

每个数据表大小为 300 毫克,系统最多可容纳 15 个表。

这导致了一个问题,我已详细记录了@ https://epplus.codeplex.com/workitem/15085

我仍然希望能够使用 EPPlus 其非常好的 API。但是,一旦我们将工作表添加到包中,是否有更好的方法来释放工作表。

谢谢您的帮助。

c# excel excel-2007 epplus
6个回答
17
投票

我遇到了这个问题,但我通过将“

Platform target
”选项从
x86
切换到
x64
或“
Any CPU
”来解决它。 (右键单击项目,然后选择“属性”,然后选择“构建”选项卡,然后在“平台目标”上选择“x64”)

问题是,对于平台

x86
,您只能使用大约 1.8 GB 的 RAM。对于平台
x64
,您没有此限制。


9
投票

不幸的是,这似乎是 EPPlus 的一个主要限制 - 您可以在他们的 codeplex 页面上找到其他人发布的相关内容。我在导出大型数据集时遇到了类似的问题 - 宽度超过 115 列、高度超过 60K 行的单个表。通常,大约 30 到 35k 行时内存就会耗尽。所发生的情况是,创建的每个单元格都是它自己的对象,这对于小型数据集来说很好,但在我的情况下,它将是 115x60K= ~700 万。由于每个单元格都是一个包含内容(主要是字符串)的对象,因此它的内存占用量会快速增加。

在未来的某个时候,我的计划是使用 Linq2Xml 手动创建 XML 文件。 xlsx 只是一个用构成工作簿和工作表内容的 XML 文件重命名的 zip 文件。因此,您可以使用 EPP 创建一个空的 xlsx,保存它,以 zip 格式打开它,拉出sheet1.xml 并通过字符串操作添加数据内容。您还必须处理sharedstring.xml 文件,Excel 使用该文件来帮助减小文件大小。可能还有其他 xml 文件需要更新键或名称。

如果您将任何 xlx 重命名为 .zip 扩展名,您可以看到这一点。

sheet1.xml 示例:

Simple Excel File Example

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="x14ac" xmlns:x14ac="http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac">
    <dimension ref="A1:C2"/>
    <sheetViews>
        <sheetView tabSelected="1" workbookViewId="0">
            <selection activeCell="C5" sqref="C5"/>
        </sheetView>
    </sheetViews>
    <sheetFormatPr defaultRowHeight="15" x14ac:dyDescent="0.25"/>
    <sheetData>
        <row r="1" spans="1:3" x14ac:dyDescent="0.25">
            <c r="A1" t="s">
                <v>0</v>
            </c><c r="B1" t="s">
                <v>1</v>
            </c><c r="C1" t="s">
                <v>0</v>
            </c>
        </row>
        <row r="2" spans="1:3" x14ac:dyDescent="0.25">
            <c r="A2" t="s">
                <v>1</v>
            </c><c r="B2" t="s">
                <v>0</v>
            </c><c r="C2" t="s">
                <v>1</v>
            </c>
        </row>
    </sheetData>
    <pageMargins left="0.7" right="0.7" top="0.75" bottom="0.75" header="0.3" footer="0.3"/>
</worksheet>

共享字符串.xml 示例:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" count="6" uniqueCount="2">
    <si>
        <t>AA</t>
    </si>
    <si>
        <t>BB</t>
    </si>
</sst>

你可以在我的另一篇文章中看到我是如何进行 xml 操作的:

使用 EPPLUS 创建数据透视表过滤器

抱歉我无法给您更好的答案,但希望对您有所帮助。


0
投票

@Ernie 对于当前版本 EPPlus 的一些限制是正确的。他们已经承认了这一点,并一直在努力解决这个问题。这为您提供了两种可能的选择之一来使其发挥作用:

1) 切换到 EPPlus 4.0 Beta,他们已经修复了这个问题以及其他一些问题(尽管您将使用 beta 版本)。

2)

ExcelPackage
ExcelWorksheet
类都实现
IDisposable
,因此如果您将它们的使用包装在
using()
语句中,您可能会开始获得更好的性能。


0
投票

如果您将流传递到 ExcelPackage,请注意。就我而言,我有一个 Windows 服务,使用内存流加载包。现在,服务在一段时间后崩溃并出现 OutOfMemory 异常。

原因:ExcelPackage的dispose并没有dispose流!

解决方案:

using (MemoryStream ms = new MemoryStream(Convert.FromBase64String(excelSheetBase64)))
using (ExcelPackage excelPackage = new ExcelPackage(ms))
{
    // Your code
}

0
投票

在调试大量数据时有时会出现此问题。

如果您在服务器中尝试应用程序为 true

IIS
或者在您的 PC 中的 tru IIS 中(如果您有
Win PRO
版本

OutOFMemoryException
上的问题不会出现。


0
投票

就我而言,我在

x86
平台上使用了EPPlus 7.0.1,有4张,总共约10万行。当在
sheet.Cells.AutoFitColumns()
上调用
ExcelWorksheet
时,它又消耗了 300MB RAM 并抛出
OutOfMemoryException

如果您的记忆力有限,请考虑不要使用该方法。

© www.soinside.com 2019 - 2024. All rights reserved.