Flutter CSV文件加载插件csvloader的使用

Flutter CSV文件加载插件csvloader的使用

介绍

csvloader 是一个轻量级、跨平台的 Dart 包,用于从 Stream 中读取 CSV 数据。它支持并扩展了 RFC 4180 标准。通过这个插件,您可以轻松地解析 CSV 文件,并根据需要处理数据。

使用方法

1. 导入包

首先,您需要在 pubspec.yaml 文件中添加 csvloader 依赖:

dependencies:
  csvloader: ^latest_version

然后,在您的 Dart 文件中导入 csvloader

import 'package:csvloader/csvloader.dart';
2. 创建 CSV 数据流

csvloader 可以从 Stream<String> 中读取 CSV 数据。您可以创建一个自定义的 Stream 来提供 CSV 数据。例如,以下代码创建了一个包含零件目录的 CSV 数据流:

Stream<String> catalog() async* {
  // CsvLoader 会自动解码引号之间的数据
  yield 'Part code\tPart label\tDescription\r\n';
  yield 'B1XX\tBolt\t"Your average bolt"\r\n';
  yield 'S2XX\tScrew\t"Your average screw"\r\n';
  yield 'N1XX\tNut\t"Nut; for bolts ""B1XX"""\r\n';
  yield '9N\tNail\t"A 9"" nail"\r\n';
}
3. 解析 CSV 数据

使用 CsvLoader.withHeaders 方法来解析 CSV 数据流。您可以指定分隔符(默认是逗号 ,),也可以使用其他字符作为分隔符,例如制表符 \t

void main() async {
  // 使用制表符作为分隔符
  final catalogCsv = CsvLoader.withHeaders(catalog(), separator: '\t');

  await for (var row in catalogCsv.rows) {
    final code = row['Part code'];
    final label = row['Part label'];
    final descr = row['Description'];
    print(' - $label ($code): $descr');
  }
}

完整示例 Demo

以下是一个完整的示例,展示了如何使用 csvloader 插件来读取不同类型的 CSV 数据:

import 'dart:math';

import 'package:csvloader/csvloader.dart';

void main() async {
  await readNumbers();
  await readFamilies();
  await readCatalog();
}

// 读取数字数据
Stream<String> numbers() async* {
  // CsvLoader 支持部分条目流
  yield 'Number,Odd?,Even?,Square?,Prime?\r\n0,false,tr';
  yield 'ue,true,false\r\n1,true,false,true,false\r\n2,';
  yield 'false,true,false,true\r\n3,true,false,false,true\r';
  yield '\n3.5,false,false,false,false\r\n4,false,true,tru';
  yield 'e,false\r\n9,true,false,true,false';
}

Future<void> readNumbers() async {
  print('Reading numbers...');
  final numbersCsv = CsvLoader.withHeaders(numbers());

  final props = <String>[];

  await for (var row in numbersCsv.rows) {
    final n = num.parse(row['Number'] ?? '');
    final odd = (row['Odd?'] == 'true');
    final even = (row['Even?'] == 'true');
    final square = (row['Square?'] == 'true');
    final prime = (row['Prime?'] == 'true');

    props.clear();

    if (odd && !even) {
      props.add('$n is odd.');
    } else if (!odd && even) {
      props.add('$n is even.');
    } else {
      props.add(
          '$n is strange, it is ${odd ? 'odd' : 'not odd'} and ${even ? 'even' : 'not even'}.');
    }

    if (square) {
      props.add('$n is the square of ${sqrt(n).toInt()}.');
    }

    if (prime) {
      props.add('$n is prime.');
    }

    print('   ${props.join(' ')}');
  }
}

// 读取家庭数据
Stream<String> families() async* {
  // CsvLoader 支持重复的列标题
  yield 'Name,First name,Father name,First name,Mother name,First name\r\n';
  // CsvLoader 忽略空行
  yield '\r\n';
  yield ' \r\n';
  yield ',,,,\r\n';
  yield ' , , , , \r\n';
  yield ',\t,\t,\t,\r\n';
  yield 'Doe,Jeffrey,Doe,John,Smith,Ann\r\n';
  yield 'Doe,Martin,Doe,John,Smith,Ann\r\n';
  yield 'Doe,Mary Ann,Doe,John,Smith,Ann\r\n';
  yield '\r\n';
  yield 'Doe,Jerry,Doe,John,Jones,Jennifer\r\n';
  yield '\r\n';
  yield 'Fergusson,Jack,Fergusson,Robert,Smith,Ann\r\n';
  yield '\r\n';
}

Future<void> readFamilies() async {
  print('Reading families...');
  final familyCsv = CsvLoader.withHeaders(families());

  final tree = <String, Map<String, List<String>>>{};

  await for (var row in familyCsv.rows) {
    final child = '${row.get('First name', 0)} ${row['Name']}';
    final father = '${row.get('First name', 1)} ${row['Father name']}';
    final mother = '${row.get('First name', 2)} ${row['Mother name']}';

    final fatherSpouses = tree.putIfAbsent(father, () => {});
    final spouseChildren = fatherSpouses.putIfAbsent(mother, () => []);
    spouseChildren.add(child);
  }

  for (var fatherEntry in tree.entries) {
    final father = fatherEntry.key;
    for (var spouseEntry in fatherEntry.value.entries) {
      final mother = spouseEntry.key;
      final children = spouseEntry.value;
      print(
          '   $father and $mother have ${children.length == 1 ? '1 child' : '${children.length} children'}');
      for (var child in children) {
        print('      - $child');
      }
    }
  }
}

// 读取零件目录
Stream<String> catalog() async* {
  // CsvLoader 会自动解码引号之间的数据
  yield 'Part code\tPart label\tDescription\r\nB1XX\tBolt\t"Your ';
  yield 'average bolt"\r\nS2XX\tScrew\t"Your average screw"\r';
  yield '\nN1XX\tNut\t"Nut; for bolts ""B1X';
  yield 'X"""\r\n9N\tNail\t"A 9"';
  yield '" nail"\r\n';
}

Future<void> readCatalog() async {
  print('Reading catalog...');
  // 使用制表符作为分隔符
  final catalogCsv = CsvLoader.withHeaders(catalog(), separator: '\t');

  await for (var row in catalogCsv.rows) {
    final code = row['Part code'];
    final label = row['Part label'];
    final descr = row['Description'];
    print('   $label ($code): $descr');
  }
}

更多关于Flutter CSV文件加载插件csvloader的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter CSV文件加载插件csvloader的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter应用中使用csvloader插件来加载CSV文件的示例代码。需要注意的是,csvloader并不是Flutter社区中广泛使用的标准插件,因此这里假设你提到的csvloader是指一个能够处理CSV文件的Flutter插件,或者我们可以使用类似功能的插件,比如csv库来处理CSV文件。

在实际开发中,通常我们会使用flutter_csv这样的插件来处理CSV文件。下面是一个使用flutter_csv插件的示例代码,因为它提供了加载和处理CSV文件的功能。

首先,确保在pubspec.yaml文件中添加依赖:

dependencies:
  flutter:
    sdk: flutter
  flutter_csv: ^3.0.0  # 请检查最新版本号

然后运行flutter pub get来安装依赖。

接下来,编写Flutter代码来加载和处理CSV文件。假设我们有一个CSV文件,名为data.csv,内容如下:

name,age,city
Alice,30,New York
Bob,25,Los Angeles
Charlie,35,Chicago

以下是Flutter应用的示例代码:

import 'package:flutter/material.dart';
import 'package:flutter_csv/flutter_csv.dart';
import 'dart:io';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'CSV Loader Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  List<List<dynamic>> data = [];

  @override
  void initState() {
    super.initState();
    _loadCSV();
  }

  Future<void> _loadCSV() async {
    final file = File('assets/data.csv'); // 确保CSV文件在assets文件夹中
    if (await file.exists()) {
      String csvContent = await file.readAsString();
      List<List<dynamic>> parsedData = CsvToListConverter().convert(csvContent);
      setState(() {
        data = parsedData;
      });
    } else {
      print('File does not exist');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('CSV Loader Demo'),
      ),
      body: data.isEmpty
          ? Center(child: CircularProgressIndicator())
          : ListView.builder(
              itemCount: data.length,
              itemBuilder: (context, index) {
                return ListTile(
                  title: Text(data[index].join(', ')),
                );
              },
            ),
    );
  }
}

在上面的代码中,我们做了以下几件事:

  1. pubspec.yaml文件中添加了flutter_csv依赖。
  2. 创建了一个Flutter应用,并在主页面中加载和处理CSV文件。
  3. 使用File类来读取assets文件夹中的CSV文件。请确保你的CSV文件已经被放置在assets文件夹中,并且在pubspec.yaml中正确声明了资产:
flutter:
  assets:
    - assets/data.csv
  1. 使用CsvToListConverter类将CSV内容转换为列表。
  2. 使用ListView.builder来显示CSV数据。

请注意,如果你的CSV文件不是放在assets文件夹中,而是从网络或其他来源加载,你需要相应地调整代码来读取文件内容。此外,flutter_csv插件可能不是处理CSV的唯一或最佳选项,根据你的具体需求,你可能需要查找其他适合的插件或库。

回到顶部