开发者

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:

  1. 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).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜