1、简介

用户对报表数据的处理存在各种特殊需求,如增加报表的行或列、对报表中的数据进行修改、对报表中的数据进行合计等二次加工。 系统提供两种方式来响应用户的这类特殊需求:一种是在报表宏中通过 JavaScript API 来修改报表的内容。另一种则是用 Java 开发一个"报表数据过滤器类"来完成,其原理类似Java web开发中的filter,在刷新报表数据的时候,会执行相应的过滤器类。为实现报表数据过滤的要求,系统提供接口类 ISDKGridDataFilter 供实现此类扩展开发。

文档目录:

需实现的接口方法说明如下:

  • accept:用于判断该过滤器是否生效。例如我们可能只针对某个报表才激活该过滤器,可以通过reportName或者reportId去判断。
  • doFilter:用于处理报表数据。
  • doFilterSetPageRows :用于设置过滤后的每页显示行数,参数rows 是过滤前的行数。
  • doFilterGetAllRows 用于设置过滤后的总行数,参数rows 是过滤前的总行数。
 public interface ISDKGridDataFilter {
	void doFilter(ISDKGridData gridData);
   	int doFilterSetPageRows(int rows);
   	int doFilterGetAllRows(int rows);
    public boolean accept(String dataSourceId,String bizViewId,String reportId,String reportName);
}


2、示例说明

下面将以"如何对报表数据进行小计合计"的例子来演示如何用 Java 开发一个报表数据过滤器类。(仅演示ISDKGridDataFilter实现,不支持跨页小计合计)


3、操作步骤

  1. 打开服务器部署文件smartbi.war,解压后将smartbi.war\WEB-INF\lib\目录下的 smartbi-FreeQuery.jar、 smartbi-Common.jar 包加入到插件包项目的classpath中去。
  2. 撰写报表过滤器类GridDataFilterDemoA.java,实现接口 ISDKGridDataFilter
package bof.ext.sample9_8;
import java.util.ArrayList;
import java.util.List;
import smartbi.freequery.extension.ISDKGridData;
import smartbi.freequery.extension.ISDKGridDataFilter;
import smartbi.freequery.querydata.CellData;
import smartbi.freequery.report.SimpleReportBO;
/**
 * 假设有一张报表,name = "小计合计";<BR>
 * 包含有4列,分别是:产品目录名称、产品名称、数量、运费;<BR>
 * 在报表中,通过设置表格属性,使得靠左边的两列自动合并单元格; 要求:加入合计和小计的功能。数量和运费都是求和。
 */
public class GridDataFilterDemoA implements ISDKGridDataFilter {
	class NamePair {
		int index;
		List<CellData> row;
	}
	public void doFilter(ISDKGridData gridData) {
		List<List<CellData>> rows = gridData.getData();
		String lastCat = null;
		String lastProduct = null;
		List<NamePair> newRows = new ArrayList<NamePair>();
		for (int i = 0; i < rows.size(); i++) {
			List<CellData> row = rows.get(i);
			String cat = row.get(0).getDisplayValue();
			String product = row.get(1).getDisplayValue();
			if (lastCat == null)
				lastCat = cat;
			if (lastProduct == null)
				lastProduct = product;
			if ("小计".equals(cat)) {
				lastCat = null;
				continue;
			}
			if (!lastCat.equals(cat)) {
				// 每类小计
				NamePair pair = new NamePair();
				pair.index = i;
				pair.row = new ArrayList<CellData>();
				newRows.add(pair);
				lastCat = cat;
			}
			if (i == rows.size() - 1) {
				// 每页小计
				NamePair lastPair = new NamePair();
				lastPair.index = rows.size();
				lastPair.row = new ArrayList<CellData>();
				newRows.add(lastPair);
			}
		}
		for (int i = newRows.size() - 1; i >= 0; i--) {
			NamePair pair = newRows.get(i);
			int endRowIndex = pair.index - 1;
			int startRowIndex = 0;
			if (i > 0) {
				startRowIndex = ((NamePair) newRows.get(i - 1)).index;
			}
			for (int k = 0; k <= 1; k++) { // 设置前面两列
				CellData cell = new CellData();
				pair.row.add(cell);
				cell.setStringValue("小计");
				cell.setDisplayValue("小计");
			}
			for (int col = 2; col < gridData.getColumnsCount(); col++) {
				double total = 0;
				CellData tmpData = new CellData();
				pair.row.add(tmpData);
				for (int m = startRowIndex; m <= endRowIndex; m++) {
					CellData tmpCell = gridData.get(m, col);
					if (tmpCell.getType().name().equals("INTEGER")) {
						total += tmpCell.getIntValue();
						if (m == endRowIndex) {
							tmpData.setIntValue((int) total);
							tmpData.setDisplayValue(String.valueOf((int) total));
						}
					} else if (tmpCell.getType().name().equals("DOUBLE")) {
						total += tmpCell.getDoubleValue();
						total = (double) Math.round(total * 100) / 100;
						if (m == endRowIndex) {
							tmpData.setDoubleValue(total);
							tmpData.setDisplayValue(String
									.valueOf((double) total));
						}
					}
				}
			}
			rows.add(pair.index, pair.row);
			System.out.println(rows);
		}
	}
	/* 该过滤器只针对小计合计这张报表 */
	public boolean accept(String dataSourceId, String bizViewId,
			String reportId, String reportName) {
		System.out.println("dataSourceId:" + dataSourceId + "  bizViewId:"
				+ bizViewId + "   reportId:" + reportId + "  reportName:"
				+ reportName);
		if ("报表数据过滤器分析".equalsIgnoreCase(reportName))
			return true;
		else
			return false;
	}
	public int doFilterGetAllRows(int rows) {
		return rows;
	}
	public int doFilterSetPageRows(int rows) {
		return rows;
	}
	@Override
	public void doFilterClientId(String arg0) {
		// TODO Auto-generated method stub
	}
	@Override
	public void doFilterSetBo(SimpleReportBO arg0) {
		// TODO Auto-generated method stub
	}
}

 

3. 修改Smartbi服务器配置文件smartbi-config.xml,在<freequery></freequery>节点间加入以下代码:

<gridData-filter-chain>
    <filter>bof.ext.sample9_8.GridDataFilterDemoA</filter>
</gridData-filter-chain>
    • 注:在<gridData-filter-chain>中可以包括多个<filter>。

4. 重启Smartbi服务,刷新合计小计这张报表就会执行过滤器。

 

4、示例执行效果

5、示例代码下载

示例代码下载: Sample9_8.rar