import 'dart:typed_data'; import 'package:flutter/material.dart'; import 'package:jwt_decode/jwt_decode.dart'; import 'package:nhancepolicy/customAppBar/customAppBar.dart'; import 'dart:convert'; import 'dart:async'; import 'package:http/http.dart' as http; import 'package:nhancepolicy/customAppBar/toastHelper.dart'; import 'package:nhancepolicy/models/environment.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:universal_html/html.dart' as html; import 'package:flutter/foundation.dart' show kIsWeb; import 'package:excel/excel.dart'; import 'dart:io'; import 'package:intl/intl.dart'; import 'package:csv/csv.dart'; import 'package:spreadsheet_decoder/spreadsheet_decoder.dart'; class excelVerify extends StatefulWidget { const excelVerify({Key? key}) : super(key: key); @override State createState() => _excelVerifyState(); } class _excelVerifyState extends State { Uint8List? fileBytes; Uint8List? fileBytes2; late String _token; dynamic getPolicyNo; bool _isLoading = false; dynamic getPolicyNameDetails; dynamic clintID; String? fileName; int _currentStep = 0; // Step index tracker List dataPolicy = []; dynamic validationArray = []; dynamic missingColumnErrorMsg = 0; dynamic columnIndexMismatchCount = 0; dynamic columnMissingCount = 0; List> extractedData = []; dynamic argumentsData; List> originalData = []; // Original data source List> filteredData = []; // Filtered data source dynamic policy_name; dynamic clientPolicyId; dynamic clientId; dynamic policyType; List> nonExcelFilteredData = []; dynamic invalidRelationships = 0; dynamic dobAgeCheckCount = 0; dynamic empRefId; @override void initState() { super.initState(); _loadToken(); } @override void dispose() { super.dispose(); html.window.localStorage.remove('fileBytes'); } Future _loadToken() async { final SharedPreferences prefs = await SharedPreferences.getInstance(); final token = prefs.getString('hrtoken'); if (token != null && token.isNotEmpty) { setState(() { _token = token; }); Map? decodedToken = Jwt.parseJwt(token); clintID = decodedToken['client_id'].toString(); empRefId = prefs.getString('empRefId'); await getPolicyDetails(); } else { // Token is empty or null, handle accordingly (e.g., navigate to login screen) // For now, let's navigate to the login screen ToastHelper.showErrorToast(context, 'Session Out'); Navigator.pushReplacementNamed(context, 'hrLogin'); } } Future getPolicyDetails() async { setState(() { clientPolicyId = argumentsData['client_policy_id']; clientId = argumentsData['client_id']; policyType = argumentsData['type']; policy_name = argumentsData['policy_name']; }); } // Future _uploadFile1(importPolicyName) async { // FilePickerResult? result = await FilePicker.platform.pickFiles( // type: FileType.custom, // allowedExtensions: ['xlsx', 'xls', 'csv'], // ); // // if (result != null) { // PlatformFile file = result.files.first; // Uint8List fileBytes = file.bytes!; // // Use the fileBytes as needed // print('File name: ${file.name}'); // print('File size: ${file.size}'); // print('File bytes: $fileBytes'); // _processExcelData(fileBytes); // } else { // // User canceled the picker // } // } void _uploadFile(importPolicyName) async { print('Test'); if (kIsWeb) { print('kIsWeb'); final input = html.FileUploadInputElement(); input.accept = '.xlsx,.xls,.csv'; input.click(); input.onChange.listen((event) async { final file = input.files!.first; final reader = html.FileReader(); reader.readAsArrayBuffer(file); await reader.onLoadEnd.first; // Wait for the file to be loaded if (reader.readyState == html.FileReader.DONE) { Uint8List? fileBytes = reader.result as Uint8List?; if (fileBytes != null) { setState(() { fileName = file.name; }); // Save fileBytes to local storage final jsonString = json.encode(fileBytes); html.window.localStorage['fileBytes'] = jsonString; print('File Name: $fileName'); print('File Bytes: $fileBytes'); // Call the function to process Excel data here _processExcelData(fileBytes, fileName); } } }); } else { // Handle non-web platforms here (e.g., show an error message) print('File upload is only supported on web platforms.'); } } void _processExcelData(Uint8List fileBytes, fileName) { List> dataArray; if (fileName.endsWith('.xlsx')) { dataArray = decodeExcelData(fileBytes); } else if (fileName.endsWith('.xls')) { dataArray = decodeXLSData(fileBytes); } else if (fileName.endsWith('.csv')) { print('csv'); dataArray = decodeCSVData(fileBytes); } else { throw UnsupportedError('Unsupported file format: $fileName'); } print('_processExcelData'); // Decode the Excel file and extract relevant data // Assuming dataArray is your array containing Excel data // List> dataArray = decodeExcelData(fileBytes); print(dataArray); // print(dataArray[0].toString()); // Extract Name, Age, and City from the array print(dataArray[0].length); if (dataArray[0].length == 11) { for (int i = 0; i < dataArray.length; i++) { Map dataMap = { "Sno": dataArray[i][0].value, "Emp_Code": dataArray[i][1].value, "Name": dataArray[i][2].value, "DOJ": dataArray[i][3].value, "Gender": dataArray[i][4].value, "Relation": dataArray[i][5].value, "DOB": dataArray[i][6].value, "Mail": dataArray[i][7].value, "Mobile": dataArray[i][8].value, "SI": dataArray[i][9].value, "Grade": dataArray[i][10].value, }; if (i == 0) { // print(dataMap); validationArray.add(dataMap); } else { // print(dataMap); extractedData.add(dataMap); } } // Do something with extracted data (e.g., display in UI) originalData = extractedData; filteredData = List.from(originalData); print('filteredData'); print(filteredData); print(validationArray); validationArray[0].forEach((key, value) { print(key); print(value); if (key.toString().trim().toLowerCase() != value.toString().trim().toLowerCase()) { // If key and value are not equal, increment mismatch count columnIndexMismatchCount++; print('columnIndexMismatchCount: $value'); } if (value.toString() == 'null') { // If value is null, increment missing count columnMissingCount++; print('Value: $value'); } }); print('columnIndexMismatchCount: $columnIndexMismatchCount'); print('columnMissingCount: $columnMissingCount'); nonExcelFilteredData = filteredData.where((item) { final relation = item['Relation']; return relation != null && relation.toString().trim().toLowerCase() != 'self'; }).toList(); print('nonExcelFilteredData'); print(nonExcelFilteredData); print(nonExcelFilteredData.length); if (argumentsData['type'] == 'GPA') { if (nonExcelFilteredData.length > 0) { print('nonSelf'); invalidRelationships = nonExcelFilteredData.length; } else { print('Self'); invalidRelationships = nonExcelFilteredData.length; } print('invalidRelationships: $invalidRelationships'); } else { invalidRelationships = 0; } int invalidDobCount = countInvalidDobs(filteredData); print('Number of invalid DOBs: $invalidDobCount'); dobAgeCheckCount = invalidDobCount; } else { print('Some Column is Missing'); var columnMissingCount = 11 - dataArray[0].length; missingColumnErrorMsg = columnMissingCount; print(missingColumnErrorMsg); } } // bool checkAllSelf(List> dataList) { // // Check if any value of 'Relation' key is not 'Self' // bool allSelf = dataList.every((data) => data['Relation'] == 'Self'); // // If all values are 'Self', return true; otherwise, return false // return allSelf; // } // Placeholder function for decoding Excel data List> decodeExcelData(Uint8List fileBytes) { print('decodeExcelData'); // Create an Excel instance from the fileBytes final excel = Excel.decodeBytes(fileBytes); print('decodeExcelData'); print(excel); // Assuming there's only one sheet in the Excel file final sheet = excel.tables.keys.first; final table = excel.tables[sheet]!; // Convert Excel table to a List> // Convert Excel table to a List> List> dataArray = []; for (int rowIdx = 0; rowIdx < table.rows.length; rowIdx++) { List rowData = []; for (int colIdx = 0; colIdx < table.rows[rowIdx].length; colIdx++) { var value = table.rows[rowIdx][colIdx]?.value; rowData.add(Data(value, rowIdx, colIdx, sheet)); } dataArray.add(rowData); } return dataArray; } List> decodeXLSData(Uint8List fileBytes) { final Excel excelData = Excel.decodeBytes(fileBytes); final sheet = excelData.tables.keys.first; final table = excelData.tables[sheet]!; List> dataArray = []; for (int rowIdx = 0; rowIdx < table.rows.length; rowIdx++) { List rowData = []; for (int colIdx = 0; colIdx < table.rows[rowIdx].length; colIdx++) { var value = table.rows[rowIdx][colIdx]?.value; rowData.add(Data(value, rowIdx, colIdx, sheet)); } dataArray.add(rowData); } return dataArray; } List> decodeCSVData(Uint8List fileBytes) { String csvString = utf8.decode(fileBytes); List> csvData = const CsvToListConverter().convert(csvString); List> dataArray = []; // Skip the header row (if it exists) and start from index 1 for (int i = 1; i < csvData.length; i++) { List rowData = []; for (int j = 0; j < csvData[i].length; j++) { // Assuming the CSV data is of type String rowData.add(Data(csvData[i][j].toString(), i, j, 'Sheet1')); } dataArray.add(rowData); } return dataArray; } int countInvalidDobs(List> data) { int invalidCount = 0; for (var entry in data) { DateTime dob; // if (entry['DOB'] is String) { dob = DateTime.parse(entry['DOB'].toString()); // } else if (entry['DOB'] is DateTime) { // dob = entry['DOB']; // } else { // // Invalid DOB format, skip this entry // continue; // } print(entry['Relation']); if ((entry['Relation'].toString() == 'Son' || entry['Relation'].toString() == 'Daughter')) { if (DateTime.now().difference(dob).inDays > 25 * 365) { print('child $dob'); invalidCount++; } } else if ((entry['Relation'] != 'Son' && entry['Relation'] != 'Daughter')) { if (DateTime.now().difference(dob).inDays < 18 * 365) { print('others $dob'); invalidCount++; } } } return invalidCount; } void _dragAndDropFile(html.File file) async { print('file'); print(file); // Prepare form data final formData = html.FormData(); formData.appendBlob('file', file); // Send formData to API endpoint final response = await html.HttpRequest.request( 'your_api_endpoint_here', method: 'POST', sendData: formData, ); // Handle response as needed print(response.responseText); } void _retrieveAndUploadFile() { final jsonString = html.window.localStorage['fileBytes']; if (jsonString != null) { final decodedBytes = json.decode(jsonString); if (decodedBytes is List) { setState(() { fileName = fileName ?? 'Retrieved File'; // Provide a default name if fileName is null }); sendExcelFIleTOAPI( Uint8List.fromList(decodedBytes.cast()), fileName!, ); } } } Future sendExcelFIleTOAPI(Uint8List fileBytes, String fileName) async { print('submit'); print(fileBytes); if (fileBytes == null) { print('return'); return; // No file selected } else { print('else'); // // Prepare form data // final formData = html.FormData(); // formData.appendBlob('file', html.Blob([fileBytes]), fileName); // URL of the API where you want to send the file final apiUrl = Environment.apiUrl + 'employeeUpload'; print('else'); // Create a multipart request final request = http.MultipartRequest('POST', Uri.parse(apiUrl)); print('else'); // Attach the file to the request // Set authorization token in headers request.headers['Authorization'] = 'Bearer $_token'; // request.files.add(http.MultipartFile.fromBytes('file', fileBytes, // filename: fileName)); print('Filename: $fileName'); request.files.add(http.MultipartFile.fromBytes( 'file', fileBytes, filename: fileName ?? 'default_filename.xlsx', )); print('clintID: $clintID'); request.fields['client_id'] = clintID; print('clientPolicyId: $clientPolicyId'); // if (policyFirstPart == 'GPA') { request.fields['policy_id'] = clientPolicyId; request.fields['client_branch_id'] = empRefId; // } else { // request.fields['policy_id'] = '3'; // } print('request : $request'); // Send the request final response = await request.send(); print('else'); // Read response stream as a string final responseString = await response.stream.bytesToString(); print('else'); // Check the status code of the response if (response.statusCode == 200) { Map data = json.decode(responseString); if (data['status'] == 'success') { html.window.localStorage.remove('fileBytes'); // ToastHelper.showSuccessToast(context, 'File uploaded successfully'); ToastHelper.showSuccessToast( context, 'Data Successfully Imported...'); print('Data Successfully Imported'); Navigator.pushNamed(context, 'hrPolicyDetails', arguments: argumentsData); } else { // ToastHelper.showSuccessToast(context, 'File uploaded successfully'); ToastHelper.showErrorToast(context, 'Failed to Imported...'); // Navigator.pushNamed(context, 'hrHome'); } } else { // ToastHelper.showSuccessToast( // context, 'Failed to upload file: ${response.reasonPhrase}'); ToastHelper.showSuccessToast(context, 'Something went wrong'); print('Failed to upload file: ${response.reasonPhrase}'); } } } void search(String query) { setState(() { if (query.isEmpty) { // If search query is empty, show all data filteredData = List.from(originalData); } else { // Filter the data based on the search query filteredData = originalData.where((item) { // Implement your filter logic here, for example: return item['Emp_Code'].toLowerCase().contains(query.toLowerCase()); }).toList(); } }); } downloadSampleFile() { final anchor = html.AnchorElement(href: 'assets/assets/Template_File.xlsx'); anchor.download = 'Template_File.xlsx'; // Set the filename anchor.click(); // Trigger a click on the anchor element } resetErrorCount() { setState(() { fileBytes = null; fileName = null; _currentStep = 0; extractedData = []; originalData = []; filteredData = []; validationArray = []; nonExcelFilteredData = []; print('filteredData'); print(filteredData); print(validationArray); missingColumnErrorMsg = 0; print(missingColumnErrorMsg); columnMissingCount = 0; print(columnMissingCount); columnIndexMismatchCount = 0; print(columnIndexMismatchCount); invalidRelationships = 0; dobAgeCheckCount = 0; html.window.localStorage.remove('fileBytes'); }); } @override Widget build(BuildContext context) { dynamic arguments = ModalRoute.of(context)!.settings.arguments; print('arguments'); print(arguments); if (arguments != null && arguments is Map) { argumentsData = arguments; } return Scaffold( appBar: CustomAppBar(), body: SafeArea( child: Theme( data: ThemeData( canvasColor: Color(0xFFF4F7FE), colorScheme: Theme.of(context).colorScheme.copyWith( primary: Color(0xFFE26728), background: Colors.red, secondary: Color(0xFFE26728), ), ), child: Container( padding: const EdgeInsets.all(20), color: Color(0xFFEFF3F6), child: Card( elevation: 0, child: Column( children: [ Expanded( child: Stepper( type: StepperType.horizontal, currentStep: _currentStep, controlsBuilder: (BuildContext context, ControlsDetails controls) { return Container( alignment: Alignment.bottomCenter, padding: const EdgeInsets.all(16.0), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ ElevatedButton( onPressed: () { html.window.localStorage.remove('fileBytes'); fileBytes = null; fileName = null; _currentStep = 0; missingColumnErrorMsg = 0; columnIndexMismatchCount = 0; columnMissingCount = 0; invalidRelationships = 0; dobAgeCheckCount = 0; nonExcelFilteredData = []; Navigator.pushNamed( context, 'hrPolicyDetails', arguments: argumentsData); }, child: Text( 'Close', style: TextStyle(color: Color(0xFFE26728)), ), style: ElevatedButton.styleFrom( backgroundColor: Colors.white, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(5), side: BorderSide(color: Color(0xFFE26728)), ), ), ), // SizedBox(width: 10), // if (fileName != null) // ElevatedButton( // onPressed: () { // // Reset localStorage and fileBytes // setState(() { // html.window.localStorage // .remove('fileBytes'); // fileBytes = null; // fileName = null; // _currentStep = 0; // }); // }, // child: Text( // 'Reselect File', // style: TextStyle(color: Color(0xFFE26728)), // ), // style: ElevatedButton.styleFrom( // backgroundColor: Colors.white, // shape: RoundedRectangleBorder( // borderRadius: BorderRadius.circular(5), // side: // BorderSide(color: Color(0xFFE26728)), // ), // ), // ), Spacer(), SizedBox( width: 10), // This pushes the buttons to the right if (_currentStep != 0) ElevatedButton( onPressed: () { controls.onStepCancel!(); }, child: Text( 'Previous', style: TextStyle(color: Color(0xFFE26728)), ), style: ElevatedButton.styleFrom( backgroundColor: Colors.white, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(5), side: BorderSide(color: Color(0xFFE26728)), ), ), ), SizedBox(width: 10), if (_currentStep != 2) ElevatedButton( onPressed: _currentStep == 0 ? (fileName != null ? controls.onStepContinue! : null) : (_currentStep == 1 ? (missingColumnErrorMsg == 0 && columnIndexMismatchCount == 0 && invalidRelationships == 0 && dobAgeCheckCount == 0 ? controls.onStepContinue! : null) : null), child: const Text( 'NEXT', style: TextStyle(color: Colors.white), ), style: ElevatedButton.styleFrom( backgroundColor: Color(0xFFE26728), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(5), ), ), ), SizedBox(width: 10), if (_currentStep == 2) ElevatedButton( onPressed: () { _retrieveAndUploadFile(); }, child: Text( 'Submit', style: TextStyle(color: Colors.white), ), style: ElevatedButton.styleFrom( backgroundColor: Color(0xFFE26728), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(5), ), ), ), ], ), ); }, onStepContinue: _currentStep == 2 ? null : () { if (_currentStep == 0) { // For the first step, allow continue if fileName is not null if (fileName != null) { setState(() { _currentStep += 1; }); } } else if (_currentStep == 1) { // For the second step, allow continue if both errors are 0 if (missingColumnErrorMsg == 0 && columnIndexMismatchCount == 0 && invalidRelationships == 0 && dobAgeCheckCount == 0) { setState(() { _currentStep += 1; }); } } // setState(() { // // Increment the current step when the user clicks continue // if (_currentStep < 2) { // _currentStep += 1; // } // }); }, onStepCancel: () { setState(() { // Decrement the current step when the user clicks cancel if (_currentStep > 0) { _currentStep -= 1; } }); }, steps: [ Step( title: Container( child: Text( 'Import Excel', style: TextStyle( color: Color(0xFFE26728), ), ), ), content: Container( child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Expanded( flex: 12, child: Column( children: [ Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Expanded( child: Text( '$policy_name - ($policyType)', textAlign: TextAlign.center, style: TextStyle( fontSize: 20, fontWeight: FontWeight .w600, // Adjust the font size as needed color: Color( 0xFF181818), // Adjust the text color as needed ), ), ) ], ), SizedBox(height: 20), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Expanded( child: Container( margin: EdgeInsets.symmetric( horizontal: 150), alignment: Alignment.center, color: Colors.grey[200], height: 250, // Adjust height as needed child: DragTarget( onAccept: (html.File droppedFile) { setState(() { fileName = droppedFile.name; }); _dragAndDropFile(droppedFile); }, builder: (BuildContext context, List candidateData, List rejectedData) { return Container( alignment: Alignment.center, child: Column( mainAxisAlignment: MainAxisAlignment .center, children: [ // if (fileName == null) // ElevatedButton( // onPressed: () => {}, // child: Icon( // Icons.download, // color: Colors // .grey), // You can replace the Icon with your custom button child // style: // ElevatedButton // .styleFrom( // shape: // CircleBorder(), // Makes the button round // padding: // EdgeInsets.all( // 18), // Change the button color as needed // ), // ), // SizedBox(height: 20), // if (fileName == null) // Text( // 'Drag and drop file to import', // style: TextStyle( // fontSize: 16, // fontWeight: // FontWeight // .w600), // ), // Add spacing between texts // SizedBox(height: 20), fileName != null ? Column( mainAxisAlignment: MainAxisAlignment .center, children: [ Icon( Icons .upload_file, // Choose the appropriate icon size: 35, color: Color( 0xFFE26728), // Adjust the size as needed ), SizedBox( height: 15), // Add some space between the icon and text Text( '$fileName', style: TextStyle( fontSize: 16), ), SizedBox( height: 25), // Add some space between the icon and text MouseRegion( cursor: SystemMouseCursors .click, // Set cursor to pointer on hover child: GestureDetector( onTap: () { resetErrorCount(); }, child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon( Icons.delete_forever, // Choose the remove icon size: 20, // Adjust the size as needed color: Colors.red, // Set the color of the remove icon ), SizedBox( width: 1), // Add some space between the icon and text Text( 'Remove', style: TextStyle(fontSize: 13, color: Color(0xFF727272)), ), ], ), ), ) ], ) : ElevatedButton( onPressed: () => _uploadFile( 'Policy Name'), child: Text( 'Select File', style: TextStyle( color: Colors .white), ), style: ElevatedButton .styleFrom( backgroundColor: Color( 0xFFE26728), ), ), SizedBox(height: 20), if (fileName == null) Text( 'Supported Files : XLSX') // Add more Text widgets for additional lines of text ], ), ); }, ), ), ), ], ), Row( mainAxisAlignment: MainAxisAlignment.start, children: [ Expanded( child: Column( mainAxisAlignment: MainAxisAlignment.start, children: [ Text( 'Ensure that the import file is in the correct format by comparing it with our template file.', textAlign: TextAlign.center, style: TextStyle( fontSize: 16, fontWeight: FontWeight.w400, )), MouseRegion( cursor: SystemMouseCursors.click, child: GestureDetector( onTap: () { downloadSampleFile(); }, child: Text( 'Template File', style: TextStyle( fontSize: 15, color: Color( 0xFFE26728), // Add underline decoration ), ), ), ) ])) ], ) ], ), ), ], ), ), isActive: _currentStep == 0, ), Step( title: Text( 'Excel Validation', style: TextStyle(color: Color(0xFFE26728)), ), content: Padding( padding: EdgeInsets.only( top: 30, bottom: 30, left: 300, right: 300), // Adjust the horizontal padding as needed child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ _buildRowWithIcon( missingColumnErrorMsg == 0 ? Icons.check_circle : Icons.error, 'No of column missing : $missingColumnErrorMsg Column', iconColor: missingColumnErrorMsg == 0 ? Colors.green : Colors .red, // Set color based on condition ), if (missingColumnErrorMsg == 0) _buildRowWithIcon( columnIndexMismatchCount == 0 ? Icons.check_circle : Icons.error, 'Mismatch in Column Order : $columnIndexMismatchCount - Column', iconColor: columnIndexMismatchCount == 0 ? Colors.green : Colors.red, ), _buildRowWithIcon( invalidRelationships == 0 ? Icons.check_circle : Icons.error, 'Invalid Relationships : $invalidRelationships - Rows', iconColor: invalidRelationships == 0 ? Colors.green : Colors.red, ), _buildRowWithIcon( dobAgeCheckCount == 0 ? Icons.check_circle : Icons.error, 'Age Config - $dobAgeCheckCount - Rows', iconColor: dobAgeCheckCount == 0 ? Colors.green : Colors.red, ), ], ), ), isActive: _currentStep == 1, ), Step( title: Text( 'Preview', style: TextStyle(color: Color(0xFFE26728)), ), content: Column( children: [ Row( children: [ Expanded( flex: 10, child: Container( alignment: Alignment.centerLeft, child: Container( width: 350, // Set your desired width here height: 40, // Set your desired height here decoration: BoxDecoration( boxShadow: [ BoxShadow( color: Color.fromRGBO( 255, 255, 255, 0.5), // Shadow color with opacity offset: Offset(5, 5), // Shadow position (horizontal, vertical) blurRadius: 10, // Blur radius spreadRadius: 0, // Spread radius ), ], borderRadius: BorderRadius.circular(5), ), child: TextField( textAlignVertical: TextAlignVertical .center, // Center the text vertically decoration: InputDecoration( hintText: 'Search', suffixIcon: Icon(Icons.search), contentPadding: EdgeInsets.all( 10), // Adjust the horizontal padding border: OutlineInputBorder( borderSide: BorderSide( color: Color( 0xFFf5f5f7)), // Set border color to gray ), ), onChanged: search, // Call the search method on text change ), )), ), ], ), SizedBox(height: 20), Row( children: [ Expanded( child: SingleChildScrollView( child: _buildDataTable(), ), ) ], ), ], ), isActive: _currentStep == 2, ), ], ), ), // SizedBox(height: 20), // if (_currentStep == 2) // Align( // alignment: Alignment.bottomRight, // child: ElevatedButton( // onPressed: () { // sendExcelFIleTOAPI(); // }, // child: Text( // 'Complete', // style: TextStyle(color: Colors.white), // ), // style: ElevatedButton.styleFrom( // backgroundColor: Color(0xFFE26728), // ), // ), // ), // SizedBox(height: 20), ], ), ), ), ), ), ); } Widget _buildDataTable() { if (filteredData.isEmpty) { SizedBox(height: 25); return Text('No available data'); } else { return Card( elevation: 0, // Set elevation to 0 for no shadow child: PaginatedDataTable( rowsPerPage: 25, // Adjust rows per page as needed columns: [ DataColumn(label: Text('S.No')), DataColumn(label: Text('Employee ID')), DataColumn(label: Text('Name')), DataColumn(label: Text('Date of Joining')), DataColumn(label: Text('Gender')), DataColumn(label: Text('Relationship')), DataColumn(label: Text('Date of Birth')), DataColumn(label: Text('Mail')), DataColumn(label: Text('Mobile No')), DataColumn(label: Text('SI')), DataColumn(label: Text('Grade')), ], source: _DependenceDataSource0(filteredData), ), ); } } Widget _buildRowWithIcon(IconData iconData, String text, {Color iconColor = Colors.black}) { return Row( children: [ Icon( iconData, color: iconColor, // Set color based on the parameter ), SizedBox(width: 8), // Add some space between icon and text Text(text), // Text widget ], ); } } class Data { final dynamic value; final int row; final int column; final String sheet; Data(this.value, this.row, this.column, this.sheet); } class _DependenceDataSource0 extends DataTableSource { final List> _data; _DependenceDataSource0(this._data); @override DataRow getRow(int index) { final row = _data[index]; String dob = row['DOB'] != null ? formatDate(row['DOB']) : 'N/A'; String doj = row['DOJ'] != null ? formatDate(row['DOJ']) : 'N/A'; return DataRow(cells: [ DataCell(Text(row['Sno'].toString())), DataCell(Text(row['Emp_Code'].toString())), DataCell(Text(row['Name'].toString())), DataCell(Text(doj)), DataCell(Text(row['Gender']?.toString() ?? 'N/A')), DataCell(Text(row['Relation']?.toString() ?? 'N/A')), DataCell(Text(dob)), DataCell(Text(row['Mail']?.toString() ?? 'N/A')), DataCell(Text(row['Mobile']?.toString() ?? 'N/A')), DataCell(Text(row['SI']?.toString() ?? 'N/A')), DataCell(Text(row['Grade']?.toString() ?? 'N/A')), ]); } @override bool get isRowCountApproximate => false; @override int get rowCount => _data.length; @override int get selectedRowCount => 0; String formatDate(dynamic dateValue) { if (dateValue is String) { // If the date is already in string format DateTime dateTime = DateTime.parse(dateValue); return DateFormat('dd-MM-yyyy').format(dateTime); } else if (dateValue is DateCellValue) { // If dateValue is an instance of DateCellValue return DateFormat('dd-MM-yyyy') .format(DateTime.parse(dateValue.toString())); } else { // Handle other cases or null values return 'N/A'; } } }