はじめに
CSVファイルを使ってチームやメンバーを一括登録できる機能を実装しました。この記事では、チームとメンバーのCSVインポート機能の実装方法を解説します。
CSVインポート機能の概要
まずは、CSVファイルを使ってデータをインポートする機能の概要です。以下のような要件を満たす必要があります。
- CSVファイルを選択し、その内容を読み込む
- 各行を適切なデータ形式に変換し、重複チェックを行った後、データベースに登録
- チームやメンバーのデータにおいて、重複する項目(チーム名や番号)がある場合はエラーメッセージを表示
- 正常に登録できた場合は、アプリの画面に反映
チーム登録のCSVインポート機能
まずは、チームの登録画面にCSVインポート機能を実装しました。チーム名や所在地などをまとめてインポートできるようになっています。
チームCSVのサンプル
チーム名,所在地,表示順
Team A,Tokyo,1
Team B,Osaka,2
Team C,Nagoya,3
チーム登録画面のコード
以下のコードは、チームを登録する画面に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();
print("File Content: $fileContent");
List<String> rows = fileContent.split('\n');
print("Rows after splitting by newline: $rows");
if (rows.isNotEmpty) {
rows.removeAt(0); // ヘッダーを削除
print("Rows after header removal: $rows");
for (var row in rows) {
List<String> values = row.split(','); // 各行をカンマで分割
print("Processing row: $values");
if (values.length >= 3) {
String name = values[0].trim();
String location = values[1].trim();
int order = int.tryParse(values[2].trim()) ?? _teams.length + 1;
Team newTeam = Team(
name: name,
location: location,
registrationDate: DateTime.now().toString(),
lastEditedDate: DateTime.now().toString(),
displayOrder: order,
);
await _teamProvider.insertTeam(newTeam);
print("Successfully inserted team: $name");
} else {
print("Invalid row: $row");
}
}
await _loadTeams();
print("Teams loaded after CSV import: ${_teams.map((t) => t.name).toList()}");
} else {
print("No rows found in CSV.");
}
}
} catch (e) {
print("Error importing CSV: $e");
}
}
チーム登録画面のスクリーンショット
メンバー登録のCSVインポート機能
次に、メンバー登録の画面にCSVインポート機能を実装しました。メンバーには、名前、番号、ポジション、身長、体重、表示順といった情報を含めます。
メンバーCSVのサンプル
名前,番号,ポジション,身長,体重,表示順
Player A,10,PG,180,75,1
Player B,11,SG,185,80,2
Player C,12,SF,190,85,3
メンバー登録画面のコード
以下のコードは、メンバー登録画面に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();
print("File Content: $fileContent");
List<String> rows = fileContent.split('\n');
print("Rows after splitting by newline: $rows");
if (rows.isNotEmpty) {
rows.removeAt(0); // ヘッダーを削除
print("Rows after header removal: $rows");
for (var row in rows) {
List<String> values = row.split(','); // 各行をカンマで分割
print("Processing row: $values");
if (values.length >= 6) {
String name = values[0].trim();
int number = int.tryParse(values[1].trim()) ?? 0;
String position = values[2].trim();
double height = double.tryParse(values[3].trim()) ?? 0.0;
double weight = double.tryParse(values[4].trim()) ?? 0.0;
int displayOrder = int.tryParse(values[5].trim()) ?? _members.length + 1;
Member newMember = Member(
name: name,
number: number,
position: position,
height: height,
weight: weight,
teamId: widget.team.id!,
registrationDate: DateTime.now().toString(),
lastEditedDate: DateTime.now().toString(),
displayOrder: displayOrder,
);
// 同じ番号が存在するかチェック
Member? existingMember = await _memberProvider.getMemberByTeamAndNumber(widget.team.id!, number);
if (existingMember != null) {
print("重複するメンバーが存在します: $number");
} else {
await _memberProvider.insertMember(newMember);
print("Successfully inserted member: $name");
}
} else {
print("Invalid row: $row");
}
}
await _loadMembers();
print("Members loaded after CSV import: ${_members.map((m) => m.name).toList()}");
} else {
print("No rows found in CSV.");
}
}
} catch (e) {
print("Error importing CSV: $e");
}
}
メンバー登録画面のスクリーンショット
まとめ
このようにして、チームとメンバーをCSVファイルから一括でインポートできる機能を実装しました。手作業で1つ1つ登録するのではなく、まとめてデータを投入できるので、効率がアップしました。
コメント