2017-02-21 17 views
1

私はjasperstudio 6.3.0によく似ており、問題なくJavaから他のレポートを実行することができます。うまくいく。ただし、サブレポートを含むレポートを実行することはできません。私はここでstackoverflowのソリューションを見つけましたが、まだそれを動作させることができません。私のソリューションでは、レポートを格納するテーブルにロードし、サブレポートとメインレポートをデータベースから取り出してjrxmlをコンパイルしています。すべてが正常に動作してから、Javaのサブレポートを呼び出す

net.sf.jasperreports.engine.JRException:リソースが見つかりません:subInvoiceSummary.jasper。 runReportのERROR:リソースが見つかりません:subInvoiceSummary.jasper。 net.sf.jasperreports.repo.RepositoryUtil.getReportでnet.sf.jasperreports.repo.RepositoryUtil.getResourceFromLocation(RepositoryUtil.java:153) (RepositoryUtil.java:112)net.sf.jasperreports.engineで で。 net.sf.jasperreports.engine.fill.JRFillSubreport.evaluateSubreportでnet.sf.jasperreports.engine.fill.JRFillSubreport.evaluateReport(JRFillSubreport.java:365) でfill.JRFillSubreport.loadReport(JRFillSubreport.java:398) ( JRFillSubreport.java:427) at net.sf.jasperreports.engine.fill.JRFillSubreport.evaluate(JRFillSubreport.java:341) at net.sf.jasperreports.engine.fill.JRFillElementContainer.evaluate(JRFillElementContainer.java:381) at net.sf.jasperreports.engine.fill.JRFillBand.evaluate(JRFillBand.java:500)(JRVerticalFiller.java:2022) (JRVerticalFiller.java:255) JRBaseFiller.fill(JRBaseFiller.java:580) at net.sf.jasperreports.engine.fill.BaseReportFiller.fill(BaseReportFiller.java:396) at net.sf.jasperreports.engine.fill.JRFiller.fill(JRFiller。 java:90) at net.sf.jasperreports.engine.JasperFillManager.fill(JasperFillManager.java:456) at net.sf.jasperreports.engine.JasperFillManager.fillReポート(JasperFillManager.java:863)

私は多くの順列を試みましたが、無駄です。上記のスタックをトレースするためのjasperreportsコードを取得しようとしましたが、非常に多くの.jar依存関係とバージョンがあります.2日後にプロジェクトをクリーンにコンパイルできませんでした。その仕事をするための簡単な方法は私に知らせてください)。ここでは、コードスニペットがある:どのような援助

答えて

0

を事前に

Map<String, Object> rptParms = new HashMap<String, Object>(); 

List<daRecOnDemandSubReport> subReports = report.getOnDemandSubReport(); 
Iterator<daRecOnDemandSubReport> subReportList = subReports.iterator(); 
while (subReportList.hasNext()) { 
daRecOnDemandSubReport subReport = subReportList.next(); 
ByteArrayInputStream x = getSubReportDataStream(dbConnROIPro, report.getODReportID()); 
JasperReport compiledSubReport = JasperCompileManager.compileReport(x); 
String fileName = subReport.getODSubReportFileName().replace(".jrxml", ".jasper"); 
rptParms.put(fileName, compiledSubReport); 
} 

ByteArrayInputStream x = getReportDataStream(dbConnROIPro, report.getODReportID()); 

JasperReport cRpt = JasperCompileManager.compileReport(x); 

rptParms = getReportParameters(dbConnGTrack,report.getODReportID(), rptParms, report.getOnDemandParm(), programID); 

JasperPrint rpt = JasperFillManager.fillReport(cRpt,rptParms,dbConnGTrack.getDbConn()); 

ByteArrayOutputStream outStream = new ByteArrayOutputStream(); 
JRXlsxExporter XLSXexporter = new JRXlsxExporter(); 
    XLSXexporter.setExporterInput(new SimpleExporterInput(rpt)); 
    XLSXexporter.setExporterOutput(new SimpleOutputStreamExporterOutput(outStream)); 
    XLSXexporter.exportReport(); 

おかげで、私は同じ問題がなかったし、決してこれをachieiveする簡単な方法を発見しました。 Jasperの開発者たちは、サブレポートはフォーラムではうまく実装されていないと言います。

私はこのコードで問題を解決しました。それは完璧とはほど遠いですが、うまくいきます。

public byte[] generateReport(ExportType exportType, String resourceName, Connection connection, Map<String, Object> parameters) throws JRException, SQLException { 
    JasperReport jasperReport = loadReport(resourceName); 

    LOGGER.debug("Loading subreports if any..."); 
    Map<String, JasperReport> subReports = loadSubReports(resourceName, jasperReport); 
    parameters.putAll(subReports); 

    LOGGER.debug("Filling report with JDBC and {}", parameters); 
    JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, parameters, connection); 

    LOGGER.debug("Exporting report with {}", exportType.getClass().getSimpleName()); 
    byte[] pdf = exportType.export(jasperPrint); 

    return pdf; 
} 

/** 
* Converts a system resource into a JasperReport instance. 
* If the extension is ".jasper", it tries to load a pre-compiled report. 
* If the extension is ".jrxml", it tries to compile the report. 
*/ 
private JasperReport loadReport(String resourceName) throws JRException { 
    JasperReport jasperReport = null; 
    InputStream inputStream = this.getClass().getResourceAsStream(resourceName); 

    if (inputStream != null) { 
     if (resourceName.toLowerCase().endsWith(JASPER)) { 
      LOGGER.debug("Loading pre-compiled report: {}", resourceName); 
      jasperReport = (JasperReport) JRLoader.loadObject(inputStream); 
     } else { 
      LOGGER.debug("Compiling XML report: {}", resourceName); 
      jasperReport = JasperCompileManager.compileReport(inputStream); 
     } 
    } else { 
     LOGGER.warn("Unable to open resource: {}", resourceName); 
    } 
    return jasperReport; 
} 

/** 
* Parses a Report for SubReport parameters. 
* A Parameter has to be a <code>java.lang.Object</code> or a <code>net.sf.jasperreports.engine.JasperReport</code> to be considered a SubReport Input 
* An Object parameter has the advantage to allow Jasper Report's IDE to accept a Filename String resource. 
* If the parameter is an Object, the Filename declared as <b>default value</b> is used to load the SubReport. 
* If the parameter is a JasperReport, the parameter's name is used instead. 
* 
* The default value, or the parameter's name, have to use a ".jasper" or ".jrxml" extension. 
* The SubReport resource's path has to be located relatively to the parent Report. 
*/ 
private Map<String, JasperReport> loadSubReports(String masterResource, JasperReport jasperReport) throws JRException { 
    Map<String, JasperReport> subReportExpressions = new HashMap<>(); 
    String masterPath = FilenameUtils.getFullPath(masterResource); 

    for (JRParameter jrParameter : jasperReport.getParameters()) { 
     String subReportName = getSubReportName(jrParameter); 
     if (subReportName != null) { 
      String name = jrParameter.getName(); 
      JasperReport subReport = loadReport(masterPath + subReportName); 
      subReportExpressions.put(name, subReport); 
     } 
    } 
    return subReportExpressions; 
} 


/** 
* Analyses the parameter to find a SubReport resource name respecting the defined rules 
* 
* @return The filename of the resource, or null 
*/ 
private String getSubReportName(JRParameter jrParameter) { 
    String ret = null; 
    Class<?> valueClass = jrParameter.getValueClass(); 
    boolean isObject = (valueClass == Object.class); 
    boolean isJasperReport = (valueClass == JasperReport.class); 

    // If the parameter is an Object, 
    // we take the SubReport name from the default value (a String) 
    if (isObject) { 
     String defaultValue = getDefaultValue(jrParameter); 
     if (defaultValue != null && checkExtension(defaultValue)) { 
      ret = defaultValue; 
     } 
    } 

    // If the parameter is a JasperReport, or an Object without a correct defaultValue, 
    // we take the SubReport name from the parameter's name 
    if (isJasperReport || (ret == null && isObject)) { 
     String name = jrParameter.getName(); 
     if (checkExtension(name)) { 
      ret = name; 
     } 
    } 
    return ret; 
} 


private boolean checkExtension(String defaultValue) { 
    defaultValue = defaultValue.toLowerCase(); 
    return defaultValue.endsWith(JRXML) || defaultValue.endsWith(JASPER); 
} 

private String getDefaultValue(JRParameter jrParameter) { 
    String ret = null; 
    JRExpression defaultValueExpression = jrParameter.getDefaultValueExpression(); 
    if (defaultValueExpression != null) { 
     ret = defaultValueExpression.getText(); 
     if (ret != null && ret.length() > 2 && ret.startsWith(QUOTE) && ret.endsWith(QUOTE)) { 
      // Removing quotes from the String 
      ret = ret.substring(1, ret.length() - 1); 
     } 
    } 
    return ret; 
} 

これが役に立ちます。誰かがより良い解決策を持っているなら、私はあなたの質問を好きになるでしょう。

関連する問題