8

私はスタンドアロンアプリケーションを持っており、その任務の1つは、*。jrxmlファイルのパスを取得してコンパイルすることです。

サブレポートを含むレポートが表示されるまで、これを問題なく実行できます。マスターのコンパイルではその子がコンパイルされないため、後でサブレポート*.jasperファイルが見つかりません。

する方法はありますか

1)サブレポートを自動的に取得するようにJasperCompileManagerを設定しますか?

2)JasperDesignまたはJasperReportオブジェクトのいずれかに含まれるサブレポートへのパスのリストを取得しますか?

私はjrxmlファイルに直接アクセスできないため、コンパイル方法に合わせてレポートを変更することはできません。また、どのサブレポートがどのレポートに属するかを推測するための標準的な命名スキームを適用することもできません。

ここにも同様の問題があります。

http://jasperforge.org/plugins/espforum/view.php?group_id=102&forumid=103&topicid=40683

JRVisitorを使用してJRSubreportオブジェクトのリストを作成しますが、これを使用してサブレポートへのパスを取得し、それをコンパイルしてサブレポートのサブレポートを再帰的に検索する方法の説明がなく、理解できません。

4

1 に答える 1

10

さて、それは少しハッカーが必要でした、しかし私は何かを理解することができました...

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;
}
于 2012-04-04T07:15:04.623 に答える