Java Injection in Jasper Reports

I needed to create a JasperReports variable of type NumberFormat to format dollars without cents.

Try to stay calm while reading this.

JasperReports allows the creation of variables that can be evaluated at report run time. The variables can be of any Java object type. You can set the value of the variable to be the result of any Java expression that evaluates to the same type as the object variable (which cannot be void).

I created a JasperReports variable named “nfc” for (number format currency) and set it up to be of type java.text.NumberFormat. Then I set its value to be NumberFormat.getCurrencyInstance()

java-injection-1

It’s convenient to use in fields throughout my report:

$V{nfc}.format($F{assets})

That worked, but to my chagrin, getCurrencyInstance() returns a formatter that includes two decimal places for cents. In free-form Java of course, we’d just call setMaximumFractionDigits(0) on the formatter, and be rid of the wretched pennies. But in JasperReports we can only evaluate Java “expressions.” Because setMaxiumFractionDigits returns void, it can’t be used as an expression.

Luckily I figured out a way to inject arbitrary Java into the JasperReports expression evaluator. You can do this in iReport or straight in the jrxml file.

Here’s how:
1. Create a variable: (View->Variables->New)
2. Type in the type: java.text.NumberFormat
3. Set the value to:

java-injection-2

NumberFormat.getCurrencyInstance()
);
System.out.println( "Hello World! Java Injection!" );
((NumberFormat)value).setMaximumFractionDigits(0

There are two things to notice:

A. The fun begins with ); That is what JasperReports expression evaluator sticks at the end of your expression when it compiles. After you provide your own ); to complete that expression evaluation, you can add any Java statements you like. Just remember when you’re done, leave off the trailing ); because the expression evaluator will tack that onto the end.

B. “value” is the name of the temporary variable that will contain the result of your expression. In order to call setMaximumFractionDigits on my NumberFormat object, I first have to cast “value” to NumberFormat.

Here’s how that variable looks in the JasperReports xml (jrxml) file:

<variable name=”nfc” class=”java.text.NumberFormat” resetType=”Report” calculation=”Nothing”>
<variableExpression> <![CDATA[
NumberFormat.getCurrencyInstance()
);
System.out.println( "Hello World! Java Injection!" );
((NumberFormat)value).setMaximumFractionDigits(0
]]>
</variableExpression>
</variable>

Note: JasperReports also allows the use of Java ‘Scriptlets’ that would solve this problem, but I didn’t want to use that feature because it would force other users of my report to get the pre-compiled external class file into their classpath, yadda blah blah ClassNotFoundException blah half-the-day-wasted yadda yadda… My point is that I wanted the JasperReports XML to stand on its own three feet, shielding everyone else from external dependencies.

UPDATE: I have now learned that JasperReports has formatting built in and while this Java injection technique is “cool”, it is not necessary for number formatting. Here’s what I eventually figured out: In iReport, right click on the number field, choose Properties, click on the “Text Field” tab, and then enter #,##0.0 in the Pattern box. This example will round to one decimal digit. You can use any pattern supported by java.text.NumberFormat.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值