Jasper Reports 使用 comparatorExpression 进行交叉表排序
我正在尝试根据某些自定义方案对交叉表中的动态列进行排序。
在文档中,我发现提到了comparatorExpression:交叉表组存储桶比较器表达式。这个表达式的结果是 用于按升序或降序对存储桶进行排序。如果没有比较器 指定了表达式,将使用自然顺序。
但我不明白表达式应该是什么样子。我可以使用常规的 java 比较器吗?有人可以分享一个例子吗?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我遇到了同样的问题,没有找到任何示例或解释,但我找到了如何做到这一点。我会解释一下,希望其他人可以使用这个解决方案。
我已将下面的代码用于 jasperreports 3.1.0 和 iReport 3.1.4,但我想它几乎适用于所有版本。
首先,您必须确保您知道行/列组的存储桶表达式中的类。默认情况下,这是 java.lang.String,但我在那里有一个自定义类。为此,我需要为我的列组编辑 xml,如下所示:
显然
,此 customObj 值是一个具有相应类的字段,在报表本身中定义。
然后您需要添加一个 Comparator 作为参数,例如:
现在在 jasperreport 中添加这样一个 OVERRIDE_Comparator 参数,使用 java.util.Comparator 参数类。
最后一步:将 $P{OVERRIDE_Comparator} 作为比较器表达式放入您需要的行/列组中。
编译此类报告时,最可能的编译错误是转换问题。 Jasperreports 默认为 java.lang.String,您可能需要手动编辑报告的 xml 以在每一步获取正确的类。
(我从一些亚洲网站找到了这个方法,幸运的是代码本身是可读的!:-))
I've had the same issue and did not find any examples or explanation but I found how to do it. I'll explain, so hopefully other people can use this solution.
I've used the code below for jasperreports 3.1.0 and iReport 3.1.4, but I guess it works for pretty much all versions.
First you'll have to make sure that you know wich class you have in the bucket expression for your row/column group. By default this is java.lang.String, but I have a custom class there. For this to work I needed to edit the xml like this for my column group:
to
Obviously this customObj value is a field with the corresponding class, defined in the report itself.
Then you'll need to add a Comparator as a parameter, for example:
Now add such a OVERRIDE_Comparator parameter in the jasperreport, using the java.util.Comparator Parameter Class.
Final step: Put $P{OVERRIDE_Comparator} as the Comparator Expression in the row/column group you needed.
When compiling such a report, the most likely compile error would be casting issues. Jasperreports defaults to java.lang.String, you might need to edit the xml of the report manually to get the correct class at each step.
(I found out this method from some asian site, thankfully the code itself was readable! :-) )
可能有更简单和直接的解决方案:
我正在使用 Jasper Reports Studio(Eclipse 插件)。
最终没有为我工作:-( ...(参见 1.我的答案下面的评论 - 可能是一个错误)您只需检查[x]数据在交叉表属性中预先排序。
当然,只有当您不需要根据预先排序的结果集在报告中的其他位置进行另一次排序时,这才有效。
使用不可见的交叉表组标题,这是相当棘手的:
Row Group1
或类似的名称总位置
设置为无
(我们不希望每行/列生成总列)name="invisible sort column ..."
如果您在群组中使用群组总计(
总排名
!=无
)那么您必须基本上将这些总计元素/设置移动到第一个虚拟排序组,因为否则总计将不再显示在每个组列/行之后的总计(=每第二组总计),例如(这里只用列组来展示,行组也遵循同样的原理)最简单的方法可能是在 XML 中执行此操作,类似于此转换(不要忘记移动
totalPosition=...
和columnTotalGroup=...
属性并更改总和(如果适用于您的场景)$V{SomeSum_..._ALL}
):<前><代码>...
...
...<交叉表TotalColumnHeader>
<单元格内容/>>
<列组名称=“X”...totalPosition=“结束”>
...
<交叉表TotalColumnHeader>
<单元格内容...>
...
...
...
...
=>
<前><代码>...
...
...<交叉表TotalColumnHeader>
<单元格内容...>
...
<列组名称=“X”...>
...
<交叉表TotalColumnHeader>
<单元内容/>>
...
...
;
...
...
(可以跳过:)删除不必要生成的
单元格$F{ORDER_FOR_X}
值类名称
分配给java.lang.Integer
或此处适合您值的任何内容(看看在您的数据集中分配哪种类型(如果您通过某些列使用它)添加一些变量表达式到原始组的
Order By Expression
中,例如$V{ORDER_FOR_X}
$V{...}
就是窍门,不要使用$F{...}
!意思是如果您可以提供一些定义排序并与要排序的列值相关的字段,例如(Oracle SQL)
否则你当然也可以在这里使用其他东西
如果你应该得到一些
<前><代码>...
引起原因:java.lang.NullPointerException
在 org.apache.commons.collections.comparators.ComparableComparator.compare(ComparableComparator.java:92)
在net.sf.jasperreports.crosstabs.fill.BucketExpressionOrderer.compareOrderValues(BucketExpressionOrderer.java:70)
...
您可以简单地将表达式更改为
$V{ORDER_FOR_X} == null ? 0 : $V{ORDER_FOR_X}
应该可以解决问题将虚拟组的所有高/宽字段设置为
0
,并将文本字段打印当表达式
为false
时
使用基于度量总计的排序 (如底部链接所述)
使用 >自定义 Java Comparator 类(如 Pieter VN 2011-11-16 的答案中所述)
我发现的进一步可能有用的链接:
There may be much easier and straight forward solutions:
I am using Jasper Reports Studio (Eclipse Plugin).
did not finally work for me :-( ... (see 1. comment below my answer - may be a bug) you just can check [x] Data Pre Sorted in the Crosstab Properties.
Of course this only works if you do not need another ordering somewhere else in the report based on the pre-sorted result set.
using an invisible crosstab group header, which is rather tricky:
Row Group1
or similar as is for nowTotal Position
toNone
(we do not want to have a total column per row/column generated)name="invisible sort column ..."
if you are using group totals on your group (
Total Position
!=None
) then you have to basically move these totalling elements/settings to the first dummy sort group, because otherwise the totals will be no totals anymore (= per 2nd group totals) displayed after each group column/row, e.g. (here only shown with column group, but row group follows the same principle)easiest may be to do this in the XML similar to this transformation (do not forget to move the
totalPosition=...
andcolumnTotalGroup=...
attributes and to change the sum if applicable to your scenario$V{SomeSum_..._ALL}
):=>
(may be skipped:) remove unnecessarily generated
<crosstabCell ... column/rowTotalGroup="...">
cells$F{ORDER_FOR_X}
Value Class Name
tojava.lang.Integer
or whatever fits for your values here (have a look at your dataset which type is assigned there if your are using it via some column)add some variable expression to the
Order By Expression
of the original group, e.g.$V{ORDER_FOR_X}
$V{...}
is the trick, do not use$F{...}
!meaning if you can provide some field that defines the sort and relates to your to-be-sorted column value, e.g. (Oracle SQL)
otherwise you can of course use something else here as well
if you should get some
you can simply change the expression to
$V{ORDER_FOR_X} == null ? 0 : $V{ORDER_FOR_X}
which should do the trickset all high/width fields of the dummy group to
0
and the text fieldsPrint When Expression
tofalse
using an order by based on measure totals (as described in the bottom link)
using a custom Java Comparator class (as described in the answer from Pieter VN 2011-11-16)
further maybe helpful links I found:
orderByExpression
通常对交叉表列进行排序的方法是使用
orderByExpression
Integer
),bucket
中的orderByExpression
中的度量comparatorExpression
设置 Comparator(在java es中创建一个类。
MyCustomComparator
实现了Comparator
)Comparable
如果您要显示自己对象的值(
$F{MyField}
是用户定义的对象),您可以简单地实现 Comparable 以显示您喜欢的顺序。orderByExpression
The way to order crosstab columns normally is by using the
orderByExpression
Integer
)orderByExpression
in thebucket
comparatorExpression
Set a Comparator (create a class in java es.
MyCustomComparator
that implementsComparator
)Comparable
If you are displaying value from own object (
$F{MyField}
is a user defined object) you can simple implement Comparable to display the order as you like.