2010-07-06 6 views
2

J'écris un fichier Excel à l'aide d'un POI Apache.JAVA - Apache POI OutOfMemoryError lors de l'écriture d'un fichier Excel

Je veux y écrire toutes les données de MyResultSet

qui a les noms des champs (colonnes) stockées dans la chaîne [] fieldnames.

J'ai 70000 lignes et 27 colonnes

Mon code:

String xlsFilename = "myXLSX.xlsx"; 
org.apache.poi.ss.usermodel.Workbook myWorkbook = new XSSFWorkbook(); 
org.apache.poi.ss.usermodel.Sheet mySheet = myWorkbook.createSheet("myXLSX"); 
Row currentRow = mySheet.createRow(0); 
for (int k = 0; k < fieldNames.length; k++) { 
    // Add Cells Of Title Of ResultsTable In Excel File 
    currentRow.createCell(k).setCellValue(fieldNames[k]); 
} 

for (int j = 0; j < countOfResultSetRows; j++) { 
    myResultSet.next(); 
    currentRow = mySheet.createRow(j + 1); 
    for (int k = 0; k < fieldNames.length; k++) { 
     currentRow.createCell(k).setCellValue(myResultSet.getString(fieldNames[k])); 
     System.out.println("Processing Row " + j); 
    } 
} 

FileOutputStream myFileOutputStream = new FileOutputStream(xlsFilename); 
myWorkbook.write(myFileOutputStream); 
myFileOutputStream.close(); 

Mon problème est que tout en écrivant les lignes du programme est plus en plus lent.

Quand il atteint la ligne 3500, il arrête avec l'exception:

Exception dans le thread "thread-3" java.lang.OutOfMemoryError. Java espace de tas à java.lang.AbstractStringBuilder (AbstractStringBuilder.java:45) à java.lang.StringBuffer. (StringBuffer.java:79)

Il semble que je manque de mémoire.

Comment puis-je résoudre ce problème.

Y at-il un moyen de stocker mes données dans un fichier temporaire toutes les 1000 d'entre eux (par exemple)?

Que suggéreriez-vous?

j'ai eu le même problème en utilisant JXL et ne jamais le résoudre soit (JAVA - Out Of Memory Error while writing Excel Cells in jxl)

Maintenant, je besoin de fichiers .xlsx de toute façon, donc je dois utiliser POI.

+0

Quel serveur d'applications utilisez-vous? –

Répondre

2

Il semble y avoir une approche qui crée d'abord un fichier de données au format XML, puis le remplace par un fichier xlsx de modèle existant.

http://svn.apache.org/repos/asf/poi/trunk/src/examples/src/org/apache/poi/xssf/usermodel/examples/BigGridDemo.java

ce n'est pas applicable pour les fichiers de format xls bien.

+1

Vous êtes beaucoup mieux d'utiliser le nouveau SXSSF plutôt que la Grande Démo Grille, comme le premier fait beaucoup plus de travail pour vous que le dernier – Gagravarr

+0

merci! Je vais essayer ça à la place! – ktsujister

+0

BigGridDemo est utile si vous souhaitez modifier une feuille de calcul existante. Plain SXSSF est un format en écriture seule (en commençant par un classeur vide ou un objet XSSFWorkbook ouvert.Le modèle basé sur les événements SAX est en lecture seule .Pour avoir une classe qui peut modifier un fichier existant sans charger le classeur entier en mémoire, vous devra utiliser des API de niveau inférieur pour écrire des fichiers XML et reconditionner le classeur. – IceArdor

1

Que diriez-vous permettant à votre application d'utiliser plus de mémoire (comme -Xmx500m pour 500 Mo)?

+0

déjà essayé, pas de changement. –

+0

Est-ce que CSV n'est pas une option? –

1

attribuer plus de mémoire sur le tas lors de l'exécution de votre programme:

$ java -Xms256m -Xmx1024m NameOfYourClass 
+0

déjà essayé, pas de changement. –

1

Je suis plus d'une fois.

Exécutez-vous cette exécution sur un serveur d'applications? Ce que j'ai fait par le passé, comme l'a mentionné Pablo, est d'augmenter l'espace de tas, mais assurez-vous qu'il est augmenté pour le serveur d'applications que vous utilisez.

J'ai également dû vraiment optimiser le code lors de cette opération.

Étant donné que vous générez un fichier .xlsx, XML prend un peu de mémoire. Je ne sais pas si cela fonctionnerait pour vous dans cette situation ou non, mais si vous pouvez créer un .xls normal le faire et que le convertir à la fin dans un fichier .xlsx (en utilisant bien sûr le point d'intérêt Apache).

Questions connexes