欢迎参与讨论,转载请注明出处。
前言
先看最后的效果图:
我们以问答的形式阐述上图中的难点:
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为数据源。
注意:如果Read attributes
点击没有反应,要检查步骤2的classpath路径中是否包含全部的实体类,比如Poorder.class
中还包含了BillType.class
,所以必须包含此实体类,否则会设置失败。 - 将主报表Fields中的变量拖入到
Detail 1
band中,并在Column Header
band中添加列名,注意宽度要上下一致。注意Fields中的poorderEntrys
变量不是用于显示,而是作为子报表的数据源,后面会提到。 - 同时选中要合并行的Fields,设置属性
Stretch Type
为Relative to Band Heigh
,注意,这是关键。
子报表相关配置
- 在组件面板中拖动
Subreport
控件到主报表的Detail 1
band中,软件会自动弹出向导,依次选择Create a new report
->Blank A4
下一步->Empty datasoure
->下一步(没有可选的Fields)->下一步(不填写任何Group)->Report
name
、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 1
band以外的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
工具类如下:站在了大神的肩膀上!
|
|