Java Jasper子报告错误
当简单的报告Java Jasper子报告错误,java,jasper-reports,subreport,Java,Jasper Reports,Subreport,当简单的报告 不适用于子报表…我的Jarper知识已经有好几个版本了,但希望这会有所帮助 这是因为jasper找不到您的子报表。Jasper可以编译您的报告,但当您调用compileReport时,它不会编译引用的子报告。填写报告时,未找到引用的子报告,因为它们在工作目录中不可用 (每次被要求编写报告都是一个坏主意(除非你有非常重要的理由这么做)。) 有两种方法可以解决这个问题。其中之一是确保路径正确,并在部署应用程序之前预编译报告。AlexK提供的链接是一个很好的来源。如果需要应用程序内编译,
不适用于子报表…我的Jarper知识已经有好几个版本了,但希望这会有所帮助 这是因为jasper找不到您的子报表。Jasper可以编译您的报告,但当您调用
compileReport
时,它不会编译引用的子报告。填写报告时,未找到引用的子报告,因为它们在工作目录中不可用
(每次被要求编写报告都是一个坏主意(除非你有非常重要的理由这么做)。)
有两种方法可以解决这个问题。其中之一是确保路径正确,并在部署应用程序之前预编译报告。AlexK提供的链接是一个很好的来源。如果需要应用程序内编译,则可以使用以下解决方案:
在web应用程序中,我发现一种工作实践是处理编译,而填充报表则是手动管理。这是我写的助手类。希望它是有用的(它使用弹簧,但这些部件很容易更换)
公共类ReportSource{
//Key=文档名,Value=指向.jrxml的路径
私人地图报告;
编制私人最终地图;
私有最终布尔值;
私有最终记录器log=Logger.getLogger(ReportSource.class);
公共报告源(最终布尔lazyBuild){
超级();
懒惰=懒散的身材;
compiled=新HashMap();
}
public void setCompileTargets(最终映射目标){
报告=新的HashMap(目标);
如果(!懒惰){
for(最终字符串键:targets.keySet()){
编译(键);
}
}
}
公共JasperReport getReport(最终字符串reportName){
if(compiled.get(reportName)==null){//未找到或未编译
log.info(“延迟编译:”+reportName);
返回编译(reportName);
}
return compiled.get(reportName);
}
私有JasperReport编译(最终字符串reportName){
最终字符串路径=reports.get(reportName);
InputStream fis=null;
JasperReport报告=null;
试一试{
final FileSystemResourceLoader resourceLoader=新FileSystemResourceLoader();
fis=resourceLoader.getResource(路径).getInputStream();
log.info(“编译报告:“+reportName+”(“+path+”));
报告=jaspecpompilemanager.compileReport(fis);
}捕获(最终ioe异常ioe){
抛出新的IllegalStateException(“未找到配置错误文件:+path+”(对于键:+reportName+)”),ioe);
}捕获(最终jre异常){
抛出新的IllegalStateException(“未找到配置错误文件:+path+”(对于键:+reportName+)”),jre);
}
已编译。put(报告名称、报告);
返回报告;
}
}
借助此类帮助,您可以在以下文档中引用子报表:
public class ReportSource {
// Key = document name, Value = path to .jrxml
private Map<String, String> reports;
private final Map<String, JasperReport> compiled;
private final boolean lazy;
private final Logger log = Logger.getLogger(ReportSource.class);
public ReportSource(final boolean lazyBuild) {
super();
lazy = lazyBuild;
compiled = new HashMap<String, JasperReport>();
}
public void setCompileTargets(final Map<String, String> targets) {
reports = new HashMap<String, String>(targets);
if (!lazy) {
for (final String key : targets.keySet()) {
compile(key);
}
}
}
public JasperReport getReport(final String reportName) {
if (compiled.get(reportName) == null) { // not found or not compiled
log.info("Lazily compiling: " + reportName);
return compile(reportName);
}
return compiled.get(reportName);
}
private JasperReport compile(final String reportName) {
final String path = reports.get(reportName);
InputStream fis = null;
JasperReport report = null;
try {
final FileSystemResourceLoader resourceLoader = new FileSystemResourceLoader();
fis = resourceLoader.getResource(path).getInputStream();
log.info("Compiling report: " + reportName + " (" + path + ")");
report = JasperCompileManager.compileReport(fis);
} catch (final IOException ioe) {
throw new IllegalStateException("Configuration error file: " + path + " (for key: " + reportName +") not found.", ioe);
} catch (final JRException jre) {
throw new IllegalStateException("Configuration error file: " + path + " (for key: " + reportName +") not found.", jre);
}
compiled.put(reportName, report);
return report;
}
}
这里
$p{data}
是作为文档参数提供的合适对象,其中getSubreport()
最终调用ReportSource.getReport()
。如果直接将reportSource
作为参数提供,则它当然可以是$P{reportSource}.getReport(“..”)
。(我们使用ReportModel方法;简而言之,它是适合报告上下文的表示模型)。您可以查看,当您说,“这里$p{data}是作为文档参数提供的合适对象”和“如果直接作为参数提供reportSource,它当然可以是$p{reportSource}.getReport(…”),我不确定您的意思。您能否进一步解释此数据
或报告源
参数?我知道这是一个可以调用.getReport()的对象,但是我该如何设置它呢?现在我有一个ReportGenerator对象,它有一个compileReport()方法。但是如果我使用reportGenerator
它会说:jrvalidateexception:Report design not valid参数not found:reportGenerator
我上次使用jasperReports已经有几年了。您可以给报表指定参数,就像给函数指定参数一样(常用的习惯用法是Map)。然而,我在早期使用自定义类捕获错误,其参数名为data(${data})。我将此模式称为reportModel(非常类似于MVVM中的viewModel)。ReportModel包含reportGenerator实例(上面的源代码)。当报表渲染调用getSubreport(“…”)时,reportModel将该调用转发给reportSource。当然,您可以直接将reportSource作为参数do document(${reportSource})给出
JasperReport jasperReport = JasperCompileManager.compileReport(hdnWebInfPath+seperator+"reports"+seperator+"invoice.jrxml");
JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, model, new JREmptyDataSource());
JasperExportManager.exportReportToPdfFile(jasperPrint, fPath+seperator+fileName);
public class ReportSource {
// Key = document name, Value = path to .jrxml
private Map<String, String> reports;
private final Map<String, JasperReport> compiled;
private final boolean lazy;
private final Logger log = Logger.getLogger(ReportSource.class);
public ReportSource(final boolean lazyBuild) {
super();
lazy = lazyBuild;
compiled = new HashMap<String, JasperReport>();
}
public void setCompileTargets(final Map<String, String> targets) {
reports = new HashMap<String, String>(targets);
if (!lazy) {
for (final String key : targets.keySet()) {
compile(key);
}
}
}
public JasperReport getReport(final String reportName) {
if (compiled.get(reportName) == null) { // not found or not compiled
log.info("Lazily compiling: " + reportName);
return compile(reportName);
}
return compiled.get(reportName);
}
private JasperReport compile(final String reportName) {
final String path = reports.get(reportName);
InputStream fis = null;
JasperReport report = null;
try {
final FileSystemResourceLoader resourceLoader = new FileSystemResourceLoader();
fis = resourceLoader.getResource(path).getInputStream();
log.info("Compiling report: " + reportName + " (" + path + ")");
report = JasperCompileManager.compileReport(fis);
} catch (final IOException ioe) {
throw new IllegalStateException("Configuration error file: " + path + " (for key: " + reportName +") not found.", ioe);
} catch (final JRException jre) {
throw new IllegalStateException("Configuration error file: " + path + " (for key: " + reportName +") not found.", jre);
}
compiled.put(reportName, report);
return report;
}
}
<subreport>
<reportElement x="0" y="0" width="200" height="30"/>
<subreportParameter name="data">
<subreportParameterExpression><![CDATA[$P{data}]]></subreportParameterExpression>
</subreportParameter>
<subreportParameter name="REPORT_RESOURCE_BUNDLE">
<subreportParameterExpression><![CDATA[$P{REPORT_RESOURCE_BUNDLE}]]></subreportParameterExpression>
</subreportParameter>
<dataSourceExpression><![CDATA[new net.sf.jasperreports.engine.JREmptyDataSource()]]></dataSourceExpression>
<subreportExpression class="net.sf.jasperreports.engine.JasperReport"><![CDATA[$P{data}.getSubreport("name_of_your_subreport")]]></subreportExpression>
</subreport>