を事前に
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;
}
これが役に立ちます。誰かがより良い解決策を持っているなら、私はあなたの質問を好きになるでしょう。