动态Sheet扩展

编辑
  • 文档创建者:秃破天际
  • 浏览次数:4200次
  • 编辑次数:6次
  • 最近更新:Carly 于 2019-08-22
  • 1. 描述

    使用场景:我们在某些情况下需要做一些类似“每个子公司/员工/产品/每天/每月一个 sheet”等等的,需要让 cpt 按照某种规律,动态的展现多个 sheet。

    技术要求:具备基础的 Java 开发能力,了解FR的插件开发流程

    模板制作准备:

    1)安装插件:动态 sheet 扩展接口插件V9.0版本  动态 sheet 扩展接口插件 V10.0 版本

    2)实现插件中的接口——开发对应的方案插件


    2. 接口

    接口介绍:


    package com.tptj.plugin.hg.fun;
    import java.util.List;
    import java.util.Map;
    import com.fr.base.TableData;
    import com.fr.stable.fun.mark.Mutable;
    import com.fr.stable.script.CalculatorProvider;
    import com.tptj.plugin.hg.bean.ExpandRequest;
    public interface ExpandProvider extends Mutable {
     
    /**
    * 此次预览是否使用扩展方案
    * @param parameters  前方传过来的全部参数
    * @param bookpath    模板的路径
    * @return 是否使用扩展方案
    */
    public boolean accept( Map<String,Object> parameters, String bookpath );
    /**
    * 生成所有要扩展的sheet请求,程序就是根据你的请求进行扩展的
    * @param parameters 此次模板计算用到的全部参数
    * @param resources该模板的全部数据集<数据集名,数据集对象>
    * @param sheetNames 初始情况该模板的各个sheet名
    * @param cal此次计算用到的算子
    * @return扩展请求的列表
    */
    public List<ExpandRequest> getExpand( Map<String,Object> parameters, Map<String,TableData> resources,
    List<String> sheetNames, CalculatorProvider cal );
    /**
    * 重新计算数据集的克隆对象:默认已经简单的实现了一个对数据查询的克隆,其他数据集或者一些特殊复杂的数据查询的克隆请自己根据自己的业务进行实现
    * @param old原来的数据集
    * @param params需要用于动态重计算的参数表(不是改数据集的全部参数,而仅仅是扩展需要动态改变的部分,来源于扩展请求)
    * @param cal计算用的算子
    * @param sheetName当前的sheet名(非原始sheet名,是扩展后的sheet名,主要用于重命名参数的)
    * @return 克隆得到的新数据集
    */
    public TableData cloneDS( TableData old, Map<String,Object> params, CalculatorProvider cal, String sheetName );
    String XML_TAG = "ExpandProvider";
        int CURRENT_LEVEL = 1;

    我们插件中只需要实现前两个方法,数据集克隆的方法默认是不需要实现的,除非你使用的数据集本身没有实现克隆的功能(FR 本身的数据集都实现了),才需要单独自己克隆


    package com.tptj.plugin.hg.impl;
    import java.util.Map;
    import com.fr.base.TableData;
    import com.fr.stable.fun.impl.AbstractProvider;
    import com.fr.stable.fun.mark.API;
    import com.fr.stable.script.CalculatorProvider;
    import com.tptj.plugin.hg.fun.ExpandProvider;
    @API(level = ExpandProvider.CURRENT_LEVEL)
    public abstract class AbstractExpandProvider extends AbstractProvider implements ExpandProvider {
    public int currentAPILevel() {
            return CURRENT_LEVEL;
        }
        public String mark4Provider() {
            return getClass().getName();
        }
        
        public TableData cloneDS( TableData old, Map<String,Object> params, CalculatorProvider cal, String sheetName ){
        try{
        return (TableData)old.clone();
        }catch(Exception e){
       
        }
        return old;
        }
    }

    实现的 demo——FRdemo 数据源中销量表,对每个销售员单独用一个 sheet 展现(你自己做的插件一定不要思维定式,可以自己总结规律多个模板用一个扩展方案的)

    注:下面的代码可根据实际情况进行修改。


    package com.tptj.plugin.hg.autosheet.rgt;
    import java.net.URLEncoder;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    import com.fr.base.FRContext;
    import com.fr.base.TableData;
    import com.fr.stable.script.CalculatorProvider;
    import com.tptj.plugin.hg.bean.ExpandRequest;
    import com.tptj.plugin.hg.bean.ExpandSheet;
    import com.tptj.plugin.hg.impl.AbstractExpandProvider;
    //我们要做的就是每个销售员单独一个sheet
    public class Demo extends AbstractExpandProvider {
    @Override
    public boolean accept( Map<String,Object> parameters, String bookpath ) {
    //demo方案只对demo.cpt生效,若多个方案都满足,则只执行最先匹配的方案,所以原则上不要多个方案同时生效
    return "demo.cpt".equals(bookpath) || "/demo.cpt".equals(bookpath);
    }
    /**
    * 从参数表中,获取需要扩展的销售员的数组
    * @param parameters
    * @return
    */
    private String[] getSellers( Map<String, Object> parameters ){
    try{
    Object val =  parameters.get(URLEncoder.encode("销售员","utf-8"));
    if( !(val instanceof String) ){
    return new String[0];
    }
    String vstr = val.toString();
    String[] sellers = new String[]{vstr};
    if( vstr.indexOf(",")!=-1){
    sellers = vstr.split(",");
    }
    return sellers;
    }catch(Exception e){
    FRContext.getLogger().error("获取销售员出错!", e);
    }
    return new String[0];
    }
    @Override
    public List<ExpandRequest> getExpand(
    Map<String, Object> parameters, Map<String, TableData> resources, 
    List<String> sheetNames, CalculatorProvider cal ) {
    List<ExpandRequest> result = new ArrayList<ExpandRequest>();
    try{
    //前端传递过来的参数是被编码过的,所以这里需要解码比较一下,并生成销售员的数组
    String[] sellers = getSellers(parameters);
    //ExpandRequest就是定义需要对cpt的哪个sheet进行扩展
    //此例中我们对demo.cpt中名为sheet1的sheet进行扩展
    ExpandRequest request = new ExpandRequest("sheet1");
    for( String seller : sellers  ){
    //每一个销售员定义扩展一个sheet
    //使用销售员的名字作为sheet名
    ExpandSheet sheet = new ExpandSheet( seller );
    //定义这个扩展sheet的数据集需要用什么参数值重新计算
    //将要数据集添加到当前的扩展记录sheet中
    Map<String, Object> nparams = new HashMap<String, Object>();
    nparams.put("销售员", seller);
    sheet.addDatasource("销量", nparams);
    //对原sheet记录一次扩展:表示这个sheet是用sheet1扩展的
    request.addExpandSheet(sheet);
    }
    //如果要对多个原有的sheet进行扩展~就添加多个
    result.add(request);
    }catch(Exception e){}
    return result;
    }
    }

    方案需要注册到 XML 里面


    <dependence>
    <Item key="com.tptj.plugin.hg.autosheet" type="plugin"/>
    </dependence>
    <extra-report>
    <ExpandProvider class="com.tptj.plugin.hg.autosheet.rgt.Demo"/>
    </extra-report>

    编译打包成插件安装

    安装插件后,新建模板如下:

    注:已完成模板请点击下载:demo.cpt

    222


    222

    下面是重点:

    所有的参数控件(提示框和按钮这种跟查询无关不算),都需要在初始化事件调用一个 JS

    FR.ASSubmit.addPWidget(this);

    原有自动生成那个查询控件需要删掉,重新用一个按钮执行查询,按钮的点击事件调用 JS 为:

    FR.ASSubmit.addSButton(this,doSearchAction);

    doSearchAction 是定义在事件的参数列表里面的,值为公式:=$doSearchAction

    222

    到此模板制作就完成了,预览查询即可

    222

    选择一组销售,然后点查询:

    222

    222

    完成了!


    附件列表


    主题: 报表应用
    标签: 暂无标签
    如果您认为本文档还有待完善,请编辑

    文档内容仅供参考,如果你需要获取更多帮助,付费/准付费客户请咨询帆软技术支持
    关于技术问题,您还可以前往帆软社区,点击顶部搜索框旁边的提问按钮
    若您还有其他非技术类问题,可以联系帆软传说哥(qq:1745114201

    此页面有帮助吗?只是浏览 [ 去社区提问 ]