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-
- File picker chooses the correct file
- It is also converted in Uint8list format
- 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.