Rodrigo Santos
Rodrigo Santos

Reputation: 23

Flutter- CSV file to Map

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

Answers (3)

shradha Khaire
shradha Khaire

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

mezoni
mezoni

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

Emmett Deen
Emmett Deen

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

Related Questions