iReport : How to process a parameter whose expression class = List and inside that list is another list?

寵の児 提交于 2019-12-19 09:42:32

问题


I have a parameter whose expression class is a List. Inside that List is another list so the data looks something like this.

Class Bean{

String property1
String property2
Long property3
List<BeanDetails> beanDetails
}

Please take note that I'll be passing Bean in a list. (List beans)

1) Is it possible to process and read this type of data in iReport?

2) How are we going to declare it/ define it and use it in iReport?

The report should look like this

Col1    Col2     Col3       Col4              Col5              Col6    
 1     bean.id  bean.name   beanDetail.det1   beanDetail.det2   beanDetail.det3
                            beanDetail.det1   beanDetail.det2   beanDetail.det3
                            beanDetail.det1   beanDetail.det2   beanDetail.det3

 2     bean.id  bean.name   beanDetail.det1   beanDetail.det2   beanDetail.det3
                            beanDetail.det1   beanDetail.det2   beanDetail.det3
                            beanDetail.det1   beanDetail.det2   beanDetail.det3

回答1:


There are multiple solutions to achieve what you need.

  1. Create flat structure of your datasource, as example a List of Map<String,Object>, looping your Bean, BeanDetails example

    List<Map<String,Object>> mapList = new ArrayList<Map<String,Object>>();
    for(Bean bean : yourBeans){
      Map<String,Object> map = new HashMap<String,Object>();
      map.put("col1", bean.getProperty1());
      map.put("col2", bean.getProperty2());
      map.put("col3", bean.getProperty3());
      boolean first = true;
      if (bean.getBeanDetails()==null|| bean.getBeanDetails().size()==0){
        mapList.add(map);
      }else{
       for (BeanDetails bd:bean.getBeanDetails()){
         if (!first){
             map = new HashMap<String,Object>();
             map."col1", "");//or use printWhenExpression != null in jrxml
             ....
         }else{
            first = false;
         }
         map.put("col4",bd.getDet1());
         ....
         mapList.add(map);
      }
     }
    }
    //This now becomes your datasource
    JRMapArrayDataSource datasource = new JRMapArrayDataSource(mapList);
    
  2. Use subreport include a subreport spanning col4 to col6, setup field Bean in main report

    <field name="_THIS" class="com.your.package.Bean"/>
    

    and pass as datasource to the subreport

    <dataSourceExpression><![CDATA[new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($F{_THIS}.getBeanDetails())]]></dataSourceExpression>
    
  3. Create you own JRDataSource (I will not submit the whole class, but only some hints on how this can be done, creating a new class implementing JRDataSource)

    JRDataSource myDatasource = new JRDataSource() {
        //TODO: keep controll of you list of Beans, current Bean and current BeanDetails, using pointers.
        @Override
        public boolean next() throws JRException {
         //TODO: Implement if there are still records, move to next Bean or BeanDetails
         boolean existsRecords = false;
         return existsRecords;
        }
    
        @Override
        public Object getFieldValue(JRField field) throws JRException {
           String name = field.getName();
           //TODO: On the basis of your pointer, current Bean and current BeanDetails, return the value requested.
           return null;
        }
    };
    

Make your choice and have fun!



来源:https://stackoverflow.com/questions/34125526/ireport-how-to-process-a-parameter-whose-expression-class-list-and-inside-th

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!