ロングトークの前にスモールトーク;)
(もちろん、この長い詳細な記事をすべて読むように勧めたくはありません!太字のマーカーだけで問題を解決できるかもしれませんが、このトリッキーな内容をさらに詳しく説明する価値があると思いました!)
これにさらに数時間を費やしたので(数週間前に解決した後、現在変更がありましたが、適切に文書化するのを忘れ、どのように行ったかを忘れ、アップロードおよび構成時にこの情報をどのような形式でも再度取得できませんでしたto/in JasperServer) ...ここでは、サブレポートの参照、その仕組み、および試すことができるものに関して、さまざまなサイトで言及されているいくつかの集約機能を示します...
(うまくいけば、いくつかある場合は、ここで私のまたは他の調査結果を更新します)
ショートカットの詳細 / ベスト プラクティス?! 4
ジャスパーの機能が同様の「ラッピング」ソリューション自体を提供するまで...
*.jrxml、*.jasper ファイルをプレビュー モードでローカルに実行するか、JasperServer でリモートで実行することに関連するすべての問題を回避するために、私は現在、単一の *.jrxml ファイルのみを操作できる次のアプローチを使用しています。マルチ開発者環境で、変更なしでローカルおよびリモートで、環境ごとのディレクトリ構造 (パス、名前) の独立したリファクタリングをサポートします(= 必要に応じて ;-) ):
- jasper-utils-*.jarを使用する
- プロジェクト(Java)のクラスパスに入れます(
Project->Properties->Java Build Path->Libraries->Add
)
../jasperserver/WEB-INF/lib/
あなたのフォルダに入れます
jr.utl.EnvScriptlet
マスターレポートで醜いサブレポートパス/参照マジックを実行する
カスタム Jasper Java Scriptletを参照する
REPORT_SCRIPTLET
マスター レポートに属性を追加して定義します:レポート プロパティ -> レポート -> データ セット -> スクリプトレット クラス: jr.utl.EnvScriptlet
いくつかのカスタム プロパティ ファイルjr.utl.properties
または別の方法で提供されたシステム プロパティを使用して(Java システム プロパティを設定する他の方法でも問題なく動作します - すでに設定されているプロパティは、ロードされたファイル プロパティを上書きします)
- プロパティによる現在の環境情報
jr.utl.env
(prod、myOsUsrName、test、demo、staging、local など)
- サブレポート参照をどのように生成する必要があるか/どのように見えるかを決定します
- サーバー サブレポートの親ディレクトリ プロパティの参照
- たとえば、これらのプロパティ ファイルの内容を環境ごとに 1 つここに配置します。
サーバー上で:../jasperserver/WEB-INF/classes/jr.utl.properties
jr.utl.env=prod
mycompany.local.jr.gui.rep.subrep1.parentdir=repo:/x/y/z/
mycompany.local.jr.gui.rep.subrep2.parentdir=repo:/x/y/z/
mycompany.local.jr.gui.rep.subrep3.parentdir=repo:/x/y/foobar/
ローカルのJasperSoft Studio (Eclipse) Java src/build パス:例../myrepproject/src/java/jr.utl.properties
jr.utl.env=dietrian
mycompany.local.jr.gui.rep.subrep1.parentdir=D:/reporting/src/reports/
mycompany.local.jr.gui.rep.subrep2.parentdir=D:/reporting/src/reports/
mycompany.local.jr.gui.rep.subrep3.parentdir=D:/reporting/src/reports.otherdir/
私たちの環境でソース変更の独立性を達成するために、これらの値をパラメーター化しlocal.properties
、このアイデアに基づいて、ワークスペースに依存する/ユーザー固有のファイルを介してそれらを一度生成しました。
|- build.xml (ANT ビルド マジックを含む)
|- build.properties (グローバル プロパティを含む)
|- local.properties (バージョン管理では無視されます。例: .hgignore、local.template.properties から生成されたユーザー固有)
|- local.template.properties (上記の local.properties を生成する ANT ビルド タスクのソース)
|- mycomp.local.proj.reporting.dir=D:/reporting
|- ソース/レポート
|- jr.utl.properties (バージョン管理では無視され、以下のテンプレートに基づいてユーザー固有に生成されます)
|- jr.utl.template.properties (上記の jr.utl.properties を生成する ANT ビルド タスクのソース)
jr.utl.env=${user.name}
mycompany.local.jr.gui.rep.subrep1.parentdir=${mycomp.local.proj.reporting.dir}/src/reports/
mycompany.local.jr.gui.rep.subrep2.parentdir=${mycompany.local.jr.gui.rep.subrep1.parentdir}
mycompany.local.jr.gui.rep.subrep3.parentdir=${mycomp.local.proj.reporting.dir}/src/reports.otherdir/
BASE_DIR
たとえば、マスターレポートのパラメーターを
定義する(ファイル$P{REPORT_SCRIPTLET}.getProp("mycompany.allsubreports.parentdir")
内の環境依存のプロパティに一致する)jr.utl.properties
- マスターサブレポート式を次のように定義する
jr.utl.EnvScriptlet.getSubrepPath( $P{BASE_DIR}, "subrep1.jrxml")
- プロパティから値を自動的に解決します。たとえば、次のバリアントも使用できます。
jr.utl.EnvScriptlet.getSubrepPathByPropKey( $P{BASE_DIR}, "mycompany.local.jr.gui.rep.subrep1.name")
jr.utl.EnvScriptlet.getSubrepPathByPropKeys( "mycompany.local.jr.gui.rep.subrep1.parentdir", "mycompany.local.jr.gui.rep.subrep1.name")
$P{REPORT_SCRIPTLET}.getSubrepPath(...)
ここでは機能しません:-( (理由はわかりません)
- すべてのファイルをサーバーに配置したら、サーバーを再起動することを忘れないでください。
( 4 : もちろん、ここでいくつかの小さな改善が見られますが、これまでに見つけたすべての醜い解決策よりもはるかに優れているようです。改善点:
- または スクリプトレット機能を使用するの
REPORT_SCRIPTLET
は最善の方法ではないかもしれませんが、おそらくほとんどのユースケースで機能します
- 既存の Jasper クラスは両方ともこれを示唆していますが、上記を適切に処理できないようです。
( 5 : 関連する特別な処理がここにエンコードされています: EnvScriptlet.java/getSubrepPath(String,String,boolean,String[]) )
イントロ(背景)
最初に知っておくべきことは、JasperStudio での処理/セットアップは、 Jasper Server (リポジトリ) 5での処理とはかなり異なるということです ...
次の環境があるとします。
- Eclipse のインストール ディレクトリ:
C:\eclipse\
- Eclipse (レポート) ワークスペース:
C:\workspace\
- 私たちのレポートプロジェクトは次のとおりです。
C:\workspace\report-project\
- 私たちのレポートは次のとおりです。
C:\workspace\report-project\src/reports
- マスターレポート
C:\workspace\report-project\src/reports/masterrep.jrxml
- いくつかのサブレポート
C:\workspace\report-project\src/reports/subrep1.jrxml
- 別のサブレポート
C:\workspace\report-project\src/reports/somesubdir/subrep2.jrxml
BASE_DIR
ワークスペースマスターレポートの(次のセクションで説明します) はに設定されていますC:\workspace\report-project\src/reports/
- マスター レポートの Jasper Report Server GUI リポジトリ ID パスは次のようになります
/x/y/z/
(これは、視覚的な名前付きパスと混同しないでください。たとえばFinancial Reports/Expenses/Current Year
、
一般: Jasper Studio、JasperServer
(およびカスタム Java Jasper パッケージの使用などの他の「Jasper ランタイム環境」):
- Jasperランタイム環境によって異なるレポート パラメータ「プレフィックス」を宣言することをお勧めします。
BASE_DIR
- ここで重要なのは、サフィックス
/
が含まれている可能性があると想定するのが最善のように思われること です
- たとえば
$P{BASE_DIR} + "subrep1.jrxml"
、これはに解決する必要があります
repo:subrep1.jrxml
- 詳細については、たとえばここを参照してください ( を探してください
SUBREPORT_DIR
)
( 1 : ディレクトリのような構造を扱う場合、私は個人的に一般的に悪い習慣を見つけます (この点で Jasper Reports を見ていません))
JasperStudio デザイナー (Eclipse プラグイン)
(より多くの機能を備えた公式の IReport の後継)
(プレビュー機能を使用しない場合、これは興味がないかもしれません)
- 残念ながら、サブレポート(およびおそらく他の相対的なリソース)を使用して(通常の)「チーム開発」を完全にサポートする実用的な方法は見つかりませんでした。つまり、ローカルパスと *.jrxml ファイルを分離する(現在のところ私には不明な)存在しない可能性があります。 -(
- たとえば、バージョン管理システムが導入されていて、さまざまな環境 (レポジトリやさまざまな開発者へのローカル パスが異なる) で作業している場合、マスター レポートには何らかの方法でサブレポートへのローカル パスを含める必要があります)
。
- 失敗したさまざまなアプローチを試しました:
BASE_DIR
作業ディレクトリがEclipseディレクトリであるため、相対パス式は機能しません。C:\eclipse
Eclipse->Window->Preferences->JasperStudio->Properties->Add
例: my.base.dir
- プレビュー モードでは使用できません。たとえば
new java.io.File(System.getProperty("my.base.dir")).getCanonicalPath() + "/"
、BASE_DIR
エクスプレッションを介して使用できます (これらの小道具は、デザイナー自身によってのみ使用される場合がありますが、プレビューの実行では設定されません)。
- あなたがつまずくかもしれない場合に備えて(私がしたように):
Eclipse->Window->Preferences->JasperStudio->Report Execution->Virtualizer Temporary Path
レポート結果の「キャッシュ」の保存を扱う無関係な(ここでは役に立たない)ものです
- もちろん、すべての使用/チェックアウトで正規表現フィルターのコピーに基づいてこれらのローカル パターンを置き換える ANT タスクを作成することもできますが、これを処理する良い方法ではないようです。
*.jrxml
ファイルのみを操作したい場合(私がそうしているように3subrep1.jrxml
)、次のようなものを参照する必要があります。net.sf.jasperreports.engine.JasperCompileManager.compileReport($P{BASE_DIR} + "subrep1.jrxml")
( 3 :*.jasper
ファイルを明示的に必要とせず、なぜそれらを処理したいのかわかりません。ところで、JasperServer WebGUI は*.jrxml
ファイルのアップロードのみをサポートしているようです)
JasperServer Web GUI
(たとえば、一部の Tomcat アプリケーション サーバーによって提供され、そのデータを一部の postgres データベースに保存する)
シナリオ 1: 添付されたサブレポート リソースを参照する
- 一般的にレポートを再利用したくない場合は、supreport をマスター レポートに追加しても問題ないようです (そのため、GUI リポジトリ ツリーには表示されません。以下のサブ項目で、マスターの外部で参照する方法を参照してください)。
- サブレポートを添付する場合、通常はそのファイル名をそのリソース ID として持つ必要があります。たとえば、
subrep1.jrxml
上記のリソース ID を使用してアップロードしますsubrep1.jrxml
(したがって、ローカルの設計参照とサーバー参照の処理がより簡単になります)。
- 上記のサンプル レポートを使用して、アップロードするマスター レポートに設定
BASE_DIR
する必要があります。repo:
- したがって、サブレポート式
$P{BASE_DIR} + "subrep1.jrxml"
であり$P{BASE_DIR} + "somesubdir/subrep2.jrxml"
、サーバーでも機能するはずです
- 推奨されません! :この2のような絶対パスを使用して、他のレポートからこれらのレポートを引き続き参照できます。
repo:/x/y/z/masterrep.jrxml_files/masterrep.jrxml_
(2:この場合はお勧めしません。文書化されておらず、変更される可能性があります。以下で説明するように、サブレポートを「GUIリポジトリパス」に配置することをお勧めします)
シナリオ 2: repo サブレポート リソースを参照する
追加のヒント
私はレポートのデザインと展開プロセスを可能な限り自動化したいので、ローカルの *.jrxml ファイルを処理して、 およびその他の変換に関する展開可能な *.jrxml ファイル変換を処理するANT タスクをいくつか作成しBASE_DIR
ました。
jasper サーバー postgres メタ データベースのリソース ID パス構造を簡単に調査するのに役立つSQL (jdbc:postgresql://myjasperhost/jasperserver
たとえば、postgres ユーザーとの接続など):
select
f.id as folder_id,
r.id as res_id,
case when f.hidden = true then 1 else 0 end as hidden,
f.uri||case when f.uri = '/' then '' else '/' end||coalesce(r.name,'') as res_uri,
r.resourcetype,
r.creation_date,
r.update_date,
f.uri,
r.name,
-- less important
r.version,
r.parent_folder,
r.childrenfolder,
f.parent_folder,
f.version,
f.name
-- select *
from jiresourcefolder f
left outer join jiresource r on (r.parent_folder = f.id)
where not f.uri like '/themes%'
order by f.uri||coalesce(r.name,'')
関連する質問
これに関連する Jaspersoft フォーラムの質問には、次のようなものがあります。