Flutter如何将读取的Excel文件数据加载显示到ListView组件中
问题根因排查
- 你定义的
read()函数内部的list是局部变量,读取完成后数据直接丢失,没有和DataScreen的状态变量绑定 - 异步读取Excel的操作完成后没有调用
setState()触发UI重新渲染,ListView拿不到最新数据 - 未在
pubspec.yaml中注册Excel资源路径的话,rootBundle.load会读取失败,也会导致无数据 - Excel读取到的单元格值是动态类型,未强制转成String会触发类型异常,导致渲染终止
修复方案
1. 调整DataScreen代码
把Excel读取逻辑移到页面State内部,读取完成后调用setState刷新UI,同时注意避免和Flutter原生DataRow类重名:
import 'package:flutter/services.dart'; import 'package:excel/excel.dart'; // 改名避免和Flutter原生DataRow类冲突 class CustomDataRow { String dni; String nombre; CustomDataRow(this.dni, this.nombre); } class DataScreen extends StatefulWidget { @override DataScreenState createState() => DataScreenState(); } class DataScreenState extends State<DataScreen> { List<CustomDataRow> dataList = []; @override void initState() { super.initState(); // 页面初始化时触发Excel读取 readExcelData(); } Future<void> readExcelData() async { List<CustomDataRow> tempList = []; try { ByteData data = await rootBundle.load("db/Propuestas.xlsx"); var bytes = data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes); var excel = Excel.decodeBytes(bytes); for (var table in excel.tables.keys) { for (var row in excel.tables[table]!.rows) { // 校验至少有两列数据,避免数组越界 if (row.length >= 2) { // 强制转成String,避免类型异常 String dni = row[0]?.value.toString() ?? ''; String nombre = row[1]?.value.toString() ?? ''; tempList.add(CustomDataRow(dni, nombre)); } } } // 更新状态触发UI刷新 setState(() { dataList = tempList; }); } catch (e) { print("读取Excel出错:$e"); } } @override Widget build(BuildContext context) { // 读取过程中显示加载动画,优化体验 if(dataList.isEmpty) { return const Center(child: CircularProgressIndicator()); } return ListView.builder( itemCount: dataList.length, itemBuilder: (BuildContext context, int index) { return Padding( padding: const EdgeInsets.all(8.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text("DNI: ${dataList[index].dni}"), Text("Nombre: ${dataList[index].nombre}"), const Divider(), ], ), ); }); } }
2. 配置资源路径
打开项目根目录的pubspec.yaml文件,在flutter节点下添加资源注册:
flutter: assets: - db/Propuestas.xlsx
内容的提问来源于stack exchange,提问作者Lash
相关产品推荐
相关产品推荐

