Jasper Reports - custom format factory does not use defined formatter classes
I'm working with Jasper Reports, version 3.7.5.
I'm trying to use a custom FormatFactoy implementation to handle the case of an empty string representation ( "" ) of the XML data for a date field. I implemented a class implementing FormatFactory which should handle that.
public class InvoicePrintFormatFactory implements FormatFactory {
@Override
public DateFormat createDateFormat(String string, Locale locale, TimeZone tz) {
DateFormat format = new SimpleDateFormat(string, locale){
@Override
public Date parse(String source) throws ParseException {
if((source == null) || (source.equals("")))
return null;
return super.parse(source);
}
}
return format;
}
@Override
public NumberFormat createNumberFormat(String string, Locale locale) {
NumberFormat format = new DecimalFormat(string){
@Override
public Number parse(String source) throws ParseException {
if((source == null) || (source.equals("")))
return null;
return super.parse(source);
}
}
return format;
}
}
In my JRXMLDatsource
I set the source format patterns like this:
JRXmlDataSource reportSource = new JRXmlDataSource(document, headRecordPath);
reportSource.setDatePattern("mm.dd.yy");
reportSource.setNumberPattern("####0.00");
and of course handing over a instance of my FormatFactory
reportParams.put(JRParameter.REPORT_FORMAT_FACTORY, new InvoicePrintFormatFactory());
Everything works fine here if the datasource XML does not contain "" values for a date field. But if that happens I get the following exception:
org.apache.commons.beanutils.ConversionException: Unparseable date: ""
at org.apache.commons.beanutils.locale.BaseLocaleConverter.convert(BaseLocaleConverter.java:241)
at org.apache.commons.beanutils.locale.LocaleConvertUtilsBean.convert(LocaleConvertUtilsBean.java:285)
at net.sf.jasperreports.engine.data.JRAbstractTextDataSource.convertStringValue(JRAbstractTextDataSource.java:69)
at net.sf.jasperreports.engine.data.JRXmlDataSource.getFieldValue(JRXmlDataSource.java:313)
at net.sf.jasperreports.engine.fill.JRFillDataset.setOldValues(JRFillDataset.java:821)
at net.sf.jasperreports.engine.fill.JRFillDataset.next(JRFillDataset.java:785)
at net.sf.jasperreports.engine.fill.JRBaseFiller.next(JRBaseFiller.java:1482)
at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillReport(JRVerticalFiller.java:126)
at net.sf.jasperreports.engine.fill.JRBaseFiller.fill(JRBaseFiller.java:946)
at net.sf.jasperreports.engine.fill.JRBaseFiller.fill(JRBaseFiller.java:864)
at net.sf.jasperreports.engine.fill.JRFiller.fillReport(JRFiller.java:84)
at net.sf.jasperreports.engine.JasperFillManager.fillReport(JasperFillManage开发者_开发百科r.java:624)
at com.lmobile.crm.invoicePrinter.operator.Printer.operate(Printer.java:219)
at com.lmobile.crm.invoicePrinter.service.InvoicePrintService.CreatePrintOrder(InvoicePrintService.java:39)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at za.co.softco.rest.ReflectionService.handle(ReflectionService.java:253)
at za.co.softco.rest.ReflectionHandler.handle(ReflectionHandler.java:94)
at za.co.softco.rest.RestWorker.handlePost(RestWorker.java:477)
at za.co.softco.rest.RestWorker.handleClient(RestWorker.java:289)
at za.co.softco.rest.RestWorker.run(RestWorker.java:152)
at java.lang.Thread.run(Thread.java:680)
Caused by: java.text.ParseException: Unparseable date: ""
at java.text.DateFormat.parse(DateFormat.java:337)
at net.sf.jasperreports.engine.util.JRDateLocaleConverter.parse(JRDateLocaleConverter.java:84)
at org.apache.commons.beanutils.locale.BaseLocaleConverter.convert(BaseLocaleConverter.java:230)
... 23 more
If I debug the method calls for my custom FormatFactory implementation I observe that both methods are not being called until running into the exception. Thus I assume that Jasper is using the default FormatFactory for some reason.
What did I do wrong here? Do anybody have an idea about this?
Thanks in advance.
I found a tutorial and it worked for me, basically i see some differences between your code and the code in the tutorial.
First. Instead of implement FormatFactory
you must extend DefaultFormatFactory
Second. You must not pass the class as a parameter, only configure it in the class path of the iReport.
This is the link post to jasperreports community
The answer was posted by the user thangalin I will copy and paste the answer just in case the post gets lost.
The following seems to work:
- Click Window >> Preferences >> Select Capabilities >> Check Development >> Click OK
Next:
- Open the Project Explorer Right-click Project name Select Properties Select Java Build Path Click the Source tab Click Add Folder Select Create New Folder Set Folder Name to: src Click Finish Select src Click OK Set Default output folder: Project Name/build Click OK Create a report as usual (with a text field that uses a date, either a parameter or a field),
Then:
Select the report in the Outline panel Open the Properties panel Set Format Factory Class to: com.company.reports.ReportFormatFactory Next, create some source code inside the "src" directory in a package (folder) named "com.company.reports". Paste the following into a file named "ReportFormatFactory.java" that is saved in that directory:
import java.text.DateFormat;
import java.util.Locale;
import java.util.TimeZone;
import net.sf.jasperreports.engine.util.DefaultFormatFactory;
/**
* Delegates creation of date and number formatters to JasperReports' default
* formatters. This class ensures that dates are formatted consistently across
* all reports.
*/
public class ReportFormatFactory extends DefaultFormatFactory {
/**
* Returns a DateFormat instance that creates dates in YYYY/MM/dd format.
*
* @param pattern Unused.
* @param locale Passed to the DefaultFormatFactory instance.
* @param timezone Passed to the DefaultFormatFactory instance.
*
* @return An object that can format dates.
*/
@Override
public DateFormat createDateFormat(
String pattern, Locale locale, TimeZone timezone ) {
return super.createDateFormat( "YYYY/MM/dd", locale, timezone );
}
}
When you run the report, the date should be formatted as YYYY/MM/dd.
If you want to change the format (e.g., to "dd/MM/YYYY"), update the date format line in the source code and then restart Jaspersoft Studio (the classloader does not seem to reload the ReportFormatFactory class after modification).
精彩评论