Jaspersoft Reports中如何在IF-ELSE从句内判断文件是否存在
问题根因
你使用new File()判断资源是否存在的逻辑失效,核心原因是repo:开头的路径是Jaspersoft自定义的内部仓库虚拟路径协议,并非操作系统本地文件系统的标准路径。java.io.File类仅能识别本地文件系统路径,无法解析Jasper专属的repo协议,因此无论目标资源是否真实存在,exists()/isFile()方法都会固定返回false,导致逻辑始终进入ELSE分支。
解决方案
有两种可行的实现方式:
方案1:异常捕获处理(更简单,推荐)
原有加载方法getBytesFromLocation在资源不存在时会抛出JRException,直接通过try-catch捕获异常,异常触发时加载默认资源即可,无需额外判断。
文本框表达式可直接使用如下代码(注意替换默认资源路径为你自己的实际路径):
try { return new String( net.sf.jasperreports.repo.RepositoryUtil.getInstance($P{JASPER_REPORTS_CONTEXT}).getBytesFromLocation( "repo:/home/res/html/file_" + $P{PARAM_HTML} + ".html" ), java.nio.charset.StandardCharsets.UTF_8 ); } catch (net.sf.jasperreports.engine.JRException e) { // 加载默认HTML文件 return new String( net.sf.jasperreports.repo.RepositoryUtil.getInstance($P{JASPER_REPORTS_CONTEXT}).getBytesFromLocation( "repo:/home/res/html/file_default.html" ), java.nio.charset.StandardCharsets.UTF_8 ); }
如果你的Jaspersoft版本不支持多行表达式,可将上述逻辑封装为静态工具类,打成jar包放入Jasper的类路径下,直接在表达式中调用工具类方法即可。
方案2:使用Jasper原生API判断资源存在性
如果需要先判断再加载,可使用RepositoryUtil的getResource方法校验repo路径下的资源是否存在,判断逻辑如下:
// 资源存在性判断条件 net.sf.jasperreports.repo.RepositoryUtil.getInstance($P{JASPER_REPORTS_CONTEXT}).getResource( "repo:/home/res/html/file_" + $P{PARAM_HTML} + ".html", net.sf.jasperreports.repo.DataResource.class ) != null
对应完整的三元表达式为:
net.sf.jasperreports.repo.RepositoryUtil.getInstance($P{JASPER_REPORTS_CONTEXT}).getResource("repo:/home/res/html/file_" + $P{PARAM_HTML} + ".html", net.sf.jasperreports.repo.DataResource.class) != null ? new String(net.sf.jasperreports.repo.RepositoryUtil.getInstance($P{JASPER_REPORTS_CONTEXT}).getBytesFromLocation("repo:/home/res/html/file_" + $P{PARAM_HTML} + ".html"), java.nio.charset.StandardCharsets.UTF_8) : new String(net.sf.jasperreports.repo.RepositoryUtil.getInstance($P{JASPER_REPORTS_CONTEXT}).getBytesFromLocation("repo:/home/res/html/file_default.html"), java.nio.charset.StandardCharsets.UTF_8)
内容的提问来源于stack exchange,提问作者mlaus
相关产品推荐
相关产品推荐

