How to provide a datafactory for subreport in pentaho reporting engine?
How to provide a d开发者_Python百科atafactory for subreport in pentaho reporting engine?
Locate your subreport and then set the datafactory there:
For banded subreports:
report.getReportHeader().getSubReport(0).setDataFactory(..);
For inline subreports:
SubReport report = (SubReport) report.getReportHeader().getElement(0); report.setDataFactory(..);
However, usually you define your datafactories in the report designer and then just use them. Alternatively, you can set datafactories on the master report and they get inherited to the subreports. If you need more than one type of datafactories throughout your report, then use a "CompoundDataFactory".
Ensure that your reports then have different query names, or you may run into trouble.
It should be implicitly accessible for the subreports if you call setDataFactory(DataFactory)
on the MasterReport. I use it this way with a Datasource of type Table and data that is pre-calculated by the application. In this scenario, Pentaho is basically used as a rendering engine only.
I found Thomas Morgner's advice (above) to be correct, with one caveat. His example assumes that the SubReport exists in the ReportHeader.
In my case the SubReports were deeply nested in other parts of the report, so I wrote some code to find all the SubReports. Maybe there's a better way to find this, but here's what I did, and if worked for me. If anyone know an easier way to enumerate all the SubReports, please let me know!
private Set<CompoundDataFactory> getCompoundDataFactoriesFromMasterAndSubreports() {
Set<CompoundDataFactory> CompoundDataFactories = new HashSet<CompoundDataFactory>();
CompoundDataFactories.add( compoundDataFactory ); // Master report
Set<SubReport> subReports = getSubReports();
for ( SubReport subReport : subReports ) {
if ( subReport.getDataFactory() instanceof CompoundDataFactory ) {
CompoundDataFactories.add( (CompoundDataFactory)subReport.getDataFactory() );
}
}
return CompoundDataFactories;
}
private Set<SubReport> getSubReports() {
Set<SubReport> subReports = new HashSet<SubReport>();
recurseToFindAllSubReports(masterReport,subReports);
return subReports;
}
private void recurseToFindAllSubReports(Section section, Set<SubReport> subReports) {
int elementCount = section.getElementCount();
for ( int i=0; i<elementCount ; i++ ) {
Element e = section.getElement(i);
if ( e instanceof RootLevelBand ) {
SubReport[] subs = ((RootLevelBand)e).getSubReports();
for( SubReport s : subs ) {
subReports.add(s);
}
}
if ( e instanceof Section ) {
recurseToFindAllSubReports((Section)e, subReports);
}
}
}
精彩评论