Question

I have a list of objects that I am building a report for. One of the attributes of the object is a JodaTime LocalDate object. I would like this date to be included in my report, so I do something like:

.addColumn("Shipout", "shipout", LocalDate.class.getName(),50)

which results in the following error:

net.sf.jasperreports.engine.design.JRValidationException: Report design not valid : 
    1. Class "org.joda.time.LocalDate" not supported for text field expression.

That's fine, but there must be some way that I can add a LocalDate column type - I haven't been able to find anything like this in the documentation.

The closest thing I can find is a CustomExpression, but all of the examples refer to doing things like composite columns.

What is the right way to do it?

Thanks!

Was it helpful?

Solution

The JasperReports version 3.7.1 (supported by DynamicJasper version 3.1.9) supports only this classes for text field's expression:

  • java.lang.Boolean
  • java.lang.Byte
  • java.util.Date
  • java.sql.Timestamp
  • java.sql.Time
  • java.lang.Double
  • java.lang.Float
  • java.lang.Integer
  • java.lang.Long
  • java.lang.Short
  • java.math.BigDecimal
  • java.lang.Number
  • java.lang.String

You can make sure this fact looking at source code of this method from net.sf.jasperreports.engine.design.JRVerifier class:

private static synchronized String[] getTextFieldClassNames()
{
    if (textFieldClassNames == null)
    {
        textFieldClassNames = new String[]
        {
            java.lang.Boolean.class.getName(),
            java.lang.Byte.class.getName(),
            java.util.Date.class.getName(),
            java.sql.Timestamp.class.getName(),
            java.sql.Time.class.getName(),
            java.lang.Double.class.getName(),
            java.lang.Float.class.getName(),
            java.lang.Integer.class.getName(),
            java.lang.Long.class.getName(),
            java.lang.Short.class.getName(),
            java.math.BigDecimal.class.getName(),
            java.lang.Number.class.getName(),
            java.lang.String.class.getName()
        };

        Arrays.sort(textFieldClassNames);
    }

    return textFieldClassNames;
}

private void verifyTextField(JRTextField textField)
{
    verifyReportElement(textField);
    verifyFont(textField);
    verifyAnchor(textField);
    verifyHyperlink(textField);

    if (textField != null)
    {
        JRExpression expression = textField.getExpression();

        if (expression != null)
        {
            try
            {
                String className = expression.getValueClassName();
                if (className == null)
                {
                    addBrokenRule("Class not set for text field expression.", expression);
                }
                else if (Arrays.binarySearch(getTextFieldClassNames(), className) < 0)
                {
                    addBrokenRule("Class \"" + className + "\" not supported for text field expression.", expression);
                }
            }
            catch (JRRuntimeException e)
            {
                addBrokenRule(e, expression);
            }
        }
    }
}

As you can see the verifyTextField method generates this message in your case.

The full stack trace:

  1. Class "org.joda.time.LocalDate" not supported for text field expression. net.sf.jasperreports.engine.design.JRValidationException: Report design not valid :
  2. Class "org.joda.time.LocalDate" not supported for text field expression. at net.sf.jasperreports.engine.design.JRAbstractCompiler.verifyDesign(JRAbstractCompiler.java:258) at net.sf.jasperreports.engine.design.JRAbstractCompiler.compileReport(JRAbstractCompiler.java:140) at net.sf.jasperreports.engine.JasperCompileManager.compileReport(JasperCompileManager.java:215) at ar.com.fdvs.dj.core.DynamicJasperHelper.generateJasperReport(DynamicJasperHelper.java:542) at ar.com.fdvs.dj.core.DynamicJasperHelper.generateJasperReport(DynamicJasperHelper.java:518) at ar.com.fdvs.dj.core.DynamicJasperHelper.generateJRXML(DynamicJasperHelper.java:403)

I think you should try to use scriptlet. Here is the sample.

OTHER TIPS

You could just use a function e.g. getLocalDateAsString and implement this function with a return value of String in the POJO or ValueObject.

For example, In the Layouter

drb.addColumn("LocalType", "localTypeAsString", String.class.getName(), 50)

In the Entity:

public String getLocalTypeAsString() {
        String ret = null;
        if (mannschaftsTyp!=null) {
            ret = localType.getShortDescr();
        }
        return ret;
    }

DJ cannot support what JR doesn't give. But you can create a CustomEpression Or ValueFormatter and convert the data as you need. You only need a few lines. Because the type is unsupported, declare its type as object, then in the custom expression or value formatter downcast and operate as necessary

See http://dynamicjasper.com/2010/10/06/how-to-create-value-formatter/

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top