Flutter如何读取Excel数据映射到现有User类后展示在DataTable中
Flutter 读取Excel并渲染到DataTable完整流程
1. 引入所需依赖
首先在pubspec.yaml文件中添加Excel解析依赖:
dependencies: flutter: sdk: flutter excel: ^2.1.0 # Excel解析核心包
如果你的Excel文件是放在项目的assets目录中内置使用,还需要在pubspec.yaml中配置资源路径:
flutter: assets: - assets/users.xlsx # 替换为你的Excel文件实际路径
配置完成后执行flutter pub get安装依赖。
2. 编写Excel读取与User映射逻辑
导入对应包后,编写异步方法读取Excel内容并映射为你预先定义的User类对象列表:
import 'package:excel/excel.dart'; import 'package:flutter/services.dart'; import '你的User类所在文件路径/user.dart'; Future<List<User>> loadUserListFromExcel() async { // 读取assets内置Excel文件的逻辑 ByteData fileBytes = await rootBundle.load("assets/users.xlsx"); Uint8List uint8List = fileBytes.buffer.asUint8List(); Excel excelFile = Excel.decodeBytes(uint8List); List<User> userList = []; // 取第一个工作表,也可通过表名精确获取:excelFile.tables["Sheet1"] Sheet targetSheet = excelFile.tables.values.first; // 遍历行数据,i从1开始跳过第一行表头 for (int i = 1; i < targetSheet.rows.length; i++) { List<Data?> rowData = targetSheet.rows[i]; // 按Excel列顺序读取数据,索引0为第一列,依次对应firstName、lastName、age String firstName = rowData[0]?.value.toString() ?? ""; String lastName = rowData[1]?.value.toString() ?? ""; int age = int.tryParse(rowData[2]?.value.toString() ?? "0") ?? 0; userList.add(User( firstName: firstName, lastName: lastName, age: age, )); } return userList; }
如果你需要读取用户本地存储的Excel文件,可搭配
file_picker包让用户选择文件,拿到File对象后调用file.readAsBytes()获取字节数据传入Excel.decodeBytes即可,无需使用rootBundle读取assets。
3. 渲染数据到DataTable组件
使用FutureBuilder处理异步加载状态,将拿到的User列表渲染为DataTable:
class UserExcelDisplayPage extends StatefulWidget { const UserExcelDisplayPage({super.key}); @override State<UserExcelDisplayPage> createState() => _UserExcelDisplayPageState(); } class _UserExcelDisplayPageState extends State<UserExcelDisplayPage> { late Future<List<User>> _userFuture; @override void initState() { super.initState(); // 页面初始化时触发Excel读取 _userFuture = loadUserListFromExcel(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text("用户列表")), body: FutureBuilder<List<User>>( future: _userFuture, builder: (context, snapshot) { // 加载中状态 if (snapshot.connectionState == ConnectionState.waiting) { return const Center(child: CircularProgressIndicator()); } // 加载出错状态 if (snapshot.hasError) { return Center(child: Text("加载失败:${snapshot.error}")); } // 无数据状态 if (!snapshot.hasData || snapshot.data!.isEmpty) { return const Center(child: Text("暂无用户数据")); } // 加载完成渲染表格 final userList = snapshot.data!; // 横向滚动适配表格宽度 return SingleChildScrollView( scrollDirection: Axis.horizontal, child: DataTable( columns: const [ DataColumn(label: Text("名字")), DataColumn(label: Text("姓氏")), DataColumn(label: Text("年龄")), ], rows: userList.map((user) { return DataRow(cells: [ DataCell(Text(user.firstName)), DataCell(Text(user.lastName)), DataCell(Text(user.age.toString())), ]); }).toList(), ), ); }, ), ); } }
注意事项
- 请确保Excel中列的顺序和代码中读取的索引对应,避免数据错位
- 若数据量过大,建议做分页处理或使用高性能表格组件,避免页面卡顿
- 处理数字类型字段时建议做类型兼容校验,避免类型转换异常
内容的提问来源于stack exchange,提问作者Lash
相关产品推荐
相关产品推荐

