欢迎参与讨论,转载请注明出处。
前言
先看最后的效果图:
我们以问答的形式阐述上图中的难点:
1. 图中的合并行是如何实现的?
答:主报表中包含了子报表,并设置了‘想要合并行’的相关属性。
2. 图中的小计和合计是如何实现的?
答:把子报表统计的值传入主报表。
数据准备
  ireport有多种数据填报方式,本例是用JavaBean填充,如果您已经是老油条,请直接跳过前段部分,直接看最后的技术实现。
- Java实体类 1234567891011121314Poorder.class关键属性:private String FBillNO;//单据编号private BillType billType;//单据类型private Date FPurchaseDate;//采购日期private List<PoorderEntry> poorderEntrys = new ArrayList<PoorderEntry>();//采购订单明细PoorderEntry.class关键属性:private Integer FSeq;//序号private Material material;//物料实体类private PoorderEntryF poorderEntryF;//财务实体类说明:`Poorder.class`和`PoorderEntry.class`是主要的两个实体类,存在一对多的关系,其它实体类比如`BillType`、`PoorderEntryF`只是数据的载体,存放了相关信息。
- 在数据库中填写假数据,并且编写好查询的接口,作为报表的数据源。 
制作模板
主报表相关配置
- 新建名称为POORDER_TEMPLATE作为主报表。
- 在ireport中设置classpath属性,即项目编译输出的路径,如果已经设置了请忽略。
- 点击 选择Java为数据源。 选择Java为数据源。 
 注意:如果Read attributes点击没有反应,要检查步骤2的classpath路径中是否包含全部的实体类,比如Poorder.class中还包含了BillType.class,所以必须包含此实体类,否则会设置失败。
- 将主报表Fields中的变量拖入到Detail 1band中,并在Column Headerband中添加列名,注意宽度要上下一致。注意Fields中的poorderEntrys变量不是用于显示,而是作为子报表的数据源,后面会提到。
 同时选中要合并行的Fields,设置属性 同时选中要合并行的Fields,设置属性- Stretch Type为- Relative to Band Heigh,注意,这是关键。
子报表相关配置
- 在组件面板中拖动Subreport控件到主报表的Detail 1band中,软件会自动弹出向导,依次选择Create a new report->Blank A4下一步->Empty datasoure->下一步(没有可选的Fields)->下一步(不填写任何Group)->Reportname、Location、File可以自己定义,下面的选择第一个选项:Store the directory name in a parameter,(即选择相对路径,在java代码中需要构建map,并且添加key值为SUBREPORT_DIR,用于指定子报表的路径,后面会提到)->Use a JRDatasource expression 在框中填写new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($F{poorderEntrys})。
 *注意:不按照向导也可以,在主报表界面,点击子报表,查看右边栏的属性也可以进行设置。
- 点开子报表,选择JavaBean为数据源,java填写PoorderEntry类,把需要的属性添加到Fields中。
- 把除Deatil 1band以外的band高度设置为0,或者在左侧栏在对应的band上右键点击删除。
- 将Fields中的变量拖动到Deatil 1中 
- 注意:子报表的Fields中,有物料material,在导出报表时,是一个Material对象,因此在获取物料名称时,将Text Field Expression设置为:$F{material}.getFName(),其它情况以此类推。
统计相关属性配置
  通过以上的步骤,相信已经达到可以动态合并行的效果。接下来要实现的是小计、合计。
a. 在子报表中,添加sumAmount和sumFQty变量,前者用于统计金额的总数量,后者用于统计总物料数量。点击sumAmount,属性面板如图所示:
- Name:sumAmount
- Variable Class:java.math.Bigdecimal 注意这里设置的java类型和要统计的Amount的java类型要相同,否则求和会出现异常。
- Calculation:Sum
- Reset type:report
- Increment type:None
- Variable Expression:$F{poorderEntryF}.getFAmount()
 关于sumFQty和以上设置的相同,只是Variable Expression中设置为:$F{FQty}
 b. 打开主报表,创建getSumAmount、getSumFQty和totalAmount变量,点击getSumAmount,属性面板如下图所示: 
- Name:getSumAmount
- Variable Class:java.math.Bigdecimal 注意这里设置的java类型和要统计的Amount的java类型要相同,否则求和会出现异常。
- Calculation:Nothing 这里不进行计算,只用于从子报表获取数据
- Reset type:report
- Increment type:None
- Variable Expression: 不填
 注意:getSumAmount和getSumFQty属性设置都同上,两个属性都用于小计。totalAmount的属性和以上基本相同,只是Calculation属性为Sum,用于整个报表范围的统计。
 c. 将getSumAmount、totalAmount和getSumFQty拖动到主报表的Detail 1中,如图所示: 
- 上图红色圈起来的有四个元素,分别是两个Static Text和两个Text Field,同时选中这四个元素,设置属性Position Type为Fix Relative to Bottom,这样才不会和上面的元素重叠。
- 同时选中图中红色圈1的两个Text Field(即getSumAmount和getSumFQty)设置属性Evaluation Time为Band;选中圈2的Text Field(即totalAmount)设置属性Evaluation Time为Report,注意圈2所在Band为Summary 
 d. 在主报表中,点击子报表,设置属性Return Values:添加三项设置如下图所示: 用于主表和子表的属性传递,其中前两项的属性一致,且 用于主表和子表的属性传递,其中前两项的属性一致,且Calculation type为Nothing,因为两者只是简单的数据传递;而最后一项的属性Calculation type为Sum,用于整个报表的统计。
 至此小计和合计功能已经实现。外观和字体配置
- 需要给组成表格的每一个元素设置边框,这样可以实现表格的效果。
- 设置各个元素居中显示
- 在要显示中文的元素中,设置三个属性:Pdf Font name is now属性为:STSong-Light,Pdf Embedded打钩,Pdf Encoding属性为:UniGB-UCS2-H (Chinese Simplified),以此避免导出PDF中文乱码的问题。同时在项目中要导入亚洲字体itext-**.jar和iTextAsian.jar
JAVA相关
- 导入jasperreports-**.jar包。
- 相关代码如下: 
 其中JasperHelper工具类如下:站在了大神的肩膀上!
| 
 | 
 |