2017-02-21 4 views
1

Ich bin ziemlich vertraut mit Jasperstudio 6.3.0 und bin in der Lage, andere Berichte von Java ohne Probleme zu laufen. Funktioniert gut. Ich kann jedoch keinen Bericht erstellen, der Unterberichte enthält. Ich habe hier auf Stackoverflow Lösungen gefunden, die aber immer noch nicht funktionieren. In meiner Lösung lade ich die Berichte in eine Tabelle für die Speicherung und ziehe die Unterberichte und den Hauptbericht aus der Datenbank und kompiliere die jrxml. Alles funktioniert gut bis dahin und dannRufen Sie Jasper Unterberichte in Java

net.sf.jasperreports.engine.JRException: Ressource nicht gefunden bei: subInvoiceSummary.jasper. Fehler in runReport: Ressource nicht gefunden unter: subInvoiceSummary.jasper. bei net.sf.jasperreports.repo.RepositoryUtil.getResourceFromLocation (RepositoryUtil.java:153) bei net.sf.jasperreports.repo.RepositoryUtil.getReport (RepositoryUtil.java:112) bei net.sf.jasperreports.engine. fill.JRFillSubreport.loadReport (JRFillSubreport.java:398) bei net.sf.jasperreports.engine.fill.JRFillSubreport.evaluateReport (JRFillSubreport.java:365) bei net.sf.jasperreports.engine.fill.JRFillSubreport.evaluateSubreport (JRFillSubreport.java:427) unter net.sf.jasperreports.engine.fill.JRFillSubreport.evaluate (JRFillSubreport.java:341) unter net.sf.jasperreports.engine.fill.JRFillElementContainer.evaluate (JRFillElementContainer.java:381) unter net.sf.jasperreports.engine.fill.JRFillBand.evaluate (JRFillBand.java: 500) at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillColumnBand (JRVerticalFiller.java:2022) bei net.sf.jasperreports.engine.fill.JRVerticalFiller.fillDetail (JRVerticalFiller.java:748) bei net.sf. jasperreports.engine.fill.JRVerticalFiller.fillReportStart (JRVerticalFiller.java:255) unter net.sf.jasperreports.engine.fill.JRVerticalFiller.fillReport (JRVerticalFiller.java:115) unter net.sf.jasperreports.engine.fill. JRBaseFiller.fill (JRBaseFiller.java:580) unter net.sf.jasperreports.engine.fill.BaseReportFiller.fill (BaseReportFiller.java:396) unter net.sf.jasperreports.engine.fill.JRFiller.fill (JRFiller. java: 90) bei net.sf.jasperreports.engine.JasperFillManager.fill (JasperFillManager.java:456) bei net.sf.jasperreports.engine.JasperFillManager.fillRe Port (JasperFillManager.java:863)

Ich habe viele Permutationen ausprobiert, aber ohne Erfolg. Ich habe auch versucht, den Code für jasperreports einzutragen, um den oben gezeigten Stack zu verfolgen, aber es gibt so viele .jar-Abhängigkeiten und Versionen von Abhängigkeiten, die ich nach zwei Tagen nicht in meinem Projekt kompilieren konnte (wenn jemand einen Link zu eine einfache Methode, um diese Arbeit zu machen, lass es mich wissen). Hier ist der Code-Schnipsel:

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

Vielen Dank im Voraus für jede Hilfe

Antwort

0

ich hatte das gleiche Problem und fand nie eine einfache Möglichkeit, dies achieive. Jasper-Entwickler selbst sagen, dass Unterberichte in ihren Foren nicht sehr gut implementiert sind.

Ich löste das Problem mit diesem Code von mir. Es ist auch nicht perfekt, aber es funktioniert.

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

Hoffe das hilft. Ich werde deine Frage favorisieren, wenn jemand eine bessere Lösung hat.