java - DynamicReports reportParameters.getFieldValue() 返回错误值

标签 java jasper-reports dynamic-reports

我有以下AbstractSimpleExpression<Boolean>为一些文本着色:

private class UtilisationExpression extends AbstractSimpleExpression<Boolean> {
    private static final long serialVersionUID = 1L;
    private String variableName;
    private String fieldName;

    public UtilisationExpression(String variableName, String fieldName) {
        this.variableName = variableName;
        this.fieldName = fieldName;

    }

    @Override
    public Boolean evaluate(ReportParameters reportParameters) {
        return ((Double) reportParameters.getVariableValue(variableName)
                / (Double) reportParameters.getFieldValue(fieldName) * 100) > 100;
    }
}

文本着色设置如下(initializeStyle()方法包括此。在其他任何事情之前调用):

conditionalFontColorRedMarketValue = stl
        .conditionalStyle(new UtilisationExpression("marketValueSum", "bucket.marketValueLimit"))
        .setForegroudColor(Color.RED);
subTotalStyleBottomBordersRightRedColorMarketValue = stl.style(subTotalStyleBottomBordersRight)
        .addConditionalStyle(conditionalFontColorRedMarketValue).setLinePen(stl.pen1Point());
subTotalStyleBottomBordersRightRedColorMarketValue.getStyle().getBorder().getBottomPen()
                .setLineColor(Color.BLACK);

然后我们在报告中使用它,这有点复杂,因为我使用分组等。我将包含我认为必要的所有内容:

VariableBuilder<Double> valueInEurSumGrp = DynamicReports.variable("marketValueSum", valueInEurColumn,
        Calculation.SUM);
CustomGroupBuilder bookGroup = grp.group("bucketGroup", new BucketExpression()).groupByDataType()
        .setShowColumnHeaderAndFooter(true).setHeaderLayout(GroupHeaderLayout.VALUE).setPadding(0)
        .setStyle(titleStyle).addHeaderComponent(cmp.filler().setFixedHeight(5))
        .addFooterComponent(cmp.filler().setFixedHeight(10)).setReprintHeaderOnEachPage(true)
        .setMinHeightToStartNewPage(15)
        .setPrintSubtotalsWhenExpression(new PrintSubtotalsExpression(valueInEurSumGrp)).keepTogether();
valueInEurSumGrp.setResetGroup(bookGroup);
valueInEurSumGrp.setResetType(Evaluation.GROUP);
FieldBuilder<Double> marketValueLimitField = field("bucket.marketValueLimit", type.doubleType());
// Usage in subtotals
builder.setSubtotalStyle(subTotalStyleNoBordersLeft)
        .subtotalsAtGroupFooter(bookGroup,
                ReportCommon.createSubtotalColumns(subTotalStyleNoBordersLeft,
                        ReportCommon.convertSubtotalsToList(
                                sbt.text("Limit", bookColumn).setStyle(subTotalStyleNoBordersLeft), sbt
                                        .aggregate(marketValueLimitField, valueInEurColumn,
                                                Calculation.NOTHING)
                                        .setStyle(subTotalStyleNoBordersRight).setPattern("#,##0")),
                        columns.toArray(new TextColumnBuilder<?>[] {})))

        .setSubtotalStyle(subTotalStyleBottomBordersLeft)
        .subtotalsAtGroupFooter(bookGroup, ReportCommon.createSubtotalColumns(
                subTotalStyleBottomBordersLeft,
                ReportCommon.convertSubtotalsToList(
                        sbt.text("Utilisation", bookColumn).setStyle(subTotalStyleBottomBordersLeft),
                        sbt.aggregate(
                                new PercentageExpression("bucket.marketValueLimit", valueInEurSumGrp),
                                valueInEurColumn, Calculation.NOTHING)
                                .setStyle(subTotalStyleBottomBordersRightRedColorMarketValue)),
                columns.toArray(new TextColumnBuilder<?>[] {})))
        .addSummary(cmp.filler().setFixedHeight(15));

为了进行比较,PercentageExpression ,它设法计算出正确的百分比:

private class PercentageExpression extends AbstractSimpleExpression<String> {
    private static final long serialVersionUID = 1L;

    private String fieldName;
    private VariableBuilder<Double> valueInEurColumn;

    public PercentageExpression(String fieldName, VariableBuilder<Double> valueInEurSum) {
        this.fieldName = fieldName;
        this.valueInEurColumn = valueInEurSum;
    }

    @Override
    public String evaluate(ReportParameters reportParameters) {
        Double percentage = reportParameters.getValue(valueInEurColumn)
                / (double) reportParameters.getFieldValue(fieldName) * 100;
        return String.format("%,.2f %%", percentage);
    }
}

我省略了一些代码,例如列的初始化和其他样式以及报告本身的很大一部分,因为这与当前的问题无关。

实际问题是 reportParameters.getFieldValue("bucket.marketValueLimit")UtilisationExpression一旦数据被分组到超过 1 个 block 中,就会获取错误的值。如果我只有 1 个组,它可以正常工作,但一旦我有 2 个或更多组,该方法就无法获取正确的值。

我做了一些代码挖掘,发现错误的方法调用委托(delegate)给 JRAbstractScriptlet#getFieldValue(String fieldName) 。在该方法中,它查看 Map<String,JRFillField> fieldsMap;其中包含所有字段。然后我找到了我正在搜索的字段并检查了 JRFillField它包含以下值字段:

private Object previousOldValue;
private Object oldValue;
private Object value;
private Object savedValue;

previousOldValuevalue是错误的值,而 savedValue为空且 oldValue保持我期望的值。在当前组通过小计正确完成之前,似乎已经为下一组设置了值。看来人们实际上可以访问 oldValue是否可以访问JRFillField直接,但我也找不到办法做到这一点。

我已经尝试将其设置为 PercentageExpression (使用 VariableBuilder ),但它具有相同的效果...

有人知道为什么方法调用为每个组返回错误的值吗?我该如何解决这个问题?

<小时/>

对于我在这里转储的所有信息感到抱歉,我不确定解决此问题需要什么。如果您需要更多信息,请询问

最佳答案

我找到了解决这个问题的方法。我没有使用 FieldBuilder,而是从字段创建了 VariableBuilder 并更新了 AbstractSimpleExpression,如下所示:

@Override
public Boolean evaluate(ReportParameters reportParameters) {
    return ((Double) reportParameters.getVariableValue(variableName)
            / (Double) reportParameters.getVariableValue(fieldName) * 100) > 100;
}

设置颜色:

conditionalFontColorRedMarketValue = stl
        .conditionalStyle(new UtilisationExpression("marketValueLimit", "bucketMarketValueLimit"))
        .setForegroudColor(Color.RED);
conditionalFontColorRedRiskValue = stl
        .conditionalStyle(new UtilisationExpression("valueAtRiskLimit", "bucketValueAtRiskLimit"))
        .setForegroudColor(Color.RED);

并设置字段/变量:

FieldBuilder<Double> marketValueLimitField = field("bucket.marketValueLimit", type.doubleType());
FieldBuilder<Double> valueAtRiskLimitField = field("bucket.valueAtRiskLimit", type.doubleType());

VariableBuilder<Double> marketValueLimitVariable = DynamicReports.variable("bucketMarketValueLimit",
        marketValueLimitField, Calculation.NOTHING);
VariableBuilder<Double> valueAtRiskLimitVariable = DynamicReports.variable("bucketValueAtRiskLimit",
        valueAtRiskLimitField, Calculation.NOTHING);

我仍然不确定为什么变量按预期工作而字段却不能按预期工作

关于java - DynamicReports reportParameters.getFieldValue() 返回错误值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57525452/

相关文章:

java - 获取 BufferedImage 作为资源,以便它可以在 JAR 文件中工作

java - 如何让 JasperViewer 优先考虑 PDF 的保存选项

java - DynamicReports 找不到查询参数错误

java - 使用 DynamicReports 时出错 : java. lang.NoSuchFieldError:ELEMENT_GROUP_HEIGHT

javascript - 在 eclipse 中启用 bootstrap 内容辅助

java - 在 @Source ("../../war/example.txt") textresource 客户端 bundle gwt 中提供外部文件路径

Java:使用 Stream API 在嵌套列表中查找常见项目

jasper-reports - 无法在动态碧 Jade 报告中设置横向

java - 处理程序调度失败;嵌套异常是 java.lang.AbstractMethodError : javax. xml.parsers.DocumentBuilderFactory.setFeature(Ljava/lang/String;Z)V

java - 从 BIRT 中的 POJO 生成动态报告