Reputation: 23
I need to convert a CSV file to a Map<String, String> and I'm using this package for the task. The problem is that the output of the map is returning a space before every key, as you can see:
{ 001: Visto de Trabalho, 002: Carta de Pesados, 003: Medicina do Trabalho, 004: Título de Residente]}
This is my code:
HashMap _refHashMap;
Future<HashMap> convertCSV() async {
_refHashMap = await CSV_HashMap().hashMapConvertor(
refList: ["id", "name"], csvPath: 'assets/document_types.csv');
return _refHashMap;
}
Map<String, String> loadDocTypes() {
convertCSV();
var ids = _refHashMap["id"];
var names = _refHashMap["name"];
var map = Map.fromIterables(ids, names);
var convertedMap = Map<String, String>.from(map);
return convertedMap;
}
Can you help me? Thank you in advance
Upvotes: 2
Views: 1102
Reputation: 1
import 'package:flutter/material.dart';
import 'package:file_picker/file_picker.dart';
import 'package:csv/csv.dart';
import 'dart:html' as html;
import '../utils/csv_helper.dart';
import '../widgets/custom_box.dart';
import '../widgets/primary_key_mapping.dart';
import '../widgets/filter_widget.dart';
import 'merge_screen.dart';
class HomeScreen extends StatefulWidget {
@override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
List<List<dynamic>> csvData1 = [];
List<List<dynamic>> csvData2 = [];
List<String> fields1 = [];
List<String> fields2 = [];
List<bool> selectedFields1 = [];
List<bool> selectedFields2 = [];
String? selectedPrimaryKey1;
String? selectedPrimaryKey2;
Map<String, String> filters = {};
Future<void> pickCSVFile(int fileNumber) async {
final result = await FilePicker.platform.pickFiles(type: FileType.custom, allowedExtensions: ['csv']);
if (result != null) {
final inputFile = result.files.single.bytes;
List<List<dynamic>> rows = await CsvHelper().getCSVData(inputFile!);
setState(() {
if (fileNumber == 1) {
csvData1 = rows;
fields1 = rows[0].map((field) => field.toString()).toList();
selectedFields1 = List.filled(fields1.length, false);
} else {
csvData2 = rows;
fields2 = rows[0].map((field) => field.toString()).toList();
selectedFields2 = List.filled(fields2.length, false);
}
});
}
}
void mergeCSV() {
List<List<dynamic>> mergedData = CsvHelper().mergeSelectedCSV(
csvData1,
csvData2,
fields1,
fields2,
selectedFields1,
selectedFields2,
selectedPrimaryKey1,
selectedPrimaryKey2,
filters,
);
Navigator.push(
context,
MaterialPageRoute(builder: (context) => MergeScreen(mergedData: mergedData)),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('CSV Merger')),
body: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Column(
children: [
CustomBox(
title: "Master CSV File",
onTap: () => pickCSVFile(1),
fields: fields1,
selectedFields: selectedFields1,
onSelectionChanged: (index, value) {
setState(() => selectedFields1[index] = value);
},
),
CustomBox(
title: "Source CSV File",
onTap: () => pickCSVFile(2),
fields: fields2,
selectedFields: selectedFields2,
onSelectionChanged: (index, value) {
setState(() => selectedFields2[index] = value);
},
),
PrimaryKeyMapping(
fields1: fields1,
fields2: fields2,
onPrimaryKeySelected: (key1, key2) {
setState(() {
selectedPrimaryKey1 = key1;
selectedPrimaryKey2 = key2;
});
},
),
FilterWidget(
fields1: fields1,
fields2: fields2,
onFilterApplied: (updatedFilters) {
setState(() {
filters = updatedFilters;
});
},
),
],
),
Column(
children: [
ElevatedButton(
onPressed: mergeCSV,
style: ElevatedButton.styleFrom(
backgroundColor: Colors.blue,
elevation: 5,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 15),
),
child: Text("Merge CSV Files", style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)),
),
],
),
],
),
);
}
}
import 'package:flutter/material.dart';
class PrimaryKeyMapping extends StatefulWidget {
final List<String> fields1;
final List<String> fields2;
final Function(String?, String?) onPrimaryKeySelected;
PrimaryKeyMapping({required this.fields1, required this.fields2, required this.onPrimaryKeySelected});
@override
_PrimaryKeyMappingState createState() => _PrimaryKeyMappingState();
}
class _PrimaryKeyMappingState extends State<PrimaryKeyMapping> {
String? selectedKey1;
String? selectedKey2;
@override
Widget build(BuildContext context) {
return Column(
children: [
Text("Map Primary Key", style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18)),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
DropdownButton<String>(
hint: Text("Select Master CSV Key"),
value: selectedKey1,
items: widget.fields1.map((field) => DropdownMenuItem(value: field, child: Text(field))).toList(),
onChanged: (value) {
setState(() {
selectedKey1 = value;
widget.onPrimaryKeySelected(selectedKey1, selectedKey2);
});
},
),
SizedBox(width: 20),
DropdownButton<String>(
hint: Text("Select Source CSV Key"),
value: selectedKey2,
items: widget.fields2.map((field) => DropdownMenuItem(value: field, child: Text(field))).toList(),
onChanged: (value) {
setState(() {
selectedKey2 = value;
widget.onPrimaryKeySelected(selectedKey1, selectedKey2);
});
},
),
],
),
],
);
}
}
import 'package:flutter/material.dart';
class FilterWidget extends StatefulWidget {
final List<String> fields1;
final List<String> fields2;
final Function(Map<String, String>) onFilterApplied;
FilterWidget({required this.fields1, required this.fields2, required this.onFilterApplied});
@override
_FilterWidgetState createState() => _FilterWidgetState();
}
class _FilterWidgetState extends State<FilterWidget> {
Map<String, TextEditingController> controllers = {};
@override
void initState() {
super.initState();
for (var field in widget.fields1 + widget.fields2) {
controllers[field] = TextEditingController();
}
}
@override
Widget build(BuildContext context) {
return Column(
children: [
Text("Apply Filters", style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18)),
...controllers.keys.map((field) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 5),
child: TextField(
controller: controllers[field],
decoration: InputDecoration(
labelText: "Filter for $field",
border: OutlineInputBorder(),
),
onChanged: (value) {
widget.onFilterApplied({field: value});
},
),
);
}).toList(),
],
);
}
}
<!-- begin snippet: js hide: false console: true babel: false babelPresetReact: false babelPresetTS: false -->
Upvotes: 0
Reputation: 11220
It can be done in such a simple way.
Not very elegant, but this will work as long as the CSV file is as expected by this algorithm (header and records).
import 'package:fast_csv/fast_csv.dart' as _fast_csv;
void main(List<String> args) {
final data = _fast_csv.parse(_source);
final keys = data.first;
final list = data.skip(1).map((e) => Map.fromIterables(keys, e)).toList();
print(list.first);
print(list[1]['Name']);
}
const _source = '''
Name,Total Cores,Processor Base Frequency
"Intel® Celeron® Processor G530 2M Cache, 2.40 GHz",2,2.40 GHz
"Intel® Core™ i5-3470 Processor 6M Cache, up to 3.60 GHz",4,3.20 GHz
"Intel® Core™ i3-10100F Processor 6M Cache, up to 4.30 GHz",4,3.60 GHz
''';
Output:
{Name: Intel® Celeron® Processor G530 2M Cache, 2.40 GHz, Total Cores: 2, Processor Base Frequency: 2.40 GHz}
Intel® Core™ i5-3470 Processor 6M Cache, up to 3.60 GHz
Upvotes: 0
Reputation: 731
Give this a try, it trims the keys to remove the whitespace at the end.
Map<String, String> loadDocTypes() {
convertCSV();
var ids = _refHashMap["id"];
var names = _refHashMap["name"];
var map = Map.fromIterables(ids, names);
var convertedMap = Map<String, String>.from(map);
return convertedMap.map((key, value) => MapEntry(key.trim(), value)); // Add this line
}
Upvotes: 3