android读取大量数据的excel

在Android中读取xlsx文件,使用apache-poi读取文件的时候会内存溢出,查资料说是数据量大会导致内存溢出。使用easyExcel和monitorjbl每次都会出现一堆问题,网上查资料我都查不到,能帮助下或提供可用的demo吗

在 Android 中读取 Excel 文件并不是一件容易的事情,因为 Excel 文件通常很大,可能会导致内存溢出。Apache POI 库通常用于读写 Excel 文件,但是它在 Android 系统上的内存处理效率较低,易导致内存溢出。因此,我们可以选择使用其他库来读取 Excel 文件,比如 jExcelApi 和 ExcelReader 等。下面提供使用 jExcelApi 读取 Excel 文件的示例代码,供参考:

  1. 导入 jExcelApi 库
    将以下依赖添加到模块的 build.gradle 文件中:
    implementation 'net.sourceforge.jexcelapi:jxl:2.6.12'
  2. 读取 Excel 文件
    以下是读取 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);
                }
            }
        }
    }
}

引入批量读取和缓存列表的优化措施。每次读取一行数据时,将该行的数据存储在一个列表中,然后将该列表添加到整体的数据列表中。这样可以减少对内存的频繁操作,并减少了每个单元格的处理开销。