Вопрос по jasper-reports, java – Jasper sub report error

0
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 post, this one а такжеthis one Alex K

Ваш Ответ

1   ответ
1

Это потому, что яшма не находит ваш подотчет. Jasper может скомпилировать ваш отчет, но он не компилирует ссылочные подотчеты, когда вы звонитеcompileReport, При заполнении отчета указанные подотчеты не обнаруживаются, поскольку они недоступны в рабочем каталоге.

(Компиляция отчета каждый раз, когда он запрашивается, является плохой идеей (если у вас нет действительно веских причин для этого).)

Есть несколько способов решения этой проблемы. Можно было бы убедиться в правильности путей и предварительно скомпилировать отчеты перед развертыванием приложения. Ссылки Alex K являются отличным источником для этого. Если в приложении требуется компиляция, возможно использование нижеприведенного решения:

В веб-приложении я обнаружил, что рабочая практика заключается в том, чтобы обрабатывать компиляцию, а заполнение ваших отчетов - управлять ею вручную. Вот вспомогательный класс, который я написал. Надеюсь, что это полезно (в нем используется пружина, но эти детали легко заменяются).

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>

Вот$P{data} Подходящий объект предоставляется в качестве параметра документа, гдеgetSubreport() в итоге звонитReportSource.getReport(), Конечно, это может быть$P{reportSource}.getReport("....") еслиReportSource предоставляется в качестве параметра напрямую. (Мы используем ReportModel-подход; короче говоря, это модель представления, адаптированная к контексту отчетов).

Похожие вопросы