2014-11-06 20 views
6

Systemspeicherausnahme. Ich sehe den Speicher Stream wird nur beim Speichern gespült. Wir haben 1,5 - 2GB Datensätze.EPPlus großes Dataset-Problem mit nicht genügend Arbeitsspeicher Ausnahme

I EPPlus Version 3.1.3.0

Wir nach dem in Code verwenden.

Wir Schleife durch

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

Jede Datentabelle ist eine 300mg Größe bis zu 15 Tabellen, um das System zu bilden.

Dies ist ein Problem verursacht, habe ich das @https://epplus.codeplex.com/workitem/15085

detailliert protokolliert

Ich möchte immer noch in der Lage sein EPPlus seine sehr schöne API zu verwenden. Aber gibt es eine bessere Möglichkeit, ein Arbeitsblatt freizugeben, nachdem wir es dem Paket hinzugefügt haben?

Vielen Dank für Ihre Hilfe.

Antwort

7

Leider scheint dies eine große Einschränkung von EPPlus zu sein - Sie können andere darüber auf ihrer Codeplexseite finden. Ich lief in ein ähnliches Problem, wenn großen Datenmenge Export - Einzeltische mit 115+ Spalten breit und 60K + Reihen hoch. In der Regel sind es 30 bis 35.000 Zeilen, wenn der Arbeitsspeicher knapp wird. Was passiert, ist, dass jede Zelle, die erzeugt wird, ein eigenes Objekt ist, was für kleine Datensätze gut ist, aber in meinem Fall wäre es 115x60K = ~ 7 Millionen. Da jede Zelle ein Objekt mit Inhalt (meist Strings) ist, summiert sich ihr Speicherbedarf schnell.

Irgendwann in der Zukunft war mein Plan, die XML-Dateien manuell mit Linq2Xml zu erstellen. Ein xlsx ist nur eine Zip-Datei, die mit XML-Dateien umbenannt wurde, die den Inhalt der Arbeitsmappe und der Arbeitsblätter bilden. Sie könnten also ein leeres xlsx mit EPP erstellen, es speichern, es als Zip öffnen, sheet1.xml herausziehen und den Dateninhalt per String-Manipulation hinzufügen. Sie würden auch auf der sharedstring.xml Datei arbeiten, die Excel die Dateigröße nach unten, um zu helfen verwendet. Es gibt wahrscheinlich andere XML-Dateien, die auch mit Schlüsseln oder Namen aktualisiert werden müssen.

Wenn Sie xlxs zu einer ZIP-Erweiterung umbenennen können Sie das sehen.

Beispiel 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> 

Beispiel sharedstrings.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> 

Sie können sehen, wie ich xml Manipulation habe in meinem anderen Beitrag:

Create Pivot Table Filters With EPPLUS

Leider

Ich könnte nicht geben Ihnen eine bessere Antwort, aber hoffentlich das hilft.

0

@Ernie korrekt über einige der Einschränkungen der aktuellen Version von EPPlus. Sie haben das erkannt und haben daran gearbeitet, es zu beheben. Dies lässt Ihnen eine von zwei möglichen Optionen, um dies zum Laufen zu bringen:

1) Wechseln Sie in die EPPlus 4.0 Beta, wo sie dieses Problem behoben haben, zusammen mit einigen anderen Dingen (obwohl Sie verwenden werden eine Beta-Version).

2) Die ExcelPackage und ExcelWorksheet Klassen beider implementieren IDisposable, so dass Sie ein bessere Leistung beginnen könnten bekommen, wenn Sie Ihre Nutzung von ihnen in einer using() Aussage wickeln sind.

+2

Alle Dokumention, die es in der Beta 4 festgelegt ist? Es machte keinen Unterschied für mich - zugegeben, das war vor ein paar Monaten. Ich würde es gerne reparieren, aber es sah so aus, als ob es eine Generalüberholung der Kernmaschine erfordert. Ich benutze immer IDisposable (über Using's) und es macht keinen Unterschied für mich. Das Problem ist, dass das Paket/die Arbeitsmappen im Speicher verbleiben, bis sie vollständig geschlossen sind. Ich habe sogar versucht, die Daten schrittweise durch eine Reihe von Open-Save-Close-Reopen-Add zu exportieren und es machte keinen Unterschied. Es ist alles oder nichts - sobald Sie die Datei öffnen, wird ALL geladen. Nochmals, würde gerne falsch bewiesen werden. – Ernie

+0

EPPlus 4.1.0 löst es nicht. Und das Auflösen hilft nicht, wenn Sie nur 1 Arbeitsblatt zum Schreiben haben. – Heiner

7

Ich hatte dieses Problem, aber ich regelte es durch die Möglichkeit, „Platform target“ Umschalten von x86 zu x64 oder „Any CPU“. (Rechtsklick auf das Projekt, dann wählen Sie "Eigenschaften", dann die Registerkarte "Build", dann auf "Platform Ziel" wählen Sie "x64")

Das Problem ist, dass für Plattform x86 Sie nur etwa 1,8 GB verwenden können RAM. Für Plattform x64 haben Sie diese Einschränkung nicht.

+1

Das hat auch für mich funktioniert. Hatte eine Excel-Tabelle mit 210.000 Datensätzen und bekam Ausnahmebedingungen. Zuerst dachte ich, dass es so war, weil ich viele Sachen parallel mache; Neukompilieren im x64-Modus löste es. –

0

Achten Sie darauf, wenn Sie Streams an das ExcelPackage übergeben. In meinem Fall hatte ich einen Windows-Dienst, indem ich einen Packages mit einem Memory-Stream lud. Jetzt stürzte der Dienst nach einiger Zeit mit einer OutOfMemory-Ausnahme ab.

Grund: Das Entsorgen des ExcelPackage disposed den Strom nicht!

Lösung:

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