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

如何用XLFormula_engine计算数据库批量公式及生成向量结果?

使用XLFormula_engine处理数据库中的批量公式与变量计算需求

可以使用XLFormula_engine完美解决你的需求,不管是提取公式变量、批量计算还是处理复合公式,都能通过扩展现有逻辑实现。以下是具体实现方案:

一、提取公式中的变量(生成变量向量)

XLFormula_engine的解析模块会生成抽象语法树(AST),你可以遍历AST提取所有变量引用(即"A""B"这类标识)。示例实现如下:

use xlformula_engine::parse_formula::ast::{AstNode, AstNodeType};

// 遍历AST提取所有变量引用并去重
fn extract_variables(ast: &AstNode) -> Vec<String> {
    let mut variables = Vec::new();
    match &ast.node_type {
        AstNodeType::CellReference(cell_ref) => {
            variables.push(cell_ref.to_string());
        }
        AstNodeType::FunctionCall(_, args) => {
            // 递归处理函数参数中的变量
            for arg in args {
                variables.extend(extract_variables(arg));
            }
        }
        AstNodeType::BinaryOperation(left, _, right) => {
            // 处理二元运算两边的变量
            variables.extend(extract_variables(left));
            variables.extend(extract_variables(right));
        }
        // 其他节点类型可按需扩展
        _ => {}
    }
    // 去重并排序(可选)
    variables.sort_unstable();
    variables.dedup();
    variables
}

二、适配数据库变量值表

将数据库存储的变量值表转换为data_function可查询的缓存结构,避免重复查询数据库:

use std::collections::HashMap;
use xlformula_engine::types;

// 从数据库加载变量值到HashMap(替换为你的实际数据库查询逻辑)
fn load_variables_from_db() -> HashMap<String, types::Value> {
    let mut vars = HashMap::new();
    vars.insert("A".to_string(), types::Value::Number(10.12));
    vars.insert("B".to_string(), types::Value::Number(123.0));
    vars.insert("C".to_string(), types::Value::Number(5.0));
    vars
}

// 基于缓存的data_function实现
let var_map = load_variables_from_db();
let data_function = move |s: String| {
    var_map.get(&s).cloned().unwrap_or(types::Value::Error(types::Error::Value))
};

三、处理复合公式(带依赖的公式)

对于k=a/b、j=if(a>0,a/b,0)这类复合公式,需要先处理依赖顺序(先计算被依赖的公式,再计算依赖它的公式):

  1. 读取公式时记录每个公式的依赖变量(包括其他公式的输出)
  2. 构建依赖图并通过拓扑排序确定计算顺序
  3. 将已计算的公式结果加入变量缓存,供后续公式调用

示例代码片段:

use xlformula_engine::{calculate, parse_formula, NoCustomFunction};

// 从数据库读取的复合公式列表:(公式名称, 公式字符串)
let compound_formulas = vec![
    ("k".to_string(), "=A/B".to_string()),
    ("j".to_string(), "=IF(A>0,k,0)".to_string()),
];

// 初始化变量缓存(包含基础变量)
let mut computed_vars = load_variables_from_db();

// 按依赖顺序计算(实际场景需通过拓扑排序确定顺序)
for (var_name, formula_str) in compound_formulas {
    match parse_formula::parse_string_to_formula(&formula_str, None::<NoCustomFunction>) {
        Ok(formula) => {
            // 构建包含已计算变量的查询函数
            let data_func = |s: String| {
                computed_vars.get(&s).cloned().unwrap_or(types::Value::Error(types::Error::Value))
            };
            // 计算公式结果
            let result = calculate::calculate_formula(formula, Some(&data_func)).unwrap();
            // 将结果加入缓存
            computed_vars.insert(var_name.clone(), result.clone());
            // 提取当前公式的变量向量
            let variables = extract_variables(&formula.ast().unwrap());
            // 输出结果
            println!("公式{} | 变量向量: {:?} | 计算结果: {:?}", var_name, variables, result);
        }
        Err(e) => eprintln!("解析公式{}失败: {}", formula_str, e),
    }
}

四、批量计算并输出向量

结合上述逻辑,批量处理数据库中的所有公式,输出每个公式的变量向量与计算结果:

// 从数据库读取的所有公式列表
let all_formulas = vec![
    "=IF(A>0,B/A,0)".to_string(),
    "=A+B*C".to_string(),
    "=SUM(A,B,C)".to_string(),
];

let var_map = load_variables_from_db();
let data_function = move |s: String| {
    var_map.get(&s).cloned().unwrap_or(types::Value::Error(types::Error::Value))
};

for formula_str in all_formulas {
    match parse_formula::parse_string_to_formula(&formula_str, None::<NoCustomFunction>) {
        Ok(formula) => {
            let variables = extract_variables(&formula.ast().unwrap());
            let result = calculate::calculate_formula(formula, Some(&data_function));
            println!("变量向量: {:?} | 计算结果: {:?}", variables, result);
        }
        Err(e) => eprintln!("解析公式{}失败: {}", formula_str, e),
    }
}

等价库选择

如果需要替代方案,Rust生态中的rust_xlsxwriter也支持公式计算,但XLFormula_engine更专注于独立的公式解析与计算,更适配你的场景。


内容的提问来源于stack exchange,提问作者zetaerre

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 05:55:15