2016-05-24 2 views
0

J'utilise iTextSharp pour créer des fichiers PDF. J'ai 100k dossiers, mais je reçois une exception près:Une exception de type 'System.OutOfMemoryException' s'est produite dans itextsharp.dll mais n'a pas été traitée dans le code utilisateur

Une exception de type « System.OutOfMemoryException » est produite dans itextsharp.dll mais n'a pas été traitée dans le code utilisateur à la ligne: bodyTable.AddCell (currentProperty .GetValue (lst, null) .ToString());

code est:

var doc = new Document(pageSize); 

PdfWriter.GetInstance(doc, stream); 
doc.Open(); 

//Get exportable count 
int columns = 0; 

Type currentType = list[0].GetType(); 

//PREPARE HEADER 
//foreach visible columns check if current object has proerpty 
//else search in inner properties 
foreach (var visibleColumn in visibleColumns) 
{ 
    if (currentType.GetProperties().FirstOrDefault(p => p.Name == visibleColumn.Key) != null) 
    { 
     columns++; 
    } 
    else 
    { 
     //check child property objects 
     var childProperties = currentType.GetProperties(); 
     foreach (var prop in childProperties) 
     { 
      if (prop.PropertyType.BaseType == typeof(BaseEntity)) 
      { 
       if (prop.PropertyType.GetProperties().FirstOrDefault(p => p.Name == visibleColumn.Key) != null) 
       { 
        columns++; 
        break; 
       } 
      } 
     } 
    } 
} 


//header 
var headerTable = new PdfPTable(columns); 
headerTable.WidthPercentage = 100f; 

foreach (var visibleColumn in visibleColumns) 
{ 
    if (currentType.GetProperties().FirstOrDefault(p => p.Name == visibleColumn.Key) != null) 
    { 
     //headerTable.AddCell(prop.Name); 
     headerTable.AddCell(visibleColumn.Value); 
    } 
    else 
    { 
     //check child property objects 
     var childProperties = currentType.GetProperties(); 
     foreach (var prop in childProperties) 
     { 
      if (prop.PropertyType.BaseType == typeof(BaseEntity)) 
      { 
       if (prop.PropertyType.GetProperties().FirstOrDefault(p => p.Name == visibleColumn.Key) != null) 
       { 
        //headerTable.AddCell(prop.Name); 
        headerTable.AddCell(visibleColumn.Value); 
        break; 
       } 
      } 
     } 
    } 
} 

doc.Add(headerTable); 

var bodyTable = new PdfPTable(columns); 
bodyTable.Complete = false; 
bodyTable.WidthPercentage = 100f; 

//PREPARE DATA 
foreach (var lst in list) 
{ 
    int col = 1; 
    foreach (var visibleColumn in visibleColumns) 
    { 
     var currentProperty = currentType.GetProperties().FirstOrDefault(p => p.Name == visibleColumn.Key); 
     if (currentProperty != null) 
     { 
      if (currentProperty.GetValue(lst, null) != null) 
       bodyTable.AddCell(currentProperty.GetValue(lst, null).ToString()); 
      else 
       bodyTable.AddCell(string.Empty); 

      col++; 
     } 
     else 
     { 
      //check child property objects 
      var childProperties = currentType.GetProperties().Where(p => p.PropertyType.BaseType == typeof(BaseEntity)); 
      foreach (var prop in childProperties) 
      { 
       currentProperty = prop.PropertyType.GetProperties().FirstOrDefault(p => p.Name == visibleColumn.Key); 
       if (currentProperty != null) 
       { 
        var currentPropertyObjectValue = prop.GetValue(lst, null); 
        if (currentPropertyObjectValue != null) 
        { 
         bodyTable.AddCell(currentProperty.GetValue(currentPropertyObjectValue, null).ToString()); 
        } 
        else 
        { 
         bodyTable.AddCell(string.Empty); 
        } 
        break; 
       } 
      } 
     } 
    } 
} 

doc.Add(bodyTable); 

doc.Close(); 
+0

Une trace de pile serait utile. En outre, quelle est la taille des données impliquées. Un lakh == 10000 droit? Mais quelle est la taille de chaque disque? Combien de mémoire le système a-t-il au total? C'est peut-être un cas réel de l'ordinateur à court de mémoire. –

+0

un lakh = 100000. Signifie 100000 lignes et 40 colonnes. Chaque cellule contient environ 20 caractères. Mon système a 8 Go de RAM. – Sachin

+0

Qu'est-ce qu'un lakh? Je n'ai jamais entendu ce mot auparavant. –

Répondre

1

A dos du calcul de l'enveloppe des besoins en mémoire compte tenu des données que vous avez fournies pour la consommation de mémoire donne 100000 * 40 * (2 * 20 + 4) = 167MBs. Bien dans votre limite de mémoire, mais c'est juste une limite inférieure. J'imagine que chaque objet Cell est assez gros. Si chaque cellule aurait un overhead de 512 octets, vous pourriez bien regarder 2GB prises. Je pense que ce pourrait être encore plus, car PDF est une bête complexe.

Ainsi, vous pourriez raisonnablement regarder une situation dans laquelle vous manquez réellement de mémoire. Si ce n'est pas vos ordinateurs, au moins le bit C# a mis de côté pour son propre truc.

Je ferais une chose en premier - vérifier la consommation de mémoire comme here. Vous pouvez même faire bien d'essayer avec 10, 100, 1000, 10000, 100000 lignes et voir jusqu'à quel nombre de lignes le programme fonctionne.

Vous pourriez peut-être essayer une toute autre chose. Si vous essayez d'imprimer une table bien formatée avec beaucoup de données, vous pourriez peut-être produire un document HTML, qui peut être fait de manière incrémentielle et que vous pouvez faire en écrivant simplement des choses dans un fichier plutôt que d'utiliser une bibliothèque tierce . Vous pouvez ensuite "imprimer" ce document HTML en PDF. StackOverflow à la rescue à nouveau avec ce problème.

+0

Ce n'est pas Java mais .NET, vous voudrez peut-être modifier votre réponse. –

+0

@AmedeeVanGasse oups, c'est une drôle d'erreur à faire. Merci de l'avoir signalé. J'ai changé les suggestions en C#. Comme avant, ce n'est pas une solution, mais plutôt quelques pistes d'investigation qui pourraient aider Sachin. –