You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.01 17:43:11