Flutter技术问题:从SQLite自动填充Excel(DTR模板)并预览导出
解决Flutter离线App中SQLite数据导入Excel模板并按周末调整格式的问题
1. 选择并配置Excel操作库
推荐两款适配离线场景的库,按需选择:
excel:轻量开源,适合基础Excel操作,完全免费syncfusion_flutter_xlsio:功能全面,支持复杂格式设置,非商用免费,商用需授权
以excel库为例,先在pubspec.yaml添加依赖:
dependencies: excel: ^2.0.0 path_provider: ^2.0.15 # 用于获取本地文件存储路径 sqflite: ^2.3.0 # 与现有SQLite依赖兼容
2. 准备并读取Excel模板
将你的Excel模板(如template.xlsx)放在assets/excel/目录下,同时在pubspec.yaml配置资源路径:
flutter: assets: - assets/excel/template.xlsx
读取模板的核心代码:
import 'package:excel/excel.dart'; import 'package:flutter/services.dart'; import 'package:path_provider/path_provider.dart'; import 'dart:io'; Future<Excel> loadExcelTemplate() async { // 从assets读取模板文件字节流 ByteData templateData = await rootBundle.load('assets/excel/template.xlsx'); List<int> bytes = templateData.buffer.asUint8List( templateData.offsetInBytes, templateData.lengthInBytes ); // 解析为Excel对象 return Excel.decodeBytes(bytes); }
3. 从SQLite读取目标数据
假设你已有数据模型和SQLite查询逻辑,示例代码如下(替换为你实际的实现):
class Record { final DateTime date; final String content; final double amount; Record({required this.date, required this.content, required this.amount}); } // 从SQLite获取记录(你已实现的逻辑,此处仅作示例) Future<List<Record>> fetchRecordsFromSQLite() async { // 替换为你实际的SQLite查询代码 return [ Record(date: DateTime(2024,5,18), content: "日常记录", amount: 120.5), Record(date: DateTime(2024,5,19), content: "周六加班", amount: 200.0), Record(date: DateTime(2024,5,20), content: "周日休息", amount: 0.0), ]; }
4. 插入数据并设置周末格式
核心逻辑:遍历SQLite数据,定位模板单元格插入内容,判断日期是否为周六/周日,调整单元格样式(如背景色)。
Future<void> exportToExcel() async { // 加载模板 Excel excel = await loadExcelTemplate(); // 获取模板目标工作表(假设数据插入到第一个sheet) Sheet targetSheet = excel['Sheet1']; // 读取SQLite数据 List<Record> records = await fetchRecordsFromSQLite(); // 假设模板从第3行开始插入数据(第1-2行为表头) int startRow = 3; for (int i = 0; i < records.length; i++) { Record record = records[i]; int currentRow = startRow + i; // 插入数据到对应列(示例:A列日期、B列内容、C列金额) targetSheet.cell(CellIndex.indexByColumnRow(columnIndex: 0, rowIndex: currentRow)).value = record.date.toString().split(' ')[0]; targetSheet.cell(CellIndex.indexByColumnRow(columnIndex: 1, rowIndex: currentRow)).value = record.content; targetSheet.cell(CellIndex.indexByColumnRow(columnIndex: 2, rowIndex: currentRow)).value = record.amount; // 判断是否为周六(weekday=6)或周日(weekday=7) bool isWeekend = record.date.weekday == 6 || record.date.weekday == 7; if (isWeekend) { // 设置周末行单元格背景色为浅灰色 final grayColor = HexColor.fromHex('#F0F0F0'); targetSheet.cell(CellIndex.indexByColumnRow(columnIndex: 0, rowIndex: currentRow)).cellStyle.backgroundColor = grayColor; targetSheet.cell(CellIndex.indexByColumnRow(columnIndex: 1, rowIndex: currentRow)).cellStyle.backgroundColor = grayColor; targetSheet.cell(CellIndex.indexByColumnRow(columnIndex: 2, rowIndex: currentRow)).cellStyle.backgroundColor = grayColor; } } // 保存修改后的Excel到本地 Directory docDir = await getApplicationDocumentsDirectory(); String savePath = "${docDir.path}/exported_records.xlsx"; File saveFile = File(savePath); await saveFile.writeAsBytes(excel.encode()!); }
关键注意事项
- 模板的行列索引需根据实际文件调整,确保数据插入到正确位置
- 若使用
syncfusion_flutter_xlsio,格式设置更灵活,示例设置背景色代码:worksheet.getRangeByIndex(currentRow, 1).cellStyle.backColor = const Color(0xFFF0F0F0); - 需配置本地文件读写权限:Android在
AndroidManifest.xml添加<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>;iOS在Info.plist添加NSDocumentFolderUsageDescription说明
内容的提问来源于stack exchange,提问作者user20814004
相关产品推荐
相关产品推荐

