Flutterバスケアプリ | チームとメンバー管理にCSVエクスポート機能実装&インポート機能改修

はじめに

チームやメンバーを効率的に管理するために、CSV形式でのエクスポート実装と一括更新するためインポート機能の改修を行いました。


CSVエクスポート&インポート機能とは?

CSVエクスポート

CSVエクスポート機能では、アプリ内で管理しているチームやメンバーのデータをCSVファイルとして保存します。

CSVインポート

CSVインポート機能では、エクスポートしたCSVファイルを使ってデータを一括更新します。これにより、登録済みデータの一括更新や新規データの一括挿入が可能になります。


実装のポイント

  1. CSVエクスポート
    チームまたはメンバーのデータをリスト形式で取得し、csvパッケージを使用してCSV形式に変換し、ファイルとして保存します。
  2. CSVインポート
    CSVファイルからデータを読み込み、既存データを更新したり、新しいデータを追加します。IDが存在する場合は更新、存在しない場合は新規挿入を行う仕組みです。

チーム管理のCSVエクスポート&インポート機能

コード解説

1. CSVエクスポート機能

import 'package:flutter/foundation.dart' show kIsWeb;
import 'package:path_provider/path_provider.dart';
import 'package:csv/csv.dart';
import 'dart:io';
import 'package:path/path.dart' as path;

Future<void> _exportCSV() async {
  List<List<dynamic>> rows = [];
  rows.add(["ID", "チーム名", "所在地", "表示順"]);

  for (Team team in _teams) {
    List<dynamic> row = [
      team.id ?? '',
      team.name,
      team.location,
      team.displayOrder,
    ];
    rows.add(row);
  }

  String csv = const ListToCsvConverter().convert(rows);

  try {
    Directory? directory;

    if (kIsWeb) {
      print("Webプラットフォームではサポートされていません。");
      return;
    } else if (Platform.isAndroid || Platform.isIOS) {
      directory = await getApplicationDocumentsDirectory();
    } else if (Platform.isLinux || Platform.isMacOS || Platform.isWindows) {
      directory = await getApplicationDocumentsDirectory();
    } else {
      print("サポートされていないプラットフォームです。");
      return;
    }

    final String filePath = path.join(directory.path, 'teams.csv');
    final file = File(filePath);
    await file.writeAsString(csv);

    print("CSVファイルが保存されました: $filePath");
  } catch (e) {
    print("CSVエクスポートエラー: $e");
  }
}

2. CSVインポート機能(更新機能付き)

Future<void> _importCSV() async {
  try {
    FilePickerResult? result = await FilePicker.platform.pickFiles(
      type: FileType.custom,
      allowedExtensions: ['csv'],
    );

    if (result != null) {
      File file = File(result.files.single.path!);
      String fileContent = await file.readAsString();

      List<String> rows = fileContent.split('\n');
      if (rows.isNotEmpty) {
        rows.removeAt(0); // 最初の行を削除(ヘッダー)

        for (var row in rows) {
          List<String> values = row.split(',');

          if (values.length >= 4) {
            int? id = int.tryParse(values[0].trim());
            String name = values[1].trim();
            String location = values[2].trim();
            int displayOrder = int.tryParse(values[3].trim()) ?? (_teams.length + 1);

            Team newTeam = Team(
              id: id,
              name: name,
              location: location,
              displayOrder: displayOrder,
              registrationDate: DateTime.now().toString(),
              lastEditedDate: DateTime.now().toString(),
            );

            if (id != null) {
              await _teamProvider.updateTeam(newTeam); // 更新
            } else {
              await _teamProvider.insertTeam(newTeam); // 新規追加
            }
          }
        }

        await _loadTeams();
      }
    }
  } catch (e) {
    print("CSVインポートエラー: $e");
  }
}

スクリーンショット

メンバー管理のCSVエクスポート&インポート機能

コード解説

1. CSVエクスポート機能

import 'package:path_provider/path_provider.dart';
import 'package:csv/csv.dart';
import 'dart:io';
import 'package:path/path.dart' as path;

Future<void> _exportCSV() async {
  List<List<dynamic>> rows = [];
  rows.add(["ID", "名前", "番号", "ポジション", "身長", "体重", "表示順"]);

  for (Member member in _members) {
    List<dynamic> row = [
      member.id ?? '',
      member.name,
      member.number,
      member.position,
      member.height,
      member.weight,
      member.displayOrder,
    ];
    rows.add(row);
  }

  String csv = const ListToCsvConverter().convert(rows);

  try {
    Directory? directory;

    if (kIsWeb) {
      print("Webプラットフォームではサポートされていません。");
      return;
    } else if (Platform.isAndroid || Platform.isIOS) {
      directory = await getApplicationDocumentsDirectory();
    } else if (Platform.isLinux || Platform.isMacOS || Platform.isWindows) {
      directory = await getApplicationDocumentsDirectory();
    } else {
      print("サポートされていないプラットフォームです。");
      return;
    }

    final String filePath = path.join(directory.path, 'members.csv');
    final file = File(filePath);
    await file.writeAsString(csv);

    print("CSVファイルが保存されました: $filePath");
  } catch (e) {
    print("CSVエクスポートエラー: $e");
  }
}

2. CSVインポート機能(更新機能付き)

Future<void> _importCSV() async {
  try {
    FilePickerResult? result = await FilePicker.platform.pickFiles(
      type: FileType.custom,
      allowedExtensions: ['csv'],
    );

    if (result != null) {
      File file = File(result.files.single.path!);
      String fileContent = await file.readAsString();

      List<String> rows = fileContent.split('\n');
      if (rows.isNotEmpty) {
        rows.removeAt(0); // 最初の行を削除(ヘッダー)

        for (var row in rows) {
          List<String> values = row.split(',');

          if (values.length >= 6) {
            int? id = int.tryParse(values[0].trim());
            String name = values[1].trim();
            int number = int.tryParse(values[2].trim()) ?? 0;
            String position = values[3].trim();
            double height = double.tryParse(values[4].trim()) ?? 0.0;
            double weight = double.tryParse(values[5].trim()) ?? 0.0;

            Member newMember = Member(
              id: id,
              name: name,
              number: number,
              position: position,
              height: height,
              weight: weight,
              teamId: widget.team.id!,
              registrationDate: DateTime.now().toString(),
              lastEditedDate: DateTime.now().toString(),
              displayOrder: _members.length + 1,
            );

            if (id != null) {
              await _memberProvider.updateMember(newMember); // 更新
            } else {
              await _memberProvider.insertMember(newMember); // 新規追加
            }
          }
        }

        await _loadMembers();
      }
    }
  } catch (e) {
    print("CSVインポートエラー: $e");
  }
}

スクリーンショット

まとめ

今回の実装では、CSVエクスポートとインポート機能を実装し、簡単にデータを出力・更新できるようにしました。これにより、チームやメンバーのデータを他システムと効率的に連携し、データ管理がより柔軟になります。

関連記事

コメント

タイトルとURLをコピーしました