2009-08-21 15 views
6

Używam OpenXML SDK 2.0 do generowania pliku Excel z dużą ilością danych, appox. 1000000 wierszy i muszę zoptymalizować wykorzystanie pamięci, ponieważ moja maszyna bardzo szybko zwalnia.Jak skutecznie buforować i czyścić strumień w Open XML SDK

Chcę rozwiązać ten problem, przepłukując część wygenerowanego drzewa DOM do pliku w środowisku wykonawczym. Wykonuję własne buforowanie danych. E.g Mam do zapisania 100000 rekordów i chcę, aby strumień był przepuszczany do pliku po dodaniu 1000 wierszy do arkusza programu Excel. Robię to za pomocą metody worksheetPart.Worksheet.Save(). Documantation mówi taht tej metody save() „zapisuje dane w drzewie DOM z powrotem do części mogłaby być wywołana wiele razy jak dobrze Za każdym razem to się nazywa, strumień zostanie oczyszczony.”.

  foreach (Record m in dataList) 
     { 
      Row contentRow = CreateContentRow(index, m);   // my own method to create row content 

      //Append new row to sheet data. 
      sheetData.AppendChild(contentRow); 

      if (index % BufferSize == 0) 
      { 
       worksheetPart.Worksheet.Save(); 
      } 

      index++; 

     } 

Ta metoda działa, ponieważ wykres wykorzystania pamięci ma kształt piłokształtny, ale niestety pamięć pamięci rośnie w czasie.

Czy ktoś ma pomysł, jak rozwiązać ten problem?

Odpowiedz

3

może tworzyć skoroszyt xlsx z 1 000 000 wierszy przez 40 kolumn liczb losowych (to 40 milionów komórek) w 74 sekundy Windows Vista 32).

Jaki rodzaj wydajności widzisz dzięki Open XML SDK?

Możesz pobrać bezpłatną wersję próbną programu SpreadsheetGear here i wypróbować samodzielnie.

Przekażę kod, aby wygenerować 40-milionowy skoroszyt komórki poniżej.

Zastrzeżenie: Jestem właścicielem SpreadsheetGear LLC

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using SpreadsheetGear; 

namespace ConsoleApplication10 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      try 
      { 
       // Run once with 100 rows and then run forever with 1,000,000 rows. 
       for (int rows = 100; rows <= 1000000; rows = 1000000) 
       { 
        Console.Write("rows={0}, ", rows); 
        var startMemory = System.GC.GetTotalMemory(true); 
        var timer = System.Diagnostics.Stopwatch.StartNew(); 
        var workbook = BuildWorkbook(rows); 
        var usedMemory = System.GC.GetTotalMemory(true) - startMemory; 
        Console.WriteLine("usedMemory={0}, time={1} seconds, workbook.Name={2}", usedMemory, timer.Elapsed.TotalSeconds, workbook.Name); 
        workbook = null; 
       } 
      } 
      catch (Exception e) 
      { 
       Console.WriteLine("got exception={0}", e.Message); 
      } 
     } 

     static IWorkbook BuildWorkbook(int rows) 
     { 
      var workbook = Factory.GetWorkbook(); 
      var worksheet = workbook.Worksheets[0]; 
      var values = (SpreadsheetGear.Advanced.Cells.IValues)worksheet; 
      Random rand = new Random(); 
      int cols = 40; 
      for (int col = 0; col < cols; col++) 
      { 
       for (int row = 0; row <= rows; row++) 
       { 
        values.SetNumber(row, col, rand.NextDouble()); 
       } 
      } 
      workbook.SaveAs(string.Format(@"c:\tmp\Rows{0}.xlsx", rows), FileFormat.OpenXMLWorkbook); 
      return workbook; 
     } 
    } 
} 
+0

Dziękuję za odpowiedź. Sprawdzę, czy SpreadsheetGear pomoże mi rozwiązać mój problem. Przedstawiam mój problem z wydajnością Open XML SDK w tym poście: http: //blog.goyello.com/2009/08/25/read-before-using-it-open-xml-sdk-performance-analysis/ –

+4

Doskonale sformułowane pytanie, które pojawia się jako pierwszy wynik w Google. Obejrzano 1200 razy. A jedyną odpowiedzią jest żałosna wtyczka do zewnętrznej biblioteki detalicznej? – mdisibio

+0

Zwłaszcza, że ​​jest to bardzo drogie biblioteki stron trzecich. Przy 1000 USD, arkusz kalkulacyjny jest zbyt drogi. – Wade73

0

Jest przeciwieństwem podejście do „bufor i równo” dla zadania pisania dużych plików Excel. Podejście opiera się na użyciu klasy OpenXmlWriter i wykorzystuje sekwencyjne zapisywanie zamiast buforowania i płukania. Jedno typowe rozwiązanie wykorzystuje także część zamienną i OpenXmlReader, aby uzyskać niezmienioną zawartość z szablonu. Spójrz na "Writing Large Excel Files with the Open XML SDK" (z kilkoma przykładami kodu) i "Write large OpenXML docs" (z pełnym przykładem kodu).

Powiązane problemy