jasper report 子报表中嵌套子报表

    科技2022-08-10  98

    上篇记录了主报表中嵌套子报表,用json数据源设计报表,没有问题了。

    本篇记录下子报表中再嵌套子报表(即孙报表)怎么实现。

    思路:把需要再嵌套孙报表的子报表sub_report3,当做主报表设计,内嵌的孙报表同样用分组布局放置。

    1、设计sub_report3报表布局

    如下图所示:

    建立了2个group,要嵌入4个子报表。

    sub_report3的json数据源如下:

    { "data":{ "isImport":"true", "applyer":"张三", "applyTime":"2020-09-26 10:11:11", "chiefer":"李四", "chiefTime":"2020-09-26 11:11:11", "pm":"王五", "pmTime":"2020-09-26 12:11:11", "lineItems1":[ { "isAgree":"同意", "signRemark":"这就是我要发表的意见,听不听1", "userName":"紫薯1" },{ "isAgree":"同意", "signRemark":"这就是我要发表的意见,听不听2", "userName":"紫薯" },{ "isAgree":"同意", "signRemark":"这就是我要发表的意见,听不听3", "userName":"紫薯2" } ], "lineItems2":[ { "isAgree":"不同意", "signRemark":"这就是我要发表的意见,听不听4", "userName":"紫薯1" },{ "isAgree":"同意", "signRemark":"这就是我要发表的意见,听不听6", "userName":"紫薯3" } ], "lineItems3":[ { "isAgree":"不同意", "signRemark":"这就是我要发表的意见,听不听5", "userName":"紫薯2" },{ "isAgree":"同意", "signRemark":"这就是我要发表的意见,听不听7", "userName":"紫薯4" },{ "isAgree":"同意", "signRemark":"这就是我要发表的意见,听不听8", "userName":"紫薯5" } ], "lineItems4":[ { "isAgree":"同意", "signRemark":"这就是我要发表的意见,听不听9", "userName":"紫薯6" },{ "isAgree":"同意", "signRemark":"这就是我要发表的意见,听不听2", "userName":"紫薯3" },{ "isAgree":"同意", "signRemark":"这就是我要发表的意见,听不听6", "userName":"紫薯4" } ] } }

    布局设计的几点:

    1)本例中主报表的内容宽度:550px,所有子报表的内容宽度也是550px。所以各个元素的设计宽度都是按照这个尺寸来的。

    部门一列:100px;意见列:360px(4个90px);签字列:90px

    2)部门列:StaticText,高度不固定

    Stretch Type属性:ContainerHeight,边框:上、左、右有边框线,底部没有。

    2、创建4个子报表

    4个主报表设计如下图所示:

    子报表的页面设置:margins 都设置为0

    3、子报表与孙报表数据关联

    1)添加子报表控件,选择已经存在的子报表文件:

    2)Use a JRDatasource expression:

    ((net.sf.jasperreports.engine.data.JsonDataSource)$P{REPORT_DATA_SOURCE}).subDataSource("lineItems1")

    3)设置Dataset Parameters

    预览sub_report3报表:

    4、关联主报表的数据源

    首先将数据整合在同一个json数据源,如下:

    test3是sub_report3的数据源。

    { "data":{ "topic":"我就是可爱的topic", "serialNo":"A98K-002-001", "isImport":"true", "isChecked":"false", "noReason":"之所以没选中,是为了测试", "test1":[ { "field1":"我是field1-row1", "field2":"我是field2-row1", "field3":"我是field3-row1", "field4":"我是field4-row1", "field5":"我是field5-row1" }, { "field1":"我是field1-row2", "field2":"我是field2-row2", "field3":"我是field3-row2", "field4":"我是field4-row2", "field5":"我是field5-row2" }, { "field1":"我是field1-row3", "field2":"我是field2-row3", "field3":"我是field3-row3", "field4":"我是field4-row3", "field5":"我是field5-row3" } ], "test2":[ { "name":"MISS李", "tel":"12345678", "email":"12345689@qq.com" }, { "name":"MISS张", "tel":"12345679", "email":"12356789@qq.com" }, { "name":"MISS王", "tel":"12345689", "email":"12346789@qq.com" } ], "test3":{ "isImport":"true", "applyer":"张三", "applyTime":"2020-09-26 10:11:11", "chiefer":"李四", "chiefTime":"2020-09-26 11:11:11", "pm":"王五", "pmTime":"2020-09-26 12:11:11", "lineItems1":[ { "isAgree":"同意", "signRemark":"这就是我要发表的意见,听不听1", "userName":"紫薯1" },{ "isAgree":"同意", "signRemark":"这就是我要发表的意见,听不听2", "userName":"紫薯" },{ "isAgree":"同意", "signRemark":"这就是我要发表的意见,听不听3", "userName":"紫薯2" } ], "lineItems2":[ { "isAgree":"不同意", "signRemark":"这就是我要发表的意见,听不听4", "userName":"紫薯1" },{ "isAgree":"同意", "signRemark":"这就是我要发表的意见,听不听6", "userName":"紫薯3" } ], "lineItems3":[ { "isAgree":"不同意", "signRemark":"这就是我要发表的意见,听不听5", "userName":"紫薯2" },{ "isAgree":"同意", "signRemark":"这就是我要发表的意见,听不听7", "userName":"紫薯4" },{ "isAgree":"同意", "signRemark":"这就是我要发表的意见,听不听8", "userName":"紫薯5" } ], "lineItems4":[ { "isAgree":"同意", "signRemark":"这就是我要发表的意见,听不听9", "userName":"紫薯6" },{ "isAgree":"同意", "signRemark":"这就是我要发表的意见,听不听2", "userName":"紫薯3" },{ "isAgree":"同意", "signRemark":"这就是我要发表的意见,听不听6", "userName":"紫薯4" } ] } } }

    整合到主报表后,预览,报错:

    抛出 net.sf.jasperreports.engine.JRException: Resource not found at: xxx.jasper 异常。

    原因:主报表找不到孙报表的编译文件

    解决办法:

    在主报表中设置变量:SUBREPORT_DIR(若不存在则新建),代表子报表模板文件的真实路径。

    设置子报表的属性Subreport Expression 的值为:$P{SUBREPORT_DIR} + "/sub_report3.jasper",通过程序动态设置SUBREPORT_DIR,使得主报表 能够获得子报表模板文件的真实路径。

    传递参数:

    将SUBREPORT_DIR参数一层一层传递下去。

    这样子报表嵌套子报表就可以显示数据啦

     

     

    Processed: 0.015, SQL: 8