Longtalk 之前的 Smalltalk ;)
(当然,我不想鼓励您阅读这篇冗长详细的帖子的所有内容!粗体标记可能已经足以解决您的问题,但我发现值得记录这些棘手的内容更详细一点!)
因为我又在这方面投入了几个小时(几周前我解决了这个问题,现在有一个更改,但忘记正确记录它,忘记了我是如何做到的,并且无法以任何形式再次检索此信息 - 当上传和配置到/在 JasperServer 中)...这里有一些在各个站点上提到的关于子报表引用的聚合功能,它是如何工作的以及可以尝试什么...
(如果希望有的话,我会在这里更新我的或其他发现)
捷径细节/最佳做法?!4
直到 Jasper 功能本身提供类似的“包装”解决方案...
为了解决与在本地以预览模式或在 JasperServer 上远程运行 *.jrxml、*.jasper 文件相关的所有问题,我现在使用以下方法,只允许使用单个 *. jrxml 文件,无需修改即可在本地和远程工作,在多开发人员环境中,支持每个环境独立重构 dir 结构(路径、名称)(= 应该如此;-)):
- 使用一些jasper-utils-*.jar
- 将其放入您的项目 (Java) 类路径 (
Project->Properties->Java Build Path->Libraries->Add)
- 将其放入您的
../jasperserver/WEB-INF/lib/文件夹中
- 引用一些自定义 Jasper Java Scriptlet
jr.utl.EnvScriptlet,在您的主报告中执行丑陋的子报告路径/引用魔法
- 通过向主报告添加属性来定义
REPORT_SCRIPTLET:报告属性 -> 报告 -> 数据集 -> Scriptlet 类:jr.utl.EnvScriptlet
-
使用一些自定义属性文件 jr.utl.properties 或以其他方式提供的系统属性(设置 Java 系统属性的任何其他方式也可以正常工作 - 已经设置的属性将覆盖加载的文件properties) 来配置不同的环境,包括你的
- 当前环境信息通过
jr.utl.env 属性(prod、myOsUsrName、test、demo、staging、local...)
- 服务器子报表父目录属性引用
- 例如这些属性文件内容并在此处为每个环境放置一个:
-
在您的服务器上:../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/
将您的 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 或 scriptlet 功能可能不是最好的方法,但它可能适用于绝大多数用例
- 虽然两个现有的 Jasper 类都表明了这一点,但它们似乎无法正确处理上述问题:
(5:相关特殊处理编码在这里:EnvScriptlet.java/getSubrepPath(String,String,boolean,String[]))
简介(背景)
首先要知道的是,JasperStudio 中的处理/设置 与 Jasper Server (Repository) 上的处理完全不同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 报告服务器 GUI 存储库 ID 路径将是:
/x/y/z/
(不要与可视化命名路径混淆,例如可以是Financial Reports/Expenses/Current Year)
一般:Jasper Studio、JasperServer
(以及其他“Jasper 运行时环境”,例如自定义 Java Jasper 包的使用):
- 声明一个报告参数“前缀”似乎是一种良好做法,该前缀可能因您的 Jasper 运行时环境而异,例如命名为
BASE_DIR
- 重要的是,最好假设可能包含后缀
/1,因为在某些情况下您可能有/想要以应该是空或“未斜线”路径表达式的方式使用它
- 例如
$P{BASE_DIR} + "subrep1.jrxml" 应该解析为
repo:subrep1.jrxml
- 参见例如here 了解更多详情(查找
SUBREPORT_DIR)
(1:在处理类似目录的结构时,我个人认为这通常是一种不好的做法(在这方面不看 Jasper 报告))
JasperStudio Designer(Eclipse 插件)
(具有更多功能的官方 IReport 继任者)
(如果您不使用预览功能,您可能对此不感兴趣)
- 不幸的是,我发现没有实用的方法来完全支持(正常)“团队开发”与子报告(以及可能的其他相关资源),这意味着(目前对我来说未知)不存在分离本地路径的可能性和 *.jrxml 文件 :-(
- 例如如果您有一个版本控制系统并在不同的环境中工作(到 repos 和/或不同开发人员的不同本地路径),主报告必须以某种方式包含子报告的本地路径)
- 我尝试了不同的方法,但都失败了:
-
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 文件(就像我一样3),您必须像这样引用一些 subrep1.jrxml:@987654382 @
(3: 我不需要*.jasper 文件,也不明白我为什么要处理它们。顺便说一句,JasperServer WebGUI 似乎只支持*.jrxml 的上传文件)
JasperServer 网页界面
(例如,由某个 Tomcat 应用服务器提供,并将其数据存储在某个 postgres 数据库中)
场景 1:引用附加的子报表资源
- 如果您一般不想重复使用您的报告,将您的超级报告添加到您的主报告中似乎很好(因此它在 GUI 存储库树中不可见 - 请参阅下面的子项如何在您的主报告之外引用它无论如何)
- 如果您附加子报告,它通常应该将其文件名作为其资源 ID,例如我们上面的
subrep1.jrxml 使用subrep1.jrxml 的资源ID 上传(从而使本地设计参考和服务器参考的处理变得不那么复杂)
- 以上面的示例报告为例,我们必须在要上传的主报告中将我们的
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 子报表资源
其他提示
因为我喜欢自动化报告设计和部署过程,所以我编写了一些 ANT 任务来处理本地 *.jrxml 文件以进行部署 *关于BASE_DIR 和其他转换的.jrxml 文件转换。
SQL 有助于轻松调查 jasper 服务器 postgres 元数据库 中的资源 id 路径结构(遵循 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 论坛上与此相关的问题包括: