Я хочу прочитать данные из файла Excel с нескольких листов, который превышает 10 МБ - PullRequest
0 голосов
/ 06 июня 2019

Мой код отлично работает с меньшим файлом Excel, но он не работает с большим файлом Excel, он выдает ошибку OutOfMemory.

public void onReadClick (View view) {
    printlnToUser("reading XLSX file from resources");
    InputStream stream = getResources().openRawResource(R.raw.test3);
    try {
        XSSFWorkbook workbook = new XSSFWorkbook(stream);
        XSSFSheet sheet = workbook.getSheetAt(0);
        int rowsCount = sheet.getPhysicalNumberOfRows();
        FormulaEvaluator formulaEvaluator = workbook.getCreationHelper().createFormulaEvaluator();
        for (int r = 0; r<10; r++) {
            Row row = sheet.getRow(r);
            int cellsCount = row.getPhysicalNumberOfCells();
            for (int c = 0; c<cellsCount; c++) {
                String value = getCellAsString(row, c, formulaEvaluator);
                String cellInfo = "r:"+r+"; c:"+c+"; v:"+value;
                printlnToUser(cellInfo);
            }
        }
    } catch (Exception e) {
        /* proper exception handling to be here */
        printlnToUser(e.toString());
    }
}

приводит к следующей ошибке во время выполнения. пожалуйста, помогите в ближайшее время.

Похоже, ваш пост в основном кодовый; пожалуйста, добавьте еще некоторые детали. это раздражает удалить это.

2019-06-06 03:30:43.535 5224-5224/pro.kondratev.xlsxpoiexample E/AndroidRuntime: FATAL EXCEPTION: main
Process: pro.kondratev.xlsxpoiexample, PID: 5224
java.lang.IllegalStateException: Could not execute method for android:onClick
    at android.view.View$DeclaredOnClickListener.onClick(View.java:4707)
    at android.view.View.performClick(View.java:5619)
    at android.view.View$PerformClick.run(View.java:22298)
    at android.os.Handler.handleCallback(Handler.java:754)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:165)
    at android.app.ActivityThread.main(ActivityThread.java:6375)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:912)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:802)
 Caused by: java.lang.reflect.InvocationTargetException
    at java.lang.reflect.Method.invoke(Native Method)
    at android.view.View$DeclaredOnClickListener.onClick(View.java:4702)
    at android.view.View.performClick(View.java:5619) 
    at android.view.View$PerformClick.run(View.java:22298) 
    at android.os.Handler.handleCallback(Handler.java:754) 
    at android.os.Handler.dispatchMessage(Handler.java:95) 
    at android.os.Looper.loop(Looper.java:165) 
    at android.app.ActivityThread.main(ActivityThread.java:6375) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:912) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:802) 
 Caused by:java.lang.OutOfMemoryError: OutOfMemoryError thrown while trying to throw OutOfMemoryError; no stack trace available

1 Ответ

0 голосов
/ 06 июня 2019

Вы получаете ошибку нехватки памяти, потому что POI читает, анализирует и создает целую структуру данных для всего вашего файла Excel в памяти. Это может занять большое количество памяти. Я вижу, что ваша программа читает с одного листа. Это говорит мне, что вы можете экспортировать этот лист в файл .csv (значение, разделенное запятыми). Тогда было бы легко прочитать данные.

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

Другим решением будет чтение непосредственно из файла Excel. Файл .xlsx на самом деле является zip. Вы можете открыть его и прочитать ваши данные оттуда. Чтобы понять формат zip-файла .xslx, вам нужно обратиться к документации SpreadsheetML или использовать Open XML SDK , который, как и POI, будет использовать память, но, вероятно, не так много.

...