iReport:如何处理表达式 class = List 且该列表内是另一个列表的参数?
iReport : How to process a parameter whose expression class = List and inside that list is another list?
我有一个参数,其表达式 class 是一个列表。在该列表中是另一个列表,因此数据看起来像这样。
Class Bean{
String property1
String property2
Long property3
List<BeanDetails> beanDetails
}
请注意,我将在列表中传递 Bean。 (列出豆子)
1) iReport中是否可以处理和读取此类数据?
2) 我们如何声明/定义它并在 iReport 中使用它?
报告应如下所示
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
有多种解决方案可以满足您的需求。
创建数据源的 平面 结构,例如 Map<String,Object>
的 List
,循环 Bean
, BeanDetails
例子
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);
使用子报表包含一个跨越col4到col6的子报表,在主报表
中设置字段Bean
<field name="_THIS" class="com.your.package.Bean"/>
并作为数据源传递给子报表
<dataSourceExpression><![CDATA[new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($F{_THIS}.getBeanDetails())]]></dataSourceExpression>
创建您自己的 JRDataSource(我不会提交整个 class,但只会提供有关如何完成此操作的一些提示,创建一个新 class 实施 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;
}
};
做出你的选择,玩得开心!
我有一个参数,其表达式 class 是一个列表。在该列表中是另一个列表,因此数据看起来像这样。
Class Bean{
String property1
String property2
Long property3
List<BeanDetails> beanDetails
}
请注意,我将在列表中传递 Bean。 (列出豆子)
1) iReport中是否可以处理和读取此类数据?
2) 我们如何声明/定义它并在 iReport 中使用它?
报告应如下所示
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
有多种解决方案可以满足您的需求。
创建数据源的 平面 结构,例如
Map<String,Object>
的List
,循环Bean
,BeanDetails
例子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);
使用子报表包含一个跨越col4到col6的子报表,在主报表
中设置字段Bean
<field name="_THIS" class="com.your.package.Bean"/>
并作为数据源传递给子报表
<dataSourceExpression><![CDATA[new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($F{_THIS}.getBeanDetails())]]></dataSourceExpression>
创建您自己的 JRDataSource(我不会提交整个 class,但只会提供有关如何完成此操作的一些提示,创建一个新 class 实施
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; } };
做出你的选择,玩得开心!