需实现的接口方法说明如下:
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); } |
下面将以"如何对报表数据进行小计合计"的例子来演示如何用 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> |
4. 重启Smartbi服务,刷新合计小计这张报表就会执行过滤器。
示例代码下载: Sample9_8.rar