Ist*_*tao 6 java jasper-reports
使用Jasper,我使用资源来加载报告.因此,要加载主报告,我使用如下内容:
InputStream is = getClass().getResourceAsStream("/resources/report1.jrxml");
design = JRXmlLoader.load(is);
Run Code Online (Sandbox Code Playgroud)
但是,如果report1.jrxml中有子报表,怎么说它在/resources/sub.jrxml中呢?
lkd*_*kdg 17
我是这样做的:
jasperDesign = JRXmlLoader.load(rootpath + "/WEB-INF/templates/Report.jrxml");
jasperDesignSR = JRXmlLoader.load(rootpath + "/WEB-INF/templates/SubReport.jrxml");
JasperReport jasperReport = JasperCompileManager.compileReport(jasperDesign);
JasperReport jasperReportSR = JasperCompileManager.compileReport(jasperDesignSR);
parameters.put("SubReportParam", jasperReportSR);
JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, parameters, dataSource);
Run Code Online (Sandbox Code Playgroud)
"SubReportParam"将是"JasperReport"类型的参数,作为报表中的SubreportExpression.
在.jrxml中:
<parameter name="SubReportParam" class="net.sf.jasperreports.engine.JasperReport" isForPrompting="false"/>
Run Code Online (Sandbox Code Playgroud)
我不知道您是否使用IReport进行报告设计.右键单击子报表,您应找到SubreportExpression.参数是我传递给"fillReport"的地图
祝好运.
我对lkdg的答案不太满意,因为我想分开加载正确文件和设计的问题,因为在我看来,我不应该强迫在JRXML文件的设计时加载报告.
不幸的是,Jasper Library的代码充满了静态引用,这使得很难找到注入自定义子报告加载器的正确位置,而且一些文档也很糟糕(例如,接口RepositoryService完全没有合同文档,所以我需要通过阅读调用代码来猜测合同),但有可能:
private static void fillReport() throws IOException, JRException {
// The master report can be loaded just like that, because the
// subreports will not be loaded at this point, but later when
// report is filled.
final JasperReport report = loadReport("masterReport.jasper");
// The SimpleJasperReportsContext allows us to easily specify some
// own extensions that can be injected into the fill manager. This
// class will also delegate to the DefaultJasperReportsContext and
// combine results. Thus all the default extensions will still be available
SimpleJasperReportsContext jasperReportsContext = new SimpleJasperReportsContext();
jasperReportsContext.setExtensions(
RepositoryService.class, singletonList(new SubReportFindingRepository())
);
final byte[] pdf = JasperExportManager.exportReportToPdf(
JasperFillManager
.getInstance(jasperReportsContext)
// carefully select the correct `fill` method here and don't
// accidentally select one of the static ones!:
.fill(report, YOUR_PARAMS, YOUR_CONNECTION)
);
}
private static JasperReport loadReport(final String fileName) throws IOException, JRException {
try(InputStream in = loadReportAsStream(fileName)) {
return (JasperReport) JRLoader.loadObject(in);
}
}
private static InputStream loadReportAsStream(final String fileName) {
final String resourceName = "/package/path/to/reports/" + fileName;
final InputStream report = CurrentClass.class.getResourceAsStream(resourceName);
if (report == null) {
throw new RuntimeException("Report not found: " + resourceName);
}
return report;
}
private static class SubReportFindingRepository implements RepositoryService {
@Override
public Resource getResource(final String uri) {
return null; // Means "not found". The next RepositoryService will be tried
}
@Override
public void saveResource(final String uri, final Resource resource) {
throw new UnsupportedOperationException();
}
@Override
public <K extends Resource> K getResource(final String uri, final Class<K> resourceType) {
if (!isKnownSubReport(uri)) {
return null; // Means "not found". The next RepositoryService will be tried
}
final ReportResource reportResource = new ReportResource();
try {
reportResource.setReport(loadReport(uri));
} catch (IOException | JRException e) {
throw new Error(e);
}
return resourceType.cast(reportResource);
}
private static boolean isKnownSubReport(final String uri) {
return "subReport1.jasper".equals(uri) || "subReport2.jasper".equals(uri);
}
}
Run Code Online (Sandbox Code Playgroud)
作为本地注入的替代方案,您还可以编写全局扩展.据我所知(我没有尝试),这需要创建一个jasperreports_extension.properties带有应该加载的类名的文件,其中可以包含一个自定义存储库来加载报告.但是,在这种情况下,您完全无法使用不同用例中所需的冲突配置.
| 归档时间: |
|
| 查看次数: |
12961 次 |
| 最近记录: |