2009-08-21 21 views
6

Uso OpenXML SDK 2.0 para generar archivos de Excel con gran cantidad de datos, appox. 1000000 filas, y necesito optimizar el uso de la memoria porque mi máquina se desacelera muy rápido.Cómo realizar un búfer y una corriente de forma eficaz en Open XML SDK

Quiero resolver este problema al enjuagar parte del árbol DOM generado en un archivo en tiempo de ejecución. Yo hago mi propio buffering de datos. P. ej., Tengo 100000 registros para escribir y deseo que se ejecute el flujo en el archivo cuando agregue 1000 filas en la hoja de trabajo de Excel. Lo hago utilizando el método worksheetPart.Worksheet.Save(). Documantation dice convertía este método Save(): "guarda los datos en el árbol DOM de nuevo a la parte Podría ser llamado varias veces, así Cada vez que se llama, la corriente se vaciará.".

  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++; 

     } 

Este método funciona porque la tabla de uso de memoria tiene forma de sierra, pero desafortunadamente el uso de memoria crece a tiempo.

¿Alguien tiene alguna idea de cómo resolver este problema?

Respuesta

3

puede crear un libro de xlsx con 1.000.000 de filas por 40 columnas de números aleatorios (que es de 40 millones de células) en 74 segundos (que incluye la creación del libro en la memoria de números aleatorios y guardarlo en el disco en una overclockeado Intel QX 6850 y Windows Vista 32).

¿Qué tipo de rendimiento está viendo con Open XML SDK?

Puede descargar una versión de prueba gratuita de SpreadsheetGear here y pruébelo usted mismo.

Voy a pasar el código para generar el libro de trabajo de 40 millones de células a continuación.

exención de responsabilidad: Tengo 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

Gracias por su respuesta. Comprobaré si SpreadsheetGear me ayuda a resolver mi problema. Describo mi problema de rendimiento de Open XML SDK en esta publicación: http: //blog.goyello.com/2009/08/25/read-before-using-it-open-xml-sdk-performance-analysis/ –

+4

A la perfección pregunta redactada que aparece como primer resultado en Google. Visto 1200 veces. ¿Y la única respuesta es un enchufe lamentable para una biblioteca minorista de terceros? – mdisibio

+0

Especialmente porque es una biblioteca de terceros muy costosa. A $ 1000, spreadsheetgear es demasiado caro. – Wade73

0

Hay enfoque opuesto al "buffer y al ras" para la tarea de escribir grandes archivos de Excel. El enfoque se basa en el uso de la clase OpenXmlWriter y utiliza escritura secuencial en lugar de almacenamiento en búfer y descarga. Una solución típica también utiliza una pieza de repuesto y OpenXmlReader para obtener el contenido sin cambios de una plantilla. Mire "Writing Large Excel Files with the Open XML SDK" (con algunos ejemplos de código) y "Write large OpenXML docs" (con el ejemplo de código completo).

Cuestiones relacionadas