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

发布于 1周前 作者 yuanlaile 来自 Flutter

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的唯一或最佳选项,根据你的具体需求,你可能需要查找其他适合的插件或库。

回到顶部