Jasper子报告错误

 com.hughes.exception.HughesException
    在com.hughes.service.serviceImpl.HomeServiceImpl.sendTicketEmail(HomeServiceImpl.java:1094)
     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

 .................................................. .....
 ..........................................

引起:net.sf.jasperreports.engine.JRException:找不到资源:nullinvoiceDetail.jasper
     at net.sf.jasperreports.repo.RepositoryUtil.getResource(RepositoryUtil.java:155)
     at net.sf.jasperreports.repo.RepositoryUtil.getReport(RepositoryUtil.java:126)
     at net.sf.jasperreports.engine.fill.JRFillSubreport.evaluateReport(JRFillSubreport.java:317)
     at net.sf.jasperreports.engine.fill.JRFillSubreport.evaluateSubreport(JRFillSubreport.java:347)
     at net.sf.jasperreports.engine.fill.JRFillSubreport.evaluate(JRFillSubreport.java:275)
     at net.sf.jasperreports.engine.fill.JRFillElementContainer.evaluate(JRFillElementContainer.java:257)
     at net.sf.jasperreports.engine.fill.JRFillBand.evaluate(JRFillBand.java:473)
    在net.sf.jasperreports.engine.fill.JRVerticalFiller.fillColumnBand(JRVerticalFiller.java:2021)
     at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillDetail(JRVerticalFiller.java:755)
     at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillReportStart(JRVerticalFiller.java:265)
     at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillReport(JRVerticalFiller.java:128)
     at net.sf.jasperreports.engine.fill.JRBaseFiller.fill(JRBaseFiller.java:836)
     at net.sf.jasperreports.engine.fill.JRBaseFiller.fill(JRBaseFiller.java:765)
     at net.sf.jasperreports.engine.fill.JRFiller.fillReport(JRFiller.java:84)
     at net.sf.jasperreports.engine.JasperFillManager.fillReport(JasperFillManager.java:624)
    在com.hughes.service.serviceImpl.HomeServiceImpl.sendTicketEmail(HomeServiceImpl.java:1046)
     ......还有81个
JasperReport jasperReport = JasperCompileManager.compileReport(hdnWebInfPath+seperator+"reports"+seperator+"invoice.jrxml"); JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, model, new JREmptyDataSource()); JasperExportManager.exportReportToPdfFile(jasperPrint, fPath+seperator+fileName); 

当简单报告不适用于子报告时,这是有效的…

我的Jarper知识是几个旧版本,但希望这有用。

这是因为jasper找不到您的子报表。 Jasper可以编译您的报告,但是在调用compileReport时它不会编译引用的子compileReport 。 填写报表时,找不到引用的子报表,因为它们在工作目录中不可用。

(每次请求报告时编译报告都是个坏主意(除非你有一些非常重要的理由这样做)。)

有几种方法可以解决这个问题。 一种方法是确保路径正确并在应用程序部署之前预编译报告。 链接Alex K提供的是一个很好的来源。 如果需要在应用程序编译中,则可以使用以下解决方案:

在Web应用程序中,我发现一个工作实践是处理编译并填写报告是手动管理它。 这是我写的助手类。 希望它有用(它使用弹簧,但这些部件很容易更换)。

 public class ReportSource { // Key = document name, Value = path to .jrxml private Map reports; private final Map compiled; private final boolean lazy; private final Logger log = Logger.getLogger(ReportSource.class); public ReportSource(final boolean lazyBuild) { super(); lazy = lazyBuild; compiled = new HashMap(); } public void setCompileTargets(final Map targets) { reports = new HashMap(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方法;简而言之,它是适合报告上下文的表示模型)。