Jasper sub report error

不问归期 提交于 2019-12-20 06:32:22

问题


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

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

Caused by: net.sf.jasperreports.engine.JRException: Resource not found at : 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)
    at 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)
    at com.hughes.service.serviceImpl.HomeServiceImpl.sendTicketEmail(HomeServiceImpl.java:1046)
    ... 81 more
JasperReport jasperReport = JasperCompileManager.compileReport(hdnWebInfPath+seperator+"reports"+seperator+"invoice.jrxml");
                        JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, model, new JREmptyDataSource());
                        JasperExportManager.exportReportToPdfFile(jasperPrint, fPath+seperator+fileName);

this works when simple report not working for sub reports...


回答1:


My Jarper knowledge is couple versions old, but lets hope this is helpful.

This is because jasper does not find your subreport. Jasper can compile your report, but it does not compile referenced subreports when you call compileReport. When filling the report referenced subreports are not found because they are not available in working directory.

(Compiling report every time it is requested is kind a bad idea (unless you have some really heavy reasons to do so).)

There are couple of ways solving this. One would be making sure the the paths are correct and precompiling the reports before application deployment. Links Alex K provided are an excellent source for this. If in application compilation is required then using solution below is possible:

In web application I've found that a working practice is to handle compilation and filling your reports is to manage it manually. Here is helper class I wrote. Hope that it is useful (it uses spring, but those parts are easily replaceable).

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;
    }
}

With the help of this class you can refer subreports in documents like this:

<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>

Here $P{data} is suitable object provided as document parameter, where getSubreport() ends up calling ReportSource.getReport(). It could of course be $P{reportSource}.getReport("....") if ReportSource is provided as parameter directly. (We use ReportModel-approach; in short it is presentation model fitted to the context of reports).



来源:https://stackoverflow.com/questions/10598958/jasper-sub-report-error

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!