最近负责某大学的一个实验数据分析系统,涉及到正太分布、物理公式计算。公式展示网上有许多uedior+ 公式插件。公式计算,最开始采用前端输入公式,进行识别计算,引入了guggy.js。但是这个js可参考的代码太少了,官方文档也很简单,用vue导入后实现不了对div的初始化赋值。后面发现了matlab提供jar包,可以引用之后,调外部的matlab引擎计算。

注意事项:1、需要安装的matlab试用版,并根据官方文档,引入了最新的jar,因非maven管理的jar需要按照以下《springboot添加外部jar包及打包》地址配置。2、使用StringWriter流去获取处理值、错误值。

官网链接:https://ww2.mathworks.cn/help/matlab/matlab-engine-api-for-java.html (也是看了好久的文档,才发现这个JavaAPI文档)

public static void main(String[] args) {
    try {
        Future<MatlabEngine> engFuture = MatlabEngine.startMatlabAsync();
        MatlabEngine engine = engFuture.get();
        File file = new File("D:"+File.separator+"Test.txt");
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
            file.createNewFile();
        }
        Writer writer = new FileWriter(file);
        Future<Void> future = engine.evalAsync(
                "qs=758*145.0377\n" +
                        "temp=356\n" +
                        "Ktemp=0.9\n" +
                        "Fk=75\n" +
                        "KFk=1-((1-Ktemp)*(Fk-75)/(temp-75))\n" +
                        "D=89.18/25.4\n" +
                        "t=7.26/25.4\n" +
                        "Ap=3.14159*(D-t)*t\n" +
                        "Ai=3.14159*(D/2-t)^2\n" +
                        "tm=6.973/25.4\n" +
                        "Ki=(D^2+(D-2*tm)^2)/(D^2-(D-2*tm)^2)\n" +
                        "Ti=0.80 \n" +
                        "Ni=0.90 \n" +
                        "qa=Ti*qs*KFk\n" +
                        "qv=Ni*qs*KFk\n" +
                        "Pin1=1/2/(1+Ki+Ki^2)*(-qa+qa*Ki+(-3*qa^2-6*qa^2*Ki-3*qa^2*Ki^2+4*qv^2+4*Ki*qv^2+4*Ki^2*qv^2)^(1/2))\n" +
                        "Pin=Pin1\n" +
                        "Pinm=Pin/145.0377\n" +
                        "Faz=qa*Ap/1000\n" +
                        "Fazk=Faz*4.4497\n" +
                        "Fae=Ai*Pin/1000\n" +
                        "Faek=Fae*4.4497\n" +
                        "Faj=Faz-Fae\n" +
                        "Fajk=Faj*4.4497", writer, writer);
        Scanner scan = new Scanner(new FileInputStream(file));
        while (scan.hasNextLine()) {
            System.out.println(scan.nextLine());
        }
    } catch (ExecutionException | InterruptedException |IOException  e) {
        e.printStackTrace();
    }
}

 

因为异步不能得到及时返回值,需要调本地的matlab其实很慢,最后实现同步调用。

@Override
public Result calculate(String id) {
    final Formula formula = repository.findById(id).orElse(null);
    if (formula != null) {
        if (StringUtils.isNotBlank(formula.getContent())) {
            try {
                MatlabEngine engine = MatlabEngine.startMatlab();
                StringWriter writer = new StringWriter();
                engine.eval(formula.getContent(), writer, writer);
                System.out.println("1String" + writer.toString());
                String sb = writer.toString();
                writer.close();
                return Result.ok().putData(sb);
            } catch (InterruptedException | ExecutionException | IOException e) {
                e.printStackTrace();
                return Result.error("计算失败请确认content公式参数内容正确");
            }
        }
    }
    return Result.error("计算失败请确认content公式参数内容正确");
}