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 系统属性的任何其他方式也可以并且可以工作 - 已经设置的属性将覆盖加载的文件属性)来配置不同的环境,包括您的
- 通过属性的当前环境信息
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/
为了在我们的环境中实现源修改独立性,我们参数化了这些值并通过一些工作空间相关/用户特定的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=${用户名}
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
or 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 Report Server GUI repo id-path 将是:(
/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
- 有关更多详细信息,请参见此处(查找
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
以下内容:net.sf.jasperreports.engine.JasperCompileManager.compileReport($P{BASE_DIR} + "subrep1.jrxml")
(3:我不需要这些*.jasper
文件,也不明白为什么要处理它们。顺便说一句,JasperServer WebGUI 似乎只支持*.jrxml
文件上传)
JasperServer Web 图形用户界面
(例如,由一些 Tomcat 应用服务器提供,并将其数据存储在一些 postgres 数据库中)
场景 1:引用附加的子报表资源
- 如果您一般不想重用您的报告,将您的支持添加到您的主报告似乎很好(因此它在 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 repo path”中,如下所述)
场景 2:参考 repo 子报告资源
附加提示
因为我喜欢尽可能多地自动化报告设计和部署过程,所以我编写了一些ANT 任务来处理本地 *.jrxml 文件到可部署的 *.jrxml 文件转换,BASE_DIR
以及其他转换。
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 论坛上与此相关的问题包括: