如何实现报表过滤面板、表头过滤等常规过滤原创
金蝶云社区-吴锐雄
吴锐雄
27人赞赏了该文章 9243次浏览 未经作者许可,禁止转载编辑于2022年12月15日 16:36:39

关键词:报表

一、需求

不少伙伴反馈,需要给报表做过滤,有些需要做表头下拉风格过滤,有些只需要表头常规规律,有些需要做过滤面板过滤。

写一篇文章整合一些常规的过滤。


二、思路与方案

(1)创建一张单据,为接下来的报表 提供数据源

(2)创建报表,注册2个插件

(3)报表查询插件,添加常规列和下拉列

(4)报表页面插件,启用过滤和排序

(5)报表页面插件,为下拉列添加一些自定义的列头过滤选项

(6)报表查询插件,查询数据,把列头和过滤面板上的过滤条件添加到查询条件中


三、实现过程

(1)创建一个单据,一个基础资料,为接下来的报表 提供数据源

image.png

image.png

image.png

image.png



(2)创建报表,注册插件

Image_20211008173956.png

Image_20211008174026.png




(3)在报表取数插件中,添加2个常规列,1个下拉列,

注意:添加下拉列时,列的ReportColumn类型是ComboReportColumn,fieldType是ReportColumn.TYPE_COMBO

@Override
public List<AbstractReportColumn> getColumns(List<AbstractReportColumn> columns) throws Throwable {
    // 一共添加3列,其中2列是常规的列
    columns.add(createReportColumn("billno", "text", "水果单据编号"));
    columns.add(createReportColumn("proname", "text", "水果产地"));
    // 1列是下拉框风格的表头过滤的列
    columns.add(createComboReportColumn("fruitname", ReportColumn.TYPE_COMBO, "水果名称"));
    return columns;
}

public ReportColumn createReportColumn(String fieldKey, String fieldType, String caption) {
    ReportColumn column = new ReportColumn();
    column.setFieldKey(fieldKey);
    column.setFieldType(fieldType);
    column.setCaption(new LocaleString(caption));
    return column;
}

public ComboReportColumn createComboReportColumn(String fieldKey, String fieldType, String caption) {
    ComboReportColumn column = new ComboReportColumn();
    column.setFieldKey(fieldKey);
    column.setFieldType(fieldType);
    column.setCaption(new LocaleString(caption));
    return column;
}


(4)在报表取数插件中,查询数据,把列头和过滤面板上的过滤条件添加到查询条件中

在报表查询插件中,如果传入了列头的过滤和过滤面板的过滤参数,就把过滤参数转换成QFilter,然后查询数据时用上。

注意:这里的过滤有两种

filterInfo.getFilterItem()是取过滤面板上的过滤控件的过滤参数,里面的参数是过滤控件的标识

filterInfo.getTableHeadFilterItems()是取表头过滤的过滤参数,取出来是一个List表,只要是列启用了过滤,并且有配置参数,就会在这里List里面。

@Override
public DataSet query(ReportQueryParam queryParam, Object o) throws Throwable {

    // 获取过滤条件
    FilterInfo filterInfo = queryParam.getFilter();
    // 过滤面板的过滤参数
    FilterItemInfo filter = filterInfo.getFilterItem("wjkd_area");
    // 表头的过滤参数
    List<FilterItemInfo> tableHeadFilters = filterInfo.getTableHeadFilterItems();

    QFilter resultFilter[] = new QFilter[tableHeadFilters.size()];
    // 用过滤面板的过滤参数,构建QFilter
    if (filter != null && filter.getValue() instanceof DynamicObject) {
        DynamicObject dynamicObject = (DynamicObject) filter.getValue();
        String strName = dynamicObject.get("name").toString();
        resultFilter = new QFilter[tableHeadFilters.size() + 1];
        resultFilter[resultFilter.length - 1] = new QFilter("wjkd_pro_area.name", QCP.like, strName);
    }

    for (int i = 0; i < tableHeadFilters.size(); i++) {
        FilterItemInfo filterItemInfo = tableHeadFilters.get(i);
        if ("fruitname".equals(filterItemInfo.getPropName())) {
            resultFilter[i] = filterItemInfoToQFilter("wjkd_fruit_en.wjkd_fruit_name", filterItemInfo);
        }
        if ("proname".equals(filterItemInfo.getPropName())) {
            resultFilter[i] = filterItemInfoToQFilter("wjkd_pro_area.name", filterItemInfo);
        }
        if ("billno".equals(filterItemInfo.getPropName())) {
            resultFilter[i] = filterItemInfoToQFilter("billno", filterItemInfo);
        }
    }

    // 查询水果单据
    DataSet fruitDataSet = QueryServiceHelper.queryDataSet(this.getClass().getName(), "wjkd_fruit_bill",
            "id, billno, wjkd_pro_area.name as proname, wjkd_fruit_en.wjkd_fruit_name as fruitname",
            resultFilter, null);

    return fruitDataSet;

}

public QFilter filterItemInfoToQFilter(String property, FilterItemInfo filterItemInfo) {
    QFilter qFilter = new QFilter(property, filterItemInfo.getCompareType(), filterItemInfo.getValue());
    return qFilter;
}


(5)在报表页面插件中,启用过滤和排序

把第(3)步添加的列,启用排序和过滤

@Override
public void setSortAndFilter(List<SortAndFilterEvent> list) {
    super.setSortAndFilter(list);
    // 开启列头过滤
    for (SortAndFilterEvent event : list) {
        if ("billno".equals(event.getColumnName())
                || "proname".equals(event.getColumnName())
                || "fruitname".equals(event.getColumnName())) {
            event.setSort(true);
            event.setFilter(true);
        }
    }
}



6)为下拉列添加一些自定义的列头过滤选项

beforeCreateFilterInfo事件:自定义列头过滤,每一个启用了过滤的列都会调用一遍这个事件。

判断当前列是否为下拉列kdec_fruits,如果是,就从数据库中获取 水果名称,然后添加到下拉列的选项中

注意:这个构造过程比较复杂。

最外层是Map表,里面2个List表,List表的元素又是Map表,一共3层结构

@Override
public void beforeCreateFilterInfo(CreateFilterInfoEvent event) {

    // 为水果名称这个下拉列,添加一些自定义的列头过滤选项
    if ("fruitname".equals(event.getFieldKey())) {
        ArrayList<HashMap> filterItemList = new ArrayList();
        HashMap filterItem = new HashMap();
        filterItem.put("name", new LocaleString("在……中"));
        filterItem.put("value", "");
        filterItem.put("inputCtlType", 1);
        filterItem.put("id", "17");
        filterItemList.add(filterItem);

        ArrayList<HashMap> comboItemList = new ArrayList();
        DynamicObject[] dynamicObjects = BusinessDataServiceHelper.load("wjkd_fruit_bill",
                "id, billno, wjkd_fruit_en.wjkd_fruit_name", null);
        for (DynamicObject dynamicObject : dynamicObjects) {
            for (DynamicObject entryEntityItem : dynamicObject.getDynamicObjectCollection("wjkd_fruit_en")) {
                HashMap comboItem = new HashMap();
                comboItem.put("name", new LocaleString(entryEntityItem.getString("wjkd_fruit_name")));
                comboItem.put("value", entryEntityItem.getString("wjkd_fruit_name"));
                comboItem.put("id", "17");
                comboItemList.add(comboItem);
            }
        }

        Map filterInfoMap = new HashMap();
        filterInfoMap.put("filterItems", filterItemList);
        filterInfoMap.put("comboItems", comboItemList);
        event.setFilterInfo(filterInfoMap);
        event.setCancel(true);
    }

}


过滤之后的效果

image.png


四、效果图

image.png

image.png


过滤条件为 过滤面板-地区“广东”,表头过滤-水果名称“甘蔗”,过滤之后的效果:

image.png


五、开发环境版本


image.png

六、参考资料

【开发平台】指导手册

学习成长中心

报表介绍

报表属性

报表表格列头过滤



七、附件

附件包含补丁包和java源代码。

补丁包包含jar包和元数据包,请在mc中安装补丁包,如果是在开发平台里面直接导入,那么jar包不生效,需要复制代码,手动添加插件。

附件里的案例和本文的一些截图,在界面上略有差异,但实现方式是一致的。


java源代码已上传至附件:

报表页面插件,ComboFilterReportFormPlugin.java 

报表查询插件,ComboFilterReportListDataPlugin.java 



赞 27