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

后端 未结 1 761
难免孤独
难免孤独 2021-01-14 07:16

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
St         


        
相关标签:
1条回答
  • 2021-01-14 07:44

    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!

    0 讨论(0)
提交回复
热议问题