Попытка написать файл Excel с Apache POI, вызывающим OutOfMemoryError - PullRequest
0 голосов
/ 07 декабря 2011

У меня есть программа, которая пишет файл Excel.Он использует Apache POI для записи файлов Excel 2007 (у меня более 256 столбцов, поэтому я должен его использовать).Программа работает.Я проверил его на очень маленьких файлах, но если я использую больше строк, ему не хватает памяти.

Вот трассировка стека:

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
    at java.util.Arrays.copyOf(Unknown Source)
    at java.io.ByteArrayOutputStream.write(Unknown Source)
    at org.apache.poi.openxml4j.opc.internal.MemoryPackagePartOutputStream.write(MemoryPackagePartOutputStream.java:88)
    at org.apache.xmlbeans.impl.store.Cursor._save(Cursor.java:590)
    at org.apache.xmlbeans.impl.store.Cursor.save(Cursor.java:2544)
    at org.apache.xmlbeans.impl.values.XmlObjectBase.save(XmlObjectBase.java:212)
    at org.apache.poi.xssf.usermodel.XSSFSheet.write(XSSFSheet.java:2480)
    at org.apache.poi.xssf.usermodel.XSSFSheet.commit(XSSFSheet.java:2439)
    at org.apache.poi.POIXMLDocumentPart.onSave(POIXMLDocumentPart.java:196)
    at org.apache.poi.POIXMLDocumentPart.onSave(POIXMLDocumentPart.java:200)
    at org.apache.poi.POIXMLDocument.write(POIXMLDocument.java:204)
    at model.Conversione.traduzioneFile(Conversione.java:219)
    at model.Main.scriviFile(Main.java:75)
    at model.Main.main(Main.java:51)

Произошла ошибка (согласно трассировке стека)) в строке, где я пишу «workbook.write (fileOut)», где fileOut является FileOutputStream.Это означает, что, очевидно, достаточно памяти для ВСЕХ java-объектов для хранения файла excel, но по какой-то причине при записи на жесткий диск он должен занимать гораздо больше памяти.

Просто чтобы сказать вам,Я пытался увеличить размер кучи Java до 1 гигабайта (добавив -Xms128m -Xmx1024m), но, похоже, это не сработало.

Помогите!OO


ПРИМЕР КОДА:

..

import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

//I'M USING A DATABASE 
import DAO.EventoDAO;
import DAO.ParametroDAO;

public class Conversion {

public static void traduzioneFile(File read, File write){
    FileOutputStream fos=null;


    try {
        fos = new FileOutputStream(write);
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }
    if (fos!=null) {

        try{

            Workbook wb = new XSSFWorkbook() ;

            Sheet sheet = wb.createSheet();

            //I'm reading from a table in a .txt file , converting values, and putting them in a table..

            FileInputStream fis;
            try {
                fis = new FileInputStream(fileLettura);
                InputStreamReader isr=new InputStreamReader(fis);
                BufferedReader br=new BufferedReader(isr);
                String line=br.readLine();

                //here there are some variables
                while(line!=null) {

                    Row row = null;
                    row=sheet.createRow((short)row_number);


                                            //arrayLinea contains all the words of the line
                    while (column_number<arrayLinea.length){
                    value=arrayLinea[column_number];
 //if value is ok i translate it and put it in a cell
                       row.createCell((short)contatoreColonne).setCellValue(value);
                                    contatoreColonne++                                  

                        }
                        //next line
                        linea=br.readLine();
                        row_line++;

                }



        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }catch (Exception ex){
            ex.printStackTrace();

        }


        wb.write(fos);
        fos.flush();
        fos.close();

    }catch (FileNotFoundException e){
    }catch (IOException e){
    }catch (Exception e){

    }

}
}

Я надеюсь, что это читабельно ... однако я сканирую каждую строку, переводя значения столбца встолбец, помещая их в ячейки ... Эта часть в порядке ... Я проверил это с помощью systems.out.println ^^, но после последней строки, говорящей "перевод завершен, начинается запись", возникает ошибка ..

Ответы [ 3 ]

11 голосов
/ 21 декабря 2011

Запись файлов .xlsx с помощью POI занимает много памяти.1 гига наверное не достаточно для этого.

Недавно Apache POI представил новый API ( SXSSF ), который представляет собой потоковую реализацию, используемую для записи файлов .xlsx.Сам еще не использовал, но, возможно, это то, что вы можете посмотреть.

0 голосов
/ 27 января 2016

Попробуйте увеличить пространство кучи.

Если вы используете Eclipse, щелкните правой кнопкой мыши папку вашего проекта и выберите «Запуск от имени» -> «Выполнить настройку» -> вкладка «Аргументы».

На вкладке аргументов попробуйте установить эти параметры,

-Xms для установки начального размера кучи Java

-Xmx для установки максимального размера кучи Java

-Xss для установки размера стека Java-потока

Пример:

-Xms1024M -Xmx1524M

Затем запустите программу.

Надеюсь, это должно сработать.

Извините за столь поздний ответ: D

0 голосов
/ 07 декабря 2011

Вы должны поставить точку останова отладки и отследить ваши коды.

Где-то там, я полагаю, есть бесконечный цикл, который никогда не заканчивается и вызывает эту ошибку OOM.

...