# POI große Exceldatei schreiben



## Rahmspinat (15. Okt 2010)

Hallo Leute,

ich schreibe mit POI eine relativ große Exceldatei.
Dabei gehe ich mit dem Scanner Zeile für Zeile eine andere Datei durch und schreibe immer 65000 Zeilen in ein Arbeitsblatt und erstelle dann das nächste. 

Zu erwarten sind 400432 Zeilen. (wenn ich nur den Scanner die lines rauslesen lasse läuft das programm durch)

Leider stockt die Funktion, so wie ich sie hier schreibe bei einer Zeile zwischen 240000 - 330000 --> also immer unterschiedlich (bei der gleichen Datei)

Hat einer eine Idee was ich machen kann?



```
public void writeExcelData(String tempFilePath) throws Exception{
		long time = System.currentTimeMillis();
		FileOutputStream out = new FileOutputStream("C:/workbook.xls");
		
		HSSFWorkbook wb = new HSSFWorkbook();
		Sheet s = wb.createSheet();
		int i = 0; 
		
		Scanner scanner = new Scanner(new File(tempFilePath));
		
		while(scanner.hasNextLine()) {
			if(i == 65000) {
				System.out.println("Sheet after " + (System.currentTimeMillis() - time));
				i = 0;
				s = wb.createSheet();
			}
			String line = scanner.nextLine();
			Row row = s.createRow(i);
			String[] splitLine = line.split("\t");
			for(int k = 0; k < splitLine.length; k++) {
				Cell cell = row.createCell(k);
				cell.setCellValue(splitLine[k]);
			} 
			splitLine = null;
			line = null;
			i++;
		}
		wb.write(out);
		out.close();
		System.out.println("Gesamter Vorgang " + (System.currentTimeMillis() - time));
	}
```


----------



## Geeeee (15. Okt 2010)

Mal ohne, dass ich mir vorstellen kann, wieviel Speicher die POI-Sachen bei solchen Größen fressen.

Stocken bedeutet??
Wenn: Wird langsam -> Dein Workbook wird im Speicher gehalten, d.h. es wird immer größer und somit drückt deine Anwendung auf den Speicher. Kann auch daran liegen, dass die "Anfügeoperation" bei großen Dateien einfach ewig dauert.
Hier könntest du z.B. ne riesige Exceldatei nehmen und mal versuchen "unten" was anzufügen. Den Vorgang mal mit dem Einfügen in eine leere Datei vergleichen. Ist zwar sehr ungenau, aber wenn man da einen Unterschied von (beispielhaft) 1 zu 10 Sekunden hat, kann man schon davon ausgehen, dass die Operation mit zunehmender Größe der Exceldatei / des Excelobjekts langsamer wird.
Wenn: Wirft ne Out of Memory Exception -> WB eindeutig zu groß


----------



## Rahmspinat (15. Okt 2010)

Stocken heißt, es hält komplett an. Also Vielleicht gehts ja irgendwann weiter aber eine zeile dauert, selbst wenn ich schon bei 200k Zeilen bin, wesentlich weniger als eine Sekunde.

Und auf einmal hält die Funktion komplett an. Das mein ich mit Stocken (war vielleicht falsch ausgedrückt) 

Out of Memory problem hab ich nicht, da ich den speicher auf 512mb hochgesetzt und damit war das problem gelöst.

Also an den dingen, die du genannt hast, kann es leider nicht liegen.

Ich habe einen weiteren Test gemacht. Unzwar habe ich immer ein neues Workbook erstellt, statt einem Sheet.
Also so:
Workbook0.xls
workbook1.xls
workbook2.xls
etc.
Da läuft die Funktion problemlos durch.

Ein weiterer test war gewesen, dass ich ein Workbook schreibe, ein Sheet einfüge, 65000 Zeilen hinzufüge und dann Abspeichere, dann neulade und das nächste Sheet anfüge und so weiter.
Leider stopt auch das irgendwann.


----------



## Geeeee (15. Okt 2010)

Rahmspinat hat gesagt.:


> Ein weiterer test war gewesen, dass ich ein Workbook schreibe, ein Sheet einfüge, 65000 Zeilen hinzufüge und dann Abspeichere, dann neulade und das nächste Sheet anfüge und so weiter.



Das wäre auch meine weitere Idee gewesen. Da er immer unterschiedlich aufhört, hab ich auch gerade keine Idee mehr (Korrupte Zeile in der Quelldatei, zuviel Daten im Sheet etc. kann man ja dadurch ausschließen).


----------



## Rahmspinat (15. Okt 2010)

Jop,

ach das ärgert mich. 

Da will man einen Prozess schön automatisieren, so dass der Benutzer nichtmal ne CSV aus der Excel machen und dann später alles wieder zusammenfrickeln muss und dann hakts an sonem Mist.

Die idee war ja Excel rein -> Blackbox -> Excel raus. Klappt bis auf Excel raus auch alles super 

Noch jemand eine Idee?


----------



## SlaterB (15. Okt 2010)

wieviel Speicher benötigst du denn von deinen 512 MB?
hier ein Testprogramm mit Speicherausgabe

```
public class TestExcel {
    public static void main(String[] args)     throws Exception   {
        FileOutputStream out = new FileOutputStream("C:/Temp/workbook.xls");

        HSSFWorkbook wb = new HSSFWorkbook();
        HSSFSheet s = wb.createSheet();

        long time = System.currentTimeMillis();
        long iTime = time;
        int max = 300003;
        Runtime r = Runtime.getRuntime();
        for (int i = 1; i < max; i++)
        {
            if (i % 20000 == 0)    {
                long newTime = System.currentTimeMillis();

                System.out.println("i: " + i + " - " + (newTime - iTime) + " - mem: " + 
                    (r.totalMemory() - r.freeMemory()) / 1000000);
                iTime = newTime;
                if (i % 60000 == 0)   {
                    System.out.println("new Sheet");
                    s = wb.createSheet();
                }
            }
            HSSFRow row = s.createRow(i);
            for (int k = 0; k < 10; k++)      {
                HSSFCell cell = row.createCell((short)k);
                cell.setCellValue("test");
            }
        }
        wb.write(out);
        out.close();

        long newTime = System.currentTimeMillis();
        System.out.println("Zeit fürs Schreiben: " + (newTime - iTime) + 
              " - mem: " + (r.totalMemory() - r.freeMemory()) / 1000000);
        System.out.println("Gesamter Vorgang " + (System.currentTimeMillis() - time));
    }
}
```
mit genügend Speicher ist die Ausgabe

```
i: 20000 - 1890 - mem: 44
i: 40000 - 2514 - mem: 88
i: 60000 - 2093 - mem: 133
new Sheet
i: 80000 - 1641 - mem: 177
i: 100000 - 2280 - mem: 221
i: 120000 - 1890 - mem: 267
new Sheet
i: 140000 - 1640 - mem: 307
i: 160000 - 1687 - mem: 354
i: 180000 - 2983 - mem: 397
new Sheet
i: 200000 - 1516 - mem: 444
i: 220000 - 1812 - mem: 482
i: 240000 - 1749 - mem: 530
new Sheet
i: 260000 - 1656 - mem: 569
i: 280000 - 3795 - mem: 616
i: 300000 - 2234 - mem: 659
new Sheet
Zeit fürs Schreiben: 3468 - mem: 761
Gesamter Vorgang 34848
```

mit nur 512 MB

```
i: 20000 - 1811 - mem: 44
i: 40000 - 2092 - mem: 88
i: 60000 - 1843 - mem: 132
new Sheet
i: 80000 - 2030 - mem: 177
i: 100000 - 1764 - mem: 219
i: 120000 - 2608 - mem: 263
new Sheet
i: 140000 - 1592 - mem: 308
i: 160000 - 1749 - mem: 352
i: 180000 - 1811 - mem: 396
new Sheet
i: 200000 - 2920 - mem: 440
i: 220000 - 1796 - mem: 481
i: 240000 - 4825 - mem: 525
new Sheet
[10 sec warten]
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
```


----------



## Rahmspinat (15. Okt 2010)

danke für den TestCode

Übrigens scheint da ein Fehler drin zu sein. Du musst die Zahl bei s.createRow(i);
am besten k nennen und dann immer wieder auf 0 setzen lassen, wenn ein neues Sheet erstellt wird, weil sonst sagt er dir ja, dass du außerhalb des gültigen bereichs bist.


Du wirst sicherlich früher ein OutOfMemory bekommen mit dem Code, weil ich nur 4 Cellen pro Row beschreibe(stand natürlich nicht da) und du gleich 10 stück. Bei mir reicht der Speicher, allerdings könnte ich ihn natürlich sicherheitshalber hochsetzen. Kann auch immer mal mehr werden die ganze Sache. Danke 


Aber jetzt zur neuen Erkenntnis:
Ich habe festgestellt, dass mein Rechner mehr Zeilen auswertet, wenn z.b. der Firefox zu ist.
Mein Rechner hat zwar noch 1,3 gb Arbeitsspeicher frei kommt aber damit irgendwie nicht klar hab ich dasgefühl.

Ich merk auch immer wenn das Programm läuft (auch wenn die CPU auslastung auf 0 ist) hat er probleme mit anderen Programmen.
Werd mir wohl erstmal nen größeren Arbeitsrechner geben lassen müssen  bzw den alten aufrüsten.


----------



## Rahmspinat (26. Okt 2010)

Hej Leute,

danke nochmal an SlaterB und Geeeee. Wie im letzten Post angenommen ist mein Rechner für die ganze Sache, trotz genügend arbeitsspeicher, einfach überlastet gewesen.

Ich habe das Programm fertig geschrieben und auf einen Server geladen. Es läuft einwandfrei. Brauch wohl mal ne bessere kiste 


Danke nochmal an euch


----------

