Monday, November 1, 2010

JasperReports & the Format Factory

The more I work with JasperReports, the more I admire the project altogether. It seems like every time when I'm like "I wonder if JasperReports can handle that" it does, and it does it well.

Recently one of those issues had to do with localization, specifically date & number formatting. If you have worked with JasperReports you'll probably know that you can format dates & numbers with the pattern (e.g. "MM/dd/yyyy") attribute on a text field element. That is just fine when the pattern is known at design time. But what do you do when the patterns need to be localized or in other words dynamic?

No you can't use a String parameter as a pattern. The pattern attribute on a text field does not accept an expression, only a string literal. Another solution might be to have your application twiddle the JRXML and inject the proper patterns. But that would be hacky and could easily be error prone.

Enter the Format Factory. The Format Factory concept is simple but powerful. The FormatFactory is an interface in the net.sf.jasperreports.engine.util package that you implement to create your own date & number formats.

public class MyFormatFactory implements FormatFactory {

public DateFormat createDateFormat(String pattern, Locale locale, TimeZone timeZone) {
//create your date format here
return your-date-format ;
}

public NumberFormat createNumberFormat(String pattern, Locale locale) {
// create your number format here
return your-number-format ;
}

}

Essentially, your application takes over format creation instead of the JasperReports engine itself.

The best part of all this is your ability to create formats based on your own defined constants. You'll notice that the two methods in the class above have a "pattern" parameter. That is the pattern that you assign to the textfield.

You might say, hey I thought we weren't using explicit patterns anymore. You're right. But, we have to give a hint as to how the textfield needs to be formatted, so we would use format constants (e.g. SHORT_DATE, LONG_DATE, TIMESTAMP, etc). The constants are assigned to our text fields pattern attribute and get passed to our FormatFactory where we determine how to create a formatter based on those constants. Kinda cool, eh?

You might also notice the timezone & locale parameters in the methods above. Those are also parameters you can pass into the report itself which in turn get passed in to the format factory to assist you in creating the appropriate formats. For example, when you create a date format you'll need to know the time zone since that is an important part of actually formatting a date.

The Format Factory is a fantastic feature. This is especially true for large applications that already have formatting logic implemented in the application allowing you to reuse your existing format logic.