2

Spring フレームワークが提供するJasperReportsMultiFormatViewクラスで Jasper レポートを使用します。このクラスは、Spring アプリケーション コンテキストが作成されるときに、ソース .jrxml ファイルをコンパイル済みの .jasper 形式にコンパイルします。

ただし、このコンパイル プロセスにより、アプリケーションの起動時間が大幅に遅くなります。レポートを起動時にコンパイルするのではなく、遅延コンパイルすることは可能ですか?つまり、レポートは最初に要求されたときにのみコンパイルされますか?

これが不可能な場合は、レポートのコンパイル時間を短縮/排除する方法についての代替提案を歓迎します. もちろん、コンパイルされたレポートを .jrxml ファイルと一緒に SVN にチェックインするように強制することもできますが、誰か (おそらく私) が忘れるのも時間の問題です。

乾杯、ドン

4

2 に答える 2

8

私もあなたと同じように、Jasper Reports の Spring ヘルパー クラスから始めましたが、Spring では珍しく、粒度が粗すぎて柔軟性に欠けるため、すぐにそれらを放棄しました。後付けとして追加されたようです。

私が抱えていた大きな問題は、一度コンパイルすると、新しいバージョンを入れるために appserver バウンスが必要になることでした。私の場合、JSP が通常どのように機能するかのように、ディスク上でそれらを変更して再コンパイルできるソリューションを求めていました (この機能をオフにしない場合、多くの運用サイトではそうなります)。

あるいは、jrxml ファイルをデータベースに保存したり、レポートをリモートで (たとえば、JasperServer Web サービス インターフェイスを介して) 実行したりしたいと考えていました。Spring クラスは、そのような機能を実装することをほとんど不可能にしました。

だからあなたへの私の提案は次のとおりです:あなた自身をロールバックしてください。ただし、途中でいくつかの落とし穴がありますが、痛みを最小限に抑えるためにそれらを共有します. これらのいくつかは、ドキュメントから明らかではありません。

最初に必要なのは、ジャスパー レポート コンパイラです。これは、jrxml ファイルを JasperDesign オブジェクトにコンパイルする役割を果たします。これにはいくつかの実装がありますが、必要なものは JRJdtCompiler です。これをインスタンス化して、Spring アプリケーション コンテキストに注入できます。レポートを大きな beanshell スクリプトとして実行するのは特に高速でも効率的でもないため、beanshell コンパイラのようなものは避けてください (よくわからないうちに、これは難しい方法であることがわかりました)。

JRJdtCompiler の jar ファイルを含める必要があります。完全な Jasper Reports dist にはこの jar が含まれていると思います。そのエクリプス製品。

JasperDesign は好きな場所に保存できます (HttpSession、サーブレット コンテキストなど)。fillReport() メソッドは、あなたが関心を持っている主要なメソッドです。このメソッドは、実行レポートのインスタンスである JasperPrint オブジェクトを作成します。パラメータはマップとして渡されるだけです。

HTML、PDF などで versino を作成するには、エクスポートする必要があります。これを行うには、JRHtmlExporter や JRPdfExporter などのクラスを使用します。特定のパラメーターが必要です。HTML には明らかに画像が含まれていないため、注意が必要なのは HTML エクスポーターです。Jasper には、セッション (JRHtmlExporter が配置した場所) からこれらを取得する ImageServlet クラスが含まれていますが、HTML エクスポーターとイメージ サーブレットの両方の構成を適切に取得する必要があり、どこが間違っているのかを判断するのは困難です。

詳細は覚えていませんが、Jasper Reports Definitive Guideにこのすべての例があります。US$50とかなり安いです。年間サブスクリプションも取得できますが、18 か月以上の間、私はそれを見てきましたが、変更は 1 つも見られませんでした. 必要な場合は、新しいバージョンが出たときに購入してください (おそらくそうではないでしょう)。

お役に立てれば。

于 2008-11-30T02:27:18.947 に答える
1

レポートは初回実行時にコンパイルされます。これを確認するために、AbstractJasperReportsView protected final JasperReport loadReport(Resource resource) メソッドにブレーク ポイントを配置します。

ただし、特定のコンパイル プロセスを提供する場合は、JasperReportsMultiFormatView を拡張する必要があるという上記の投稿は正しいです。

動的コンパイルの優れた例は、http: //javanetspeed.blogspot.com/2013/01/jasper-ireport-with-java-spring-and.htmlです。

import net.sf.jasperreports.engine.JasperReport;
import org.apache.log4j.Logger;
import org.springframework.web.servlet.view.jasperreports.JasperReportsMultiFormatView;

public class DynamicJasperReportsMultiFormatView extends JasperReportsMultiFormatView {

private static final Logger LOG = Logger.getLogger(DynamicJasperReportsMultiFormatView.class);

/**
 * The JasperReport that is used to render the view.
 */
private JasperReport jasperReport;

/**
 * The last modified time of the jrxml resource file, used to force compilation.
 */
private long jrxmlTimestamp;

@Override
protected void onInit() {
    jasperReport = super.getReport();

    try {
        String url = getUrl();
        if (url != null) {
            jrxmlTimestamp = getApplicationContext().getResource(url).getFile().lastModified();
        }
    } catch (Exception e) {
        e = null;
    }
}

@Override
protected JasperReport getReport() {
    if (this.isDirty()) {
        LOG.info("Forcing recompilation of jasper report as the jrxml has changed");
        this.jasperReport = this.loadReport();
    }
    return this.jasperReport;
}

/**
 * Determines if the jrxml file is dirty by checking its timestamp.
 *
 * @return true to force recompilation because the report xml has changed, false otherwise
 */
private boolean isDirty() {
    long curTimestamp = 0L;
    try {
        String url = getUrl();
        if (url != null) {
            curTimestamp = getApplicationContext().getResource(url).getFile().lastModified();
            if (curTimestamp > jrxmlTimestamp) {
                jrxmlTimestamp = curTimestamp;
                return true;
            }
        }
    } catch (Exception e) {
        e = null;
    }
    return false;
}

}

于 2013-01-30T19:02:42.120 に答える