excel icon indicating copy to clipboard operation
excel copied to clipboard

Loading some excels with multiple sheets yields null check on null issue.

Open kuoaid opened this issue 1 year ago • 1 comments

Platform: iOS

Issue: On select files with multiple sheets, the package's code throws a null check on null error.

Steps to reproduce:

  1. Load the file (file_picker) like this, and initialize excel:
  Future<void> pickFile() async {
    bool _fileSuccess = await _fileUploadService.pickFile();
    if (_fileSuccess && _fileUploadService.pickedFile != null) {
      sheetsService = BatchSheetsService(
          car: car, pickedFile: _fileUploadService.pickedFile!);
      sheetsService?.initialize().whenComplete(() {
        matchingServices.initialize(sheetsService!.columns);
        notifyListeners();
      });
    } else {
      devLog("Error: No file was picked or the file pick failed.");
    }
  }
  ///initialize the service
  Future<void> initialize() async {
    await _loadExcelFile(pickedFile);
    fileLoaded = true;
  }

  Future<void> _loadExcelFile(PlatformFile file) async {
    // try {
    devLog("Loading Excel file: ${file.name}");
    var fileBytes = File(file.path!).readAsBytesSync();
    devLog("File bytes: ${fileBytes.length}");
    // If bytes are available, use them
      if (file.bytes != null) {
        devLog("File bytes available.");
      } else if (file.path != null) {
        devLog("File path available: ${file.path}");
        // If bytes are not available, read the file from the path
        File localFile = File(file.path!);
        devLog("Local file: $localFile");
        fileBytes = localFile.readAsBytesSync();
        devLog("File bytes: ${fileBytes.length}");
      } else {
        // If neither bytes nor path are available, throw an error
        throw Exception("No file content available to read.");
      }

      _excel = Excel.decodeBytes(fileBytes);
      devLog("Excel file decoded.");

      if (_excel == null) {
        print("Error: Excel file could not be decoded.");
        return;
      }

      if (_excel!.tables.isEmpty) {
        print("Error: No tables (sheets) found in the Excel file.");
        return;
      }

      selectedSheet = _excel!.tables.keys.first;
      _loadColumns();
      fileLoaded = true;
    // } catch (e) {
    //   print("Error loading Excel file: $e");
    // }
  }
  1. Load the file test_excel_file (test_excel_file.xlsx). It has 2 sheets. You will get:
[log] Loading Excel file: test_excel_file.xlsx
[log] File bytes: 5731
[log] File path available: /private/var/mobile/Containers/Data/Application/BBE734D1-BAB6-43DE-BCA6-D27E8C7F36E4/tmp/test_excel_file.xlsx
[log] Local file: File: '/private/var/mobile/Containers/Data/Application/BBE734D1-BAB6-43DE-BCA6-D27E8C7F36E4/tmp/test_excel_file.xlsx'
[log] File bytes: 5731
[log] Matches initialized: []
[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: Null check operator used on a null value
#0      Parser._parseTable (package:excel/src/parser/parse.dart:540:9)
#1      Parser._parseContent.<anonymous closure> (package:excel/src/parser/parse.dart:156:9)
#2      Iterable.forEach (dart:core/iterable.dart:347:35)
#3      Parser._parseContent (package:excel/src/parser/parse.dart:154:39)
#4      Parser._startParsing (package:excel/src/parser/parse.dart:15:5)
#5      new Excel._ (package:excel/src/excel.dart:63:12)
#6      _newExcel (package:excel/src/excel.dart:17:20)
#7      new Excel.decodeBytes (package:excel/src/excel.dart:78:12)
#8      BatchSheetsService._loadExcelFile (package:***********************batch_upload_sheets_service.dart:52:22)
#9      BatchSheetsService.initialize (package:***********************batch_upload_sheets_service.dart:28:11)
#10     BatchAddBackend.pickFile (package:***********************main_backend.dart:90:22)
<asynchronous suspension>
<asynchronous suspension>

This points to issues with these lines' null check:

    var file = _excel._archive.findFile('xl/$target');
    file!.decompress();
  1. However, loading test_excel_file_single (test_excel_file_single.xlsx), which has only one sheet, yields no issue. It still uses the paths to locate the file, as before. If file_picker is specified to include data, the uint8list is used but the overall behavior does not change.

  2. Loading this file - car_service_mods_worksheet 3.xlsx, which has 2 sheets, has no issues. It still uses paths. car_service_mods_worksheet 3.xlsx

Please respond with any insights! Thanks in advance.

kuoaid avatar Nov 06 '24 09:11 kuoaid