【问题标题】:DynamicJasper addColumn to fastreportbuilder with non-supported data type具有不受支持的数据类型的 DynamicJasper addColumn 到 fastreportbuilder
【发布时间】:2011-11-06 20:42:41
【问题描述】:

我有一个我正在为其构建报告的对象列表。对象的属性之一是 JodaTime LocalDate 对象。我希望将此日期包含在我的报告中,因此我会执行以下操作:

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

导致以下错误:

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

没关系,但我必须有某种方法可以添加 LocalDate 列类型 - 我无法在文档中找到类似的内容。

我能找到的最接近的东西是 CustomExpression,但所有示例都涉及到复合列之类的操作。

正确的做法是什么?

谢谢!

【问题讨论】:

    标签: java reporting jasper-reports dynamic-jasper


    【解决方案1】:

    JasperReports 3.7.1 版(DynamicJasper 3.1.9 版支持)仅支持文本字段表达式的此类:

    • 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

    您可以通过查看net.sf.jasperreports.engine.design.JRVerifier 类的此方法的源代码来确定这一事实:

    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);
                }
            }
        }
    }
    

    如您所见,verifyTextField 方法会在您的情况下生成此消息。

    完整的堆栈跟踪:

    1. 文本字段表达式不支持“org.joda.time.LocalDate”类。 net.sf.jasperreports.engine.design.JRValidationException: 报告设计无效:
    2. 文本字段表达式不支持“org.joda.time.LocalDate”类。在 net.sf.jasperreports.engine.design.JRAbstractCompiler.verifyDesign(JRAbstractCompiler.java:258) 在 net.sf.jasperreports.engine.design.JRAbstractCompiler.compileReport(JRAbstractCompiler.java:140) 在 net.sf.jasperreports.engine.JasperCompileManager.compileReport(JasperCompileManager.java:215) 在 ar.com.fdvs.dj.core.DynamicJasperHelper.generateJasperReport(DynamicJasperHelper.java:542) 在 ar.com.fdvs.dj.core.DynamicJasperHelper.generateJasperReport(DynamicJasperHelper.java:518) 在 ar.com.fdvs.dj.core.DynamicJasperHelper.generateJRXML(DynamicJasperHelper.java:403)

    我认为你应该尝试使用 scriptlet。这是sample

    【讨论】:

    • DynamicJasper 的这一方面给我留下了深刻的印象,但我很感激你费心钻研代码库来找到它。
    【解决方案2】:

    你可以只使用一个函数,例如getLocalDateAsString 并在 POJO 或 ValueObject 中用 String 的返回值来实现这个函数。

    例如,在布局器中

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

    在实体中:

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

    【讨论】:

      【解决方案3】:

      DJ 不能支持 JR 不给的东西。但是您可以创建一个 CustomEpression 或 ValueFormatter 并根据需要转换数据。你只需要几行。 因为不支持类型,所以将其类型声明为对象,然后在自定义表达式或值格式化程序中向下转换并根据需要进行操作

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-03-14
        • 1970-01-01
        • 2021-06-12
        • 1970-01-01
        • 1970-01-01
        • 2014-10-23
        • 2022-06-16
        相关资源
        最近更新 更多