0

I am trying to create a project using file picker and excel packages in flutter that will allow us to pick a xlsx file and show the output in table format. I am facing main problem of-

  1. File picker chooses the correct file
  2. It is also converted in Uint8list format
  3. But after that the file data goes missing after _readExcel function and data is not shown in final output

Here is the flutter code-

import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
import 'package:syncfusion_flutter_datagrid/datagrid.dart';
import 'package:spreadsheet_decoder/spreadsheet_decoder.dart';


void main() => runApp(MyApp());



class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Excel Table Demo',
      home: HomePage(),
      debugShowCheckedModeBanner: false,
    );
  }
}




class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  List<Map<String, dynamic>> _data = [];
  bool _isLoading = false;

  Future<void> _readExcel(List<int> bytes) async{
    setState(() {
      _isLoading = false;
    });

    print(bytes.runtimeType);

    final excel = await SpreadsheetDecoder.decodeBytes(bytes.toList());
    final sheet = excel.tables['Sheet1'];
    if (sheet!=null) {
      final rows = sheet.rows;
      _data = rows

          .skip(1)
          .map((row) =>
      {
        'OrderDate': row[0]!.value,
        'Region': row[1]!.value,
        'Rep': row[2]!.value,
        'Item': row[3]!.value,
        'Units': row[4]!.value,
        'Unit Cost': row[5]!.value,
        'Total': row[6]!.value,
      })
          .toList();
    }
    print(_data);
    setState(() {
      _isLoading = true;
    });
  }


  Future<void> _uploadExcel() async {
    try {
      final pickedFile = await FilePicker.platform.pickFiles(
        type: FileType.custom,
        allowedExtensions: ['xlsx'],
      );
      print(pickedFile);
      if (pickedFile != null) {
        final bytes = pickedFile.files.first.bytes!;
        await _readExcel(bytes);
      }
    } catch (e) {
      print(e);
    }
  }



  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Excel Table Demo'),
      ),
      body: _isLoading ? Center(child: CircularProgressIndicator(),):
      _data.isEmpty
          ? Center(
        child: ElevatedButton(
          onPressed: _uploadExcel,
          child: Text('Upload Excel File'),
        ),
      )
          : SfDataGrid(
        source: _ExcelDataSource(_data),
        columnWidthMode: ColumnWidthMode.fill,
        columns: <GridColumn>[
          GridColumn(
              columnName: 'OrderDate',
              label: Container(
                padding: EdgeInsets.all(16.0),
                alignment: Alignment.centerLeft,
                child: Text('OrderDate'),
              )),
          GridColumn(
              columnName: 'Region',
              label: Container(
                padding: EdgeInsets.all(16.0),
                alignment: Alignment.centerLeft,
                child: Text('Region'),
              )),
          GridColumn(
              columnName: 'Rep',
              label: Container(
                padding: EdgeInsets.all(16.0),
                alignment: Alignment.centerLeft,
                child: Text('Rep'),
              )),
          GridColumn(
              columnName: 'Item',
              label: Container(
                padding: EdgeInsets.all(16.0),
                alignment: Alignment.centerLeft,
                child: Text('Item'),
              )),
          GridColumn(
              columnName: 'Units',
              label: Container(
                padding: EdgeInsets.all(16.0),
                alignment: Alignment.centerLeft,
                child: Text('Units'),
              )),
          GridColumn(
              columnName: 'Unit Cost',
              label: Container(
                padding: EdgeInsets.all(16.0),
                alignment: Alignment.centerLeft,
                child: Text('Unit Cost'),
              )),
          GridColumn(
              columnName: 'Total',
              label: Container(
                padding: EdgeInsets.all(16.0),
                alignment: Alignment.centerLeft,
                child: Text('Total'),
              )),
        ],
      ),
    );
  }
}






class _ExcelDataSource extends DataGridSource {
  _ExcelDataSource(this._data) {
    _buildDataGridRows();
  }

  final List<Map<String, dynamic>> _data;
  final List<DataGridRow> _rows = [];

  void _buildDataGridRows(){
    _data.forEach((row) => _rows.add(DataGridRow(cells: [
      DataGridCell<String>(columnName: 'OrderDate', value: row['OrderDate']),
      DataGridCell<String>(columnName: 'Region', value: row['Region']),
      DataGridCell<String>(columnName: 'Rep', value: row['Rep']),
      DataGridCell<String>(columnName: 'Item', value: row['Item']),
      DataGridCell<int>(columnName: 'Units', value: row['Units']),
      DataGridCell<double>(columnName: 'Unit Cost', value: row['Unit Cost']),
      DataGridCell<double>(columnName: 'Total', value: row['Total']),
    ])));
  }

  @override
  List<DataGridRow> get rows => _rows;

  @override
  DataGridRowAdapter buildRow(DataGridRow row) {
    return DataGridRowAdapter(
      cells: row.getCells().map<Widget>((cell) {
        return Container(
          padding: EdgeInsets.all(8.0),
          alignment: Alignment.centerLeft,
          child: Text(cell.value.toString()),
        );
      }).toList(),
    );
  }

}

This is the output i get after inserting a file- output image

Can anybody help me with this problem.

isherwood
  • 58,414
  • 16
  • 114
  • 157

0 Answers0