さて、それは少しハッカーが必要でした、しかし私は何かを理解することができました...
subreport.getExpression()。getText()は、マスターレポートのサブレポートウィジェットの式フィールドを返します。これは、次のような文字列です。
$P{SUBREPORT_DIR} + "/report_sub1.jasper"
そこで、次のように分解して名前を付けることができました。それは理想的ではありませんが、持ちこたえるはずです。
JRElementsVisitor.visitReport(jasperReport, new JRVisitor(){
// ** snip other overrides **
@Override
public void visitSubreport(JRSubreport subreport){
String expression = subreport.getExpression().getText().replace(".jasper", ".jrxml");
StringTokenizer st = new StringTokenizer(expression, "\"/");
String subreportName = null;
while(st.hasMoreTokens())
subreportName = st.nextToken();
compileReport(subreportName);
}
}
編集:
これが私のcompileReportメソッド全体で、サブレポートなどのサブレポートを再帰的にコンパイルする方法を示しています。完璧ではありませんが、私のアプリには十分です。コンパイルされたすべての*.jasperファイルは、コンパイルされていない* .jrxmlファイルが取得されたのと同じ場所でディスクに保存されますが、これを変更するのは難しくありません。コンパイルされたメインレポートオブジェクトは、実行したい場合などに渡されます。
この編集の時点でこのコードは9か月前のものであり、新しいバージョンのJasperReportsにはこの種の機能が組み込まれている可能性があることに注意してください。
private static final String reportsPath = "someplace/nice/";
private ArrayList<String> completedSubReports = new ArrayList<String>(30);
private Throwable subReportException = null;
/**
* Recursively compile report and subreports
*/
public JasperReport compileReport(String reportName) throws Throwable{
JasperDesign jasperDesign = JRXmlLoader.load(reportsPath + reportName + ".jrxml");
JasperReport jasperReport = JasperCompileManager.compileReport(jasperDesign);
JRSaver.saveObject(jasperReport, reportsPath + reportName + ".jasper");
toLog("Saving compiled report to: " + reportsPath + reportName + ".jasper");
//Compile sub reports
JRElementsVisitor.visitReport(jasperReport, new JRVisitor(){
@Override
public void visitBreak(JRBreak breakElement){}
@Override
public void visitChart(JRChart chart){}
@Override
public void visitCrosstab(JRCrosstab crosstab){}
@Override
public void visitElementGroup(JRElementGroup elementGroup){}
@Override
public void visitEllipse(JREllipse ellipse){}
@Override
public void visitFrame(JRFrame frame){}
@Override
public void visitImage(JRImage image){}
@Override
public void visitLine(JRLine line){}
@Override
public void visitRectangle(JRRectangle rectangle){}
@Override
public void visitStaticText(JRStaticText staticText){}
@Override
public void visitSubreport(JRSubreport subreport){
try{
String expression = subreport.getExpression().getText().replace(".jasper", "");
StringTokenizer st = new StringTokenizer(expression, "\"/");
String subReportName = null;
while(st.hasMoreTokens())
subReportName = st.nextToken();
//Sometimes the same subreport can be used multiple times, but
//there is no need to compile multiple times
if(completedSubReports.contains(subReportName)) return;
completedSubReports.add(subReportName);
compileReport(subReportName);
}
catch(Throwable e){
subReportException = e;
}
}
@Override
public void visitTextField(JRTextField textField){}
@Override
public void visitComponentElement(JRComponentElement componentElement){}
@Override
public void visitGenericElement(JRGenericElement element){}
});
if(subReportException != null) throw new RuntimeException(subReportException);
return jasperReport;
}