在Android中读取xlsx文件,使用apache-poi读取文件的时候会内存溢出,查资料说是数据量大会导致内存溢出。使用easyExcel和monitorjbl每次都会出现一堆问题,网上查资料我都查不到,能帮助下或提供可用的demo吗
在 Android 中读取 Excel 文件并不是一件容易的事情,因为 Excel 文件通常很大,可能会导致内存溢出。Apache POI 库通常用于读写 Excel 文件,但是它在 Android 系统上的内存处理效率较低,易导致内存溢出。因此,我们可以选择使用其他库来读取 Excel 文件,比如 jExcelApi 和 ExcelReader 等。下面提供使用 jExcelApi 读取 Excel 文件的示例代码,供参考:
public class ReadExcelActivity extends AppCompatActivity {
private Button btnReadExcel;
private TextView tvShowExcelData;
private Workbook workbook;
private Sheet sheet;
private int rows;
private int columns;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_read_excel);
btnReadExcel = findViewById(R.id.btn_read_excel);
tvShowExcelData = findViewById(R.id.tv_show_excel_data);
btnReadExcel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
readExcel();
}
});
}
private void readExcel() {
try {
InputStream inputStream = getAssets().open("test.xls");
workbook = Workbook.getWorkbook(inputStream);
sheet = workbook.getSheet(0);
rows = sheet.getRows();
columns = sheet.getColumns();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < rows; i++) {
for (int j = 0; j < columns; j++) {
Cell cell = sheet.getCell(j, i);
sb.append(cell.getContents()).append("\t");
}
sb.append("\n");
}
tvShowExcelData.setText(sb.toString());
} catch (IOException e) {
e.printStackTrace();
} catch (BiffException e) {
e.printStackTrace();
} finally {
workbook.close();
}
}
}
上述代码读取 Excel 文件 test.xls
,并将其显示在 TextView 中。这段代码使用了 jExcelApi 库,这个库的运行效率比 Apache POI 库要高,可以有效避免内存溢出的问题。
希望上述代码可以帮助你解决问题,如果仍然有问题或其他疑问,请随时提出。
import android.os.AsyncTask;
import android.util.Log;
import org.apache.poi.ss.usermodel.Cell;
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.ss.usermodel.WorkbookFactory;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
public class ExcelReaderTask extends AsyncTask<InputStream, Void, List<List<String>>> {
private static final String TAG = "ExcelReaderTask";
@Override
protected List<List<String>> doInBackground(InputStream... params) {
try {
InputStream inputStream = params[0];
// 打开Excel文件
Workbook workbook = WorkbookFactory.create(inputStream);
// 选择第一个工作表
Sheet sheet = workbook.getSheetAt(0);
int rows = sheet.getPhysicalNumberOfRows();
int columns = 0;
// 优化措施:使用批量读取和缓存列表
List<List<String>> data = new ArrayList<>();
// 逐行读取数据
for (int row = 0; row < rows; row++) {
Row sheetRow = sheet.getRow(row);
if (sheetRow != null) {
int currentColumns = sheetRow.getPhysicalNumberOfCells();
if (currentColumns > columns) {
columns = currentColumns;
}
List<String> rowData = new ArrayList<>();
for (int column = 0; column < columns; column++) {
Cell cell = sheetRow.getCell(column);
if (cell != null) {
String content = cell.toString();
// 在此处处理读取到的数据
rowData.add(content);
} else {
rowData.add(""); // 空单元格处理
}
}
data.add(rowData);
}
}
// 关闭Excel文件
workbook.close();
return data;
} catch (Exception e) {
Log.e(TAG, "Error reading Excel file: " + e.getMessage());
}
return null;
}
@Override
protected void onPostExecute(List<List<String>> data) {
// 在此处处理读取到的数据
if (data != null) {
for (List<String> row : data) {
for (String cellData : row) {
Log.d(TAG, "Cell: " + cellData);
}
}
}
}
}
引入批量读取和缓存列表的优化措施。每次读取一行数据时,将该行的数据存储在一个列表中,然后将该列表添加到整体的数据列表中。这样可以减少对内存的频繁操作,并减少了每个单元格的处理开销。