自定义函数解决多个数据集中求出某列的平均值
第20章 自定义函数解决多个数据集中求出某列的平均值 
 1. 问题概述 
 写一个自定义数据集函数,能够从多个数据集中求出某个列的平均值 
 该函数的参数为指定数据集名称和列名 
 请自行定义函数的参数类型和参数个数 
 要求:可计算的数据集个数不定,列名由参数指定,也可以求同一个数据集的多个列的平均值,例如ds1有三个列col1\col2\col3,利用该函数可以求出这三个列的平均值;也可以求出ds1的col1\col2和ds2的col1\col2的平均值 
 2. 展现步骤 
 1.写MyDSAvg.java继承润乾报表提供的function类, 实现其中的calculate方法,并返回运算结果 
 2.在customFunctions.properties里做函数登记 
 3. 用法格式: 
 “数据集名字1″,”字段1,字段2,字段3″,”数据集名字2″,”字段1,字段2,字段3″ 
 4.报表模板设计: 
  
 为了检验数据的正确性,第2行和第3行取值对比 
  
 3. 程序代码 
 package api; 
 
 import java.util.ArrayList; 
 
 import com.runqian.base4.util.ReportError; 
 import com.runqian.report4.dataset.DataSet; 
 import com.runqian.report4.model.expression.Expression; 
 import com.runqian.report4.model.expression.Function; 
 import com.runqian.report4.model.expression.Variant2; 
 import com.runqian.report4.usermodel.Context; 
 
 public class MyDSAvg extends Function { 
 private Context context = null; 
 
 public Object calculate(Context context, boolean isInput) { 
 this.context = context; 
 ArrayList result = new ArrayList(); 
 
 if(this.paramList.size()%2==1) 
 throw new ReportError(“该函数需要偶数个参数!”); 
 int count = this.paramList.size(); 
 for(int i=0;i<count/2;i++){ 
 Expression exp = (Expression)this.paramList.get(i*2); 
 String dsName = (String)Variant2.getValue(exp.calculate(context, isInput), false, false); 
 
 exp = (Expression)this.paramList.get(i*2+1); 
 String[] cols = ((String)Variant2.getValue(exp.calculate(context, isInput), false, false)).split(“,”); 
 for(int j=0;j<cols.length;j++){ 
 String col = cols[j]; 
 double avg = getDSAvg(dsName, col); 
 result.add(new Double(avg)); 
 } 
 } 
 return result; 
 } 
 
 public boolean isExtended() { 
 return true
 } 
 
 private double getDSAvg(String dsName, String col) { 
 DataSet ds = context.getDataSet(dsName); 
 int colIndex = ds.getColNo(col); 
 int rowCount = ds.getRowCount(); 
 try{ 
 double amount = 0; 
 for(int i=1;i<=rowCount;i++){ 
 double d = ((Number)ds.getData(i, colIndex)).doubleValue(); 
 amount += d; 
 } 
 return (amount/rowCount); 
 } 
 catch(Exception e){ 
 e.printStackTrace(); 
 return 0; 
 } 
 } 
 }