如何在Vaadin 14的水平/垂直布局中嵌入Jasper Reports?
Vaadin 14 嵌入 Jasper Reports 解决方案
先排查当前 iframe 方案的问题
- 验证 URL 有效性:直接在浏览器地址栏输入你给 iframe 的
url,确认能否正常显示报表。如果浏览器里都打不开,先优先搞定后端 Jasper 报表的生成和路由配置,确保 URL 能返回正确的报表内容(比如 PDF、HTML)。 - 调整 sandbox 属性:你当前只设置了
allowscripts,权限限制过多可能导致报表无法加载。可以先去掉 sandbox 属性测试:
如果能正常显示,再按需添加必要权限,比如jasperReportIframe.getElement().removeAttribute("sandbox");allow-same-origin allow-scripts allow-top-navigation,避免过度限制。
推荐的替代方案
方案1:用 Vaadin Embedded 组件嵌入报表
Vaadin 14 保留了 Embedded 组件,适合直接嵌入二进制流(如 PDF),步骤如下:
- 后端用 Jasper 生成报表字节流
- 将字节流转为 Vaadin 的
StreamResource - 用
Embedded加载该资源
示例代码:
// 生成 Jasper PDF 报表字节流 JasperReport jasperReport = JasperCompileManager.compileReport("report-template.jrxml"); JRDataSource dataSource = new JRBeanCollectionDataSource(yourDataList); ByteArrayOutputStream baos = new ByteArrayOutputStream(); JasperExportManager.exportReportToPdfStream(JasperFillManager.fillReport(jasperReport, null, dataSource), baos); // 创建 StreamResource StreamResource resource = new StreamResource("report.pdf", () -> new ByteArrayInputStream(baos.toByteArray())); resource.setContentType("application/pdf"); // 用 Embedded 显示报表 Embedded embeddedReport = new Embedded(); embeddedReport.setResource(resource); embeddedReport.setSizeFull(); add(embeddedReport);
方案2:将报表转为 HTML 用 Html 组件渲染
如果报表适合转为 HTML,可以直接生成 HTML 字符串,用 Vaadin 的 Html 组件渲染,规避 iframe 的跨域或权限问题:
// 生成 Jasper HTML 报表字符串 JasperReport jasperReport = JasperCompileManager.compileReport("report-template.jrxml"); JRDataSource dataSource = new JRBeanCollectionDataSource(yourDataList); String reportHtml = JasperExportManager.exportReportToHtml(JasperFillManager.fillReport(jasperReport, null, dataSource)); // 用 Html 组件显示报表 Html htmlReport = new Html(reportHtml); htmlReport.setSizeFull(); add(htmlReport);
修复 JRDataSource 方案
之前用 JRDataSource 失败,大概率是数据源绑定问题:
- 确保
JRDataSource实现(比如JRBeanCollectionDataSource)中的 bean 属性名,与 Jasper 模板里的字段名完全匹配(大小写敏感) - 填充报表时传入正确的参数和数据源,示例:
Map<String, Object> parameters = new HashMap<>(); parameters.put("ReportTitle", "销售统计报表"); JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, parameters, dataSource);
内容的提问来源于stack exchange,提问作者Ashutosh Shendye
相关产品推荐
相关产品推荐

