如何使用 Flutter 从 FaceBook 导出数据到 CSV 文件

问题描述

我有以下屏幕,其中包含用户信息并有一个按钮 Export CSV

enter image description here

当点击 Export CSV 时,我只需要按以下格式导出文件

enter image description here

这是 CSV 控制器文件

import 'package:csv/csv.dart';
import 'dart:io' as Io;
import 'package:path_provider/path_provider.dart';
import 'package:intl/intl.dart';
import 'package:simpleappauth/general.dart';

class CsvController {

  static Future<Io.File> getCsvFromList(List<List<dynamic>> csvDataList) async {
    try {
      String csvDataString = const ListToCsvConverter().convert(csvDataList);
      Io.File csvFile = await _saveFile(csvDataString);
      return csvFile;
    } catch (e) {
      print(e.toString());
      return null;
    }
  }

  static Future<Io.File> getCsvFromString(String csvString) async {
    try {
      Io.File csvFile = await _saveFile(csvString);
      return csvFile;
    } catch (e) {
      print(e.toString());
      return null;
    }
  }

  static Future<String> _getFilePath(String fileName) async {
    Io.Directory appDocumentsDirectory = await getExternalStorageDirectory(); // 1
    String appDocumentsPath = appDocumentsDirectory.path; // 2
    String filePath = '$appDocumentsPath/$fileName.csv'; // 3
    return filePath;
  }

  final DateFormat formatter = DateFormat('yyyy-MM-dd');

  static Future<Io.File> _saveFile(String fileDataString,{index = 0}) async {
    try {
      Io.File file = Io.File(await _getFilePath(
          "${DateTime.Now().millisecondsSinceEpoch}" +
              (index > 0 ? "($index)" : "")));
      if (!file.existsSync()) {
        // 1
        file.writeAsstringSync(fileDataString); // 2
        return file;
      } else {
        return _saveFile(fileDataString,index: index + 1);
      }
    } catch (e) {
      print(e.toString());
      return null;
    }
  }
}

这是下面的main.dart

import 'package:Flutter/material.dart';
import 'package:Flutter_facebook_login/Flutter_facebook_login.dart';
import 'package:http/http.dart' as http;
import 'dart:convert' as JSON;
import 'dart:io';

import 'package:simpleappauth/csv_controller.dart';

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

class MyApp extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    // Todo: implement createState
    return _MyAppState();
  }
}

class _MyAppState extends State<MyApp> {
  bool _isLoggedIn = false;
  Map userProfile;
  final facebookLogin = FacebookLogin();


  _loginWithFB() async {
    final result = await facebookLogin.logIn(['email']);

    switch (result.status) {
      case FacebookLoginStatus.loggedIn:
        final token = result.accesstoken.token;
        final graphResponse = await http.get(Uri.parse(
            'https://graph.facebook.com/v10.0/me?fields=id,name,picture,email,name_format,birthday,hometown&access_token=${token}'));

        final profile = JSON.jsonDecode(graphResponse.body);
        print(profile);
        setState(() {
          userProfile = profile;
          _isLoggedIn = true;
        });
        break;

      case FacebookLoginStatus.cancelledByUser:
        setState(() => _isLoggedIn = false);
        break;
      case FacebookLoginStatus.error:
        setState(() => _isLoggedIn = false);
        break;
    }
  }

  _logout() {
    facebookLogin.logout();
    setState(() {
      _isLoggedIn = false;
    });
  }

  @override
  Widget build(BuildContext context) {
    // Todo: implement build
    return MaterialApp(
      home: Scaffold(
        body: Center(
            child: _isLoggedIn
                ? Column(
              mainAxisAlignment: MainAxisAlignment.center,children: <Widget>[
                Image.network(
                  userProfile["picture"]["data"]["url"],height: 100.0,width: 100.0,),Text(userProfile["id"]),Text(userProfile["name"]),Text(userProfile["email"]),Text(userProfile["name_format"]),Text(userProfile["birthday"] ?? 'Birthday: empty'),Text(userProfile["hometown"] ?? 'Hometown: empty'),OutlinedButton(
                  child: Text("logout"),onpressed: () {
                    _logout();
                  },OutlinedButton(
                  child: Text("Export CSV"),onpressed: () {
                  },],)
                : Center(
              child: OutlinedButton(
                child: Text("Login with Facebook"),onpressed: () {
                  _loginWithFB();
                },)),);
  }
}

所以现在我想使用 main 类中的 CSV 控制器文件来导出包含用户数据的 csv 文件

解决方法

第一步:在你的Csvcontroller类中添加这两个函数

 static List<List<dynamic>> getCsvListFromUserProfilesMap(
      List<Map<String,dynamic>> userProfiles) {
    List<List<dynamic>> csvDataRows = [];
    List<dynamic> headerRow = ["id","name","email","hometown"];
    csvDataRows.add(headerRow);

    userProfiles.forEach((userProfile) {
      List<dynamic> dataRow = [
        userProfile["id"],userProfile["name"],userProfile["email"],userProfile["hometown"] ?? 'Hometown: empty'
      ];
      csvDataRows.add(dataRow);
    });
    return csvDataRows;
  }

  static List<List<dynamic>> getCsvListFromUserProfileMap(
      Map<String,dynamic> userProfile) {
    List<List<dynamic>> csvDataRows = [];
    List<dynamic> headerRow = ["id","hometown"];
    csvDataRows.add(headerRow);

    List<dynamic> dataRow = [
      userProfile["id"],userProfile["hometown"] ?? 'Hometown: empty'
    ];
    csvDataRows.add(dataRow);
    return csvDataRows;
  }


第 2 步:只需将以下代码添加到导出 CSV 按钮即可。

//don't forget to import the CsvController file in the main
For example or testing purpose,//Initialize these variables in your code
 var userProfile = [
    {
      "id": 123,"name": "User 1","email": "user1@gmail.com","homeTown": "city1"
    },];

  var userProfiles = [
    {
      "id": 123,{
      "id": 1234,"name": "User 2","email": "user2@gmail.com","homeTown": "city2"
    },];


 onPressed: () {

//if you just want to export only one profile
var userCsvData = CsvController.getCsvListFromUserProfileMap(userProfile);
var csvFile = await CsvController.getCsvFromList(userCsvData);
if(csvFile != null){
    print("File created here :"+csvFile.path);
}else{
    print("file not created");
}

//if you just want to export only multiple profiles
var userCsvData = CsvController.getCsvListFromUserProfilesMap(userProfiles);
var csvFile = await CsvController.getCsvFromList(userCsvData);
if(csvFile != null){
    print("File created here :"+csvFile.path);
}else{
    print("file not created");
}
                  },