解析决策表需要用到SpreadsheetCompiler类。
简单的写一个方法并输出解析后的规则。
/**
* 将xls决策表解析为普通规则文件
* @throws IOException
*/
public File ruleTableConvertDRL(String ruleTablePath) throws IOException{
SpreadsheetCompiler compiler = new SpreadsheetCompiler();
File inFile = new File(ruleTablePath);
File outFile = new File("e://outFile.txt");
InputStream xlsStream = null;
OutputStream fos = null;
OutputStreamWriter osw = null;
BufferedWriter out = null;
try {
xlsStream = new FileInputStream(inFile);
String strRule = compiler.compile(xlsStream, InputType.XLS);
fos = new FileOutputStream(outFile);
osw = new OutputStreamWriter(fos);
out = new BufferedWriter(osw);
out.write(strRule);
out.flush();
System.out.println("\n" + strRule);
} catch (IOException e) {
throw new IOException("没找到文件或写入文件错误");
}finally{
xlsStream.close();
fos.close();
osw.close();
out.close();
}
return outFile;
}
决策表:
解析后的规则文件:
package com.sinosoft.common.drools;
//generated from Decision Table
import com.sinosoft.ecif.scoreforgift.schema.model.FinalScore;
import com.sinosoft.ecif.scoreforgift.schema.model.ScoreInfo;
function void test(){
System.out.println("System.out.println()");
}
// rule values at B11, header at B6
rule "Fc_11"
when
$finalScore:FinalScore(years == "0")
then
$finalScore.setScore($finalScore.getScore()+100);
end
// rule values at B12, header at B6
rule "Fc_12"
when
$finalScore:FinalScore(years == "1", arglossRatio>=0,arglossRatio<20)
then
$finalScore.setScore($finalScore.getScore()+50);
end
// rule values at B13, header at B6
rule "Fc_13"
when
$finalScore:FinalScore(years == "1", arglossRatio>=20,arglossRatio<50)
then
$finalScore.setScore($finalScore.getScore()+30);
end
// rule values at B14, header at B6
rule "Fc_14"
when
$finalScore:FinalScore(years == "1", arglossRatio>=50,arglossRatio<101)
then
$finalScore.setScore($finalScore.getScore()+0);
end
// rule values at B15, header at B6
rule "Fc_15"
when
$finalScore:FinalScore(years == "2", arglossRatio>=0,arglossRatio<20)
then
$finalScore.setScore($finalScore.getScore()+100);
end
// rule values at B16, header at B6
rule "Fc_16"
when
$finalScore:FinalScore(years == "2", arglossRatio>=20,arglossRatio<50)
then
$finalScore.setScore($finalScore.getScore()+60);
end
// rule values at B17, header at B6
rule "Fc_17"
when
$finalScore:FinalScore(years == "2", arglossRatio>=50,arglossRatio<101)
then
$finalScore.setScore($finalScore.getScore()+0);
end
// rule values at B18, header at B6
rule "Fc_18"
when
$finalScore:FinalScore(years == "3", arglossRatio>=0,arglossRatio<20)
then
$finalScore.setScore($finalScore.getScore()+150);
end
// rule values at B19, header at B6
rule "Fc_19"
when
$finalScore:FinalScore(years == "3", arglossRatio>=20,arglossRatio<50)
then
$finalScore.setScore($finalScore.getScore()+90);
end
// rule values at B20, header at B6
rule "Fc_20"
when
$finalScore:FinalScore(years == "3", arglossRatio>=50,arglossRatio<101)
then
$finalScore.setScore($finalScore.getScore()+0);
end
说一下我在编辑决策表时遇到的问题:
1、RuleTable之前对决策表的声明中,最后一行的声明不能合并单元格,否则,此声明之前的所有声明都不会被解析。
如我的例子中,最后一个声明是第四行的functions,functions的方法体必须在一个单元格中,不能向后合并单元格。
2、ACTION列中,如果没有对象类型声明,则执行体的句末必须加上分号“;”,如果有对象类型声明,则可以不加。
如我的例子中,如果第8行的ACTION列中没有声明$finalScore,则下面的执行体必须加上分号,否则会报语法错误。
3、注意解析后的规则中的条件部分,years=="3",arglossRadio>=50,arglossRadio<101.用值替代的方法,显示的就是数字,用简单的单元值代入,显示的是字符串,但却不影响程序的正常运行。
4、RuleSet对应的就是drl文件中的package。
5、drools6需要高版本的poi依赖包,我用的是poi-3.5,一直提示没有isInRange方法,换做poi-3.9解决。