我的代码在较小的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
答案 0 :(得分:0)
由于POI会为内存中的整个Excel文件读取,解析并创建整个数据结构,因此会出现内存不足错误。这会占用大量内存。我看到您的程序从单个工作表中读取。这告诉我您可以将该工作表导出到.csv(逗号分隔值)文件。这样就很容易读取数据。
我对您的业务流程了解不多,无法确定可以导出到.csv的位置,或者在您的流程中是否有可能。 POI因使用大量内存而臭名昭著。
另一种解决方案是直接从Excel文件中读取。 .xlsx文件实际上是一个zip。您可以打开它并从那里读取数据。您可能需要查看SpreadsheetML文档来了解.xslx zip文件的格式,或者使用Open XML SDK,就像POI会使用内存,但可能不会使用太多。
答案 1 :(得分:0)
给SXSSFWorkbook一枪。尝试使用非常高效和高性能的流式SXSSFWorkbook类,而不是XSSFWorkbook(将整个Excel工作簿保留在内存中),如下所示:
SXSSFWorkbook workbook = new SXSSFWorkbook(100);
其中100是将保留在内存中并实时处理的默认行数,其他已处理的行将被刷新。