2017-02-21 8 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) at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillColumnBand (JRVerticalFiller.java:2022) at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillDetail (JRVerticalFiller.java:748) at net.sf. jasperreports.engine.fill.JRVerticalFiller.fillReportStart (JRVerticalFiller.java:255) at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillReport (JRVerticalFiller.java:115) at net.sf.jasperreports.engine.fill. 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 일 후에 프로젝트를 정리할 수 없습니다 (누군가에게 링크가있는 경우). 그 일을하는 간단한 방법을 알려주세요). 저도 같은 문제가 없었다 결코이 achieive하는 간단한 방법을 발견 한 지원

답변

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(); 

감사 : 여기에 코드입니다. 재스퍼 개발자들은 자신의 포럼에서 하위 보고서가 제대로 구현되지 않았다고 말합니다.

이 코드로 문제를 해결했습니다. 완벽하지는 않지만 완벽합니다.

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

희망이 있습니다. 누구에게나 더 나은 해결책이 있다면 나는 당신의 질문을 좋아할 것입니다.