我想从 excel 文件中读取多张大于 10 mb 的数据

I want to read data from excel file with multiple sheets which is greater than 10 mb

我的代码适用于较小的 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());
    }
}

it leades to the following run time error. please help soon.

看起来你的 post 主要是代码;请添加更多详细信息。这很烦人,删除它。

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

您收到 out-of-memory 错误,因为 POI 会在内存中读取、解析和创建整个 Excel 文件的完整数据结构。这可能会占用大量内存。我看到您的程序从一个工作表中读取。这告诉我您可以将该工作表导出到 .csv(comma-separated 值)文件。这样就很容易读取数据了。

我对您的业务流程了解不多,无法确定可以在哪里导出 .csv,或者在您的流程中是否可以这样做。 POI 因使用大量内存而臭名昭著。

另一种解决方案是直接从 Excel 文件中读取。 .xlsx 文件实际上是一个 zip。您可以打开它并从那里读取数据。您将不得不查看 SpreadsheetML documentation to understand the format of the .xslx zip file, or use the Open XML SDK,它像 POI 一样会占用内存,但可能不会那么多。

试一试 SXSSFWorkbook。而不是 XSSFWorkbook(它将整个 Excel 工作簿保存在内存中)尝试使用非常高效和高性能的流式 SXSSFWorkbook class,如下所示:

SXSSFWorkbook workbook = new SXSSFWorkbook(100);

其中 100 是将保留在内存中并实时处理的默认行数,其他已处理的行将被刷新。