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

求推荐可在Dart中计算Excel公式的类库(仅用IF/IFERROR函数)

在Dart中计算Excel公式的可行方案

你可以通过以下两种方式实现需求:

1. 使用现成类库(推荐)

dart_excel是成熟的Dart库,支持解析和计算包括IF、IFERROR在内的常见Excel公式。

实现步骤:

  • 在pubspec.yaml中添加依赖:
dependencies:
  dart_excel: ^2.0.0 # 请使用pub上的最新版本
  • 编写计算代码:
import 'package:dart_excel/dart_excel.dart';

void main() {
  final workbook = Workbook();
  final worksheet = workbook.worksheets[0];

  // 写入目标公式到单元格
  worksheet.getRangeByName('A1').setFormula('0.75*IF(4=1,1,0)+0.25*2501/4');
  
  // 触发公式计算
  workbook.calculateFormula();
  
  // 获取计算结果
  final result = worksheet.getRangeByName('A1').value;
  print('计算结果:$result'); // 输出 156.3125

  // 测试IFERROR函数
  worksheet.getRangeByName('A2').setFormula('IFERROR(1/0, "计算出错")');
  workbook.calculateFormula();
  print('IFERROR测试:${worksheet.getRangeByName('A2').value}'); // 输出 计算出错

  workbook.dispose();
}

2. 手动实现轻量解析(仅针对IF/IFERROR)

如果只需要支持IF和IFERROR,可以自己写简单解析逻辑,避免引入大库:

import 'package:expr/expr.dart'; // 用于处理数学表达式计算

double calculateExcelFormula(String formula) {
  // 处理IF函数
  while (formula.contains('IF(')) {
    final start = formula.indexOf('IF(');
    int end = start + 3;
    int bracketDepth = 1;
    // 匹配闭合括号
    while (bracketDepth > 0 && end < formula.length) {
      if (formula[end] == '(') bracketDepth++;
      if (formula[end] == ')') bracketDepth--;
      end++;
    }
    final ifBody = formula.substring(start + 3, end - 1);
    final params = splitParams(ifBody);
    final condition = params[0];
    final trueVal = params[1];
    final falseVal = params[2];

    // 判断条件是否成立
    final condResult = evaluateCondition(condition);
    // 替换IF为对应值
    formula = formula.replaceRange(start, end, condResult ? trueVal : falseVal);
  }

  // 处理IFERROR函数
  while (formula.contains('IFERROR(')) {
    final start = formula.indexOf('IFERROR(');
    int end = start + 8;
    int bracketDepth = 1;
    while (bracketDepth > 0 && end < formula.length) {
      if (formula[end] == '(') bracketDepth++;
      if (formula[end] == ')') bracketDepth--;
      end++;
    }
    final ifErrBody = formula.substring(start + 8, end - 1);
    final params = splitParams(ifErrBody);
    final expr = params[0];
    final errVal = params[1];

    try {
      // 尝试计算表达式
      final evalResult = Expr.evaluate(expr);
      formula = formula.replaceRange(start, end, evalResult.toString());
    } catch (_) {
      // 计算出错时替换为错误值
      formula = formula.replaceRange(start, end, errVal);
    }
  }

  // 计算最终数学表达式
  return Expr.evaluate(formula);
}

// 拆分函数参数(忽略括号内的逗号)
List<String> splitParams(String content) {
  final params = <String>[];
  int bracketDepth = 0;
  int start = 0;
  for (int i = 0; i < content.length; i++) {
    if (content[i] == '(') bracketDepth++;
    if (content[i] == ')') bracketDepth--;
    if (content[i] == ',' && bracketDepth == 0) {
      params.add(content.substring(start, i).trim());
      start = i + 1;
    }
  }
  params.add(content.substring(start).trim());
  return params;
}

// 计算条件表达式(支持=、>、<等基础判断)
bool evaluateCondition(String condition) {
  if (condition.contains('=')) {
    final parts = condition.split('=').map((p) => p.trim()).toList();
    return double.parse(parts[0]) == double.parse(parts[1]);
  }
  if (condition.contains('>')) {
    final parts = condition.split('>').map((p) => p.trim()).toList();
    return double.parse(parts[0]) > double.parse(parts[1]);
  }
  if (condition.contains('<')) {
    final parts = condition.split('<').map((p) => p.trim()).toList();
    return double.parse(parts[0]) < double.parse(parts[1]);
  }
  return false;
}

void main() {
  final targetFormula = '0.75*IF(4=1,1,0)+0.25*2501/4';
  final result = calculateExcelFormula(targetFormula);
  print(result); // 输出 156.3125
}

注:手动实现的逻辑仅适配你提到的IF和IFERROR,后续若需扩展更多函数,仍推荐使用现成类库。

内容的提问来源于stack exchange,提问作者André Pereira

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 05:05:30