Использование CustomExpression в диаграмме DynamicJasper - PullRequest
4 голосов
/ 14 апреля 2011

У меня есть проект, использующий DynamicJasper для создания отчетов. Пока все работает нормально, но когда я захотел добавить диаграмму в ранее работающий отчет, у меня возникли проблемы.

Я продолжаю получать это:

net.sf.jasperreports.engine.design.JRValidationException: дизайн отчета недействителен: 1. Поле не найдено: customExpression_for_Ganancia в 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) at ar.com.fdvs.dj.core.DynamicJasperHelper.generateJasperReport (DynamicJasperHelper.java:519) at ar.com.fdvs.dj.core.DynamicJasperHelper.generateJasperPrint (DynamicJasperHelper.java:279) at ar.com.fdvs.dj.core.DynamicJasperHelper.generateJasperPrint (DynamicJasperHelper.java:232)

Ganancia является единственным столбцом на диаграмме, который является CustomExpression. Если я не добавлю этот столбец в виде ряда на график, он будет отображаться правильно. Кажется, диаграмма плохо сочетается с выражениями ...

Фрагмент из моего кода:

private DynamicReport buildSalesReport() throws ColumnBuilderException, ClassNotFoundException, ChartBuilderException {

    DynamicReportBuilder drb = new DynamicReportBuilder();

    drb.setReportName("Reporte de Ventas")
        .setTitle("Reporte de ventas")
        .setSubtitle("Este reporte fue generado el " + new Date())
        .setPrintColumnNames(false)
        .setIgnorePagination(true)
        .setMargins(10, 10, 10, 10)
        .setUseFullPageWidth(true);

    Style groupOneStyle = new Style();
            groupOneStyle.setFont(Font.ARIAL_BIG);
            groupOneStyle.setHorizontalAlign(HorizontalAlign.LEFT);
            groupOneStyle.setVerticalAlign(VerticalAlign.MIDDLE);

    AbstractColumn columnDisplayName = ColumnBuilder.getNew()
            .setColumnProperty("bookingType.displayName", String.class.getName())
            .setTitle("Tipo").setWidth(new Integer(40))
            .setStyle(groupOneStyle)
            .build();

    AbstractColumn columnDestiny = ColumnBuilder.getNew()
            .setColumnProperty("bookedObject.destiny", String.class.getName())
            .setTitle("Destino").setWidth(new Integer(40))
            .build();

    Style priceStyle = new Style();
    priceStyle.setHorizontalAlign(HorizontalAlign.RIGHT);

    AbstractColumn columnCurrency = ColumnBuilder.getNew()
            .setColumnProperty("bookedObject.currency.displayName", String.class.getName())
            .setTitle("Cotizacion").setWidth(new Integer(5))
            .setShowText(false)
            .build();

    Style footerStyle = new Style();
            footerStyle.setFont(Font.ARIAL_MEDIUM);
            footerStyle.setBorderTop(Border.THIN);
            footerStyle.setHorizontalAlign(HorizontalAlign.RIGHT);
            footerStyle.setVerticalAlign(VerticalAlign.MIDDLE);

    AbstractColumn columnPrice = ColumnBuilder.getNew()
            .setColumnProperty("bookedObject.price", Double.class.getName())
            .setStyle(priceStyle)
            .setPattern("$ 0.00")
            .setTitle("Precio").setWidth(new Integer(25))
            .build();

    AbstractColumn columnCount = ColumnBuilder.getNew()
            .setColumnProperty("count", Integer.class.getName())
            .setStyle(priceStyle)
            .setTitle("Cantidad").setWidth(new Integer(25))
            .build();

    columnCount.setName("Cantidad");

    AbstractColumn columnProfit = ColumnBuilder.getNew()
        .setCustomExpression(this.getProfitExpression())
        .setStyle(priceStyle)
        .setTitle("Ganancia").setWidth(new Integer(20))
        .setPattern("$ 0.00")
        .build();

    columnProfit.setName("Ganancia");

    GroupBuilder groupBookingTypeBuilder = new GroupBuilder();
    DJGroup groupBookingType =
        groupBookingTypeBuilder.setCriteriaColumn((PropertyColumn) columnDisplayName)
            .setGroupLayout(GroupLayout.VALUE_IN_HEADER_WITH_HEADERS_AND_COLUMN_NAME)
            .build();

    GroupBuilder groupCurrencyBuilder = new GroupBuilder();
    DJGroup groupCurrency =
        groupCurrencyBuilder.setCriteriaColumn((PropertyColumn) columnCurrency)
            .addFooterVariable(columnCount,DJCalculation.SUM,footerStyle)
            .addFooterVariable(columnProfit,DJCalculation.SUM,footerStyle)
            .setGroupLayout(GroupLayout.VALUE_IN_HEADER)
            .build();

    drb.addColumn(columnDisplayName)
        .addColumn(columnCurrency)
        .addColumn(columnDestiny)
        .addColumn(columnCount)
        .addColumn(columnPrice)
        .addColumn(columnProfit)
        .addGroup(groupBookingType)
        .addGroup(groupCurrency)
        .setPrintBackgroundOnOddRows(true);

    DJAxisFormat categoryAxisFormat = new DJAxisFormat("Destino");
    categoryAxisFormat.setLabelFont(Font.ARIAL_SMALL);
    categoryAxisFormat.setLabelColor(Color.DARK_GRAY);
    categoryAxisFormat.setTickLabelFont(Font.ARIAL_SMALL);
    categoryAxisFormat.setTickLabelColor(Color.DARK_GRAY);
    categoryAxisFormat.setTickLabelMask("");
    categoryAxisFormat.setLineColor(Color.DARK_GRAY);

    DJAxisFormat valueAxisFormat = new DJAxisFormat("Ventas / Ingresos");
    valueAxisFormat.setLabelFont(Font.ARIAL_SMALL);
    valueAxisFormat.setLabelColor(Color.DARK_GRAY);
    valueAxisFormat.setTickLabelFont(Font.ARIAL_SMALL);
    valueAxisFormat.setTickLabelColor(Color.DARK_GRAY);
    valueAxisFormat.setTickLabelMask("#,##0");
    valueAxisFormat.setLineColor(Color.DARK_GRAY);

    DJChart djChart = new DJBarChartBuilder()
            //chart
            .setX(20)
            .setY(10)
            .setWidth(500)
            .setHeight(250)
            .setCentered(false)
            .setBackColor(Color.LIGHT_GRAY)
            .setShowLegend(true)
            .setPosition(DJChartOptions.POSITION_FOOTER)
            .setTitle(new StringExpression() {
                @Override
                public Object evaluate(Map fields, Map variables, Map parameters) {
                    return variables.get("bookingType.displayName");
                }
            })
            .setTitleColor(Color.DARK_GRAY)
            .setTitleFont(Font.ARIAL_BIG_BOLD)
            .setSubtitle("subtitle")
            .setSubtitleColor(Color.DARK_GRAY)
            .setSubtitleFont(Font.COURIER_NEW_BIG_BOLD)
            .setLegendColor(Color.DARK_GRAY)
            .setLegendFont(Font.COURIER_NEW_MEDIUM_BOLD)
            .setLegendBackgroundColor(Color.WHITE)
            .setLegendPosition(DJChartOptions.EDGE_BOTTOM)
            .setTitlePosition(DJChartOptions.EDGE_TOP)
            .setLineStyle(DJChartOptions.LINE_STYLE_DOTTED)
            .setLineWidth(1)
            .setLineColor(Color.DARK_GRAY)
            .setPadding(5)
            //dataset
            .setCategory((PropertyColumn) columnDestiny)
            .addSerie(columnCount, "Cantidad")
            .addSerie(columnProfit, "Ganancia") // IF I COMMENT THIS LINE THE CHART IS RENDERED
            //plot
            .setCategoryAxisFormat(categoryAxisFormat)
            .setValueAxisFormat(valueAxisFormat)
            .build();

    drb.addChart(djChart);

    HashMap vars = new HashMap();
    vars.put(columnCount, new JRDesignVariable());
    vars.put(columnProfit, new JRDesignVariable());
    JRDesignGroup group = new JRDesignGroup();
    djChart.transform(new DynamicJasperDesign(), "", group, group, vars, 0);

    DynamicReport dr = drb.build();

    return dr;
}

public JasperPrint getJasperPrint(String status, String userOwner,
            String hourFrom, String hourTo, String dateFrom, String dateTo)
        throws ColumnBuilderException, ClassNotFoundException, JRException, ChartBuilderException {

    DynamicReport dr = this.buildSalesReport();

    JRDataSource ds = new JRBeanCollectionDataSource(
            this.bookService.getReportBooks(status, userOwner, hourFrom, hourTo, dateFrom, dateTo));

    return DynamicJasperHelper.generateJasperPrint(dr , new ClassicLayoutManager(), ds);
}

/**
 *
 * @return
 */
@SuppressWarnings("serial")
private CustomExpression getProfitExpression() {
    return new CustomExpression() {

        @SuppressWarnings("rawtypes")
        @Override
        public Object evaluate(Map fields, Map variables, Map parameters) {
            Double amount = (Integer)fields.get("count") * (Double)fields.get("bookedObject.price");
            return amount;
        }

        @Override
        public String getClassName() {
            return Double.class.getName();
        }
    };

Как я уже сказал, отчет отображается правильно без диаграммы, а с диаграммой он завершается ошибкой только в том случае, если столбец выражения включен в виде серии.

Любые идеи приветствуются!

Ответы [ 3 ]

1 голос
/ 25 июня 2012

Просто выдвинул изменения для DJ 4.0.1 в коммите 05243a3

Когда-нибудь сегодня также будет толкать DJ 3.X

1 голос
/ 14 сентября 2011

Я решил эту же проблему, выполнив следующее:

  1. Установите «fieldDescription» вашего столбца.
  2. Переписать метод "Защищенная карта registerChartVariable (ar.com.fdvs.dj.domain.chart.DJChart chart)" класса AbstractLayoutManager ":

JRDesignExpression expression = new JRDesignExpression ();

String property =  ((PropertyColumn) col).getFieldDescription();

// ((PropertyColumn) col) .getColumnProperty (). GetProperty ();

expression.setText("$F{" +  property  + "}");
expression.setValueClass(clazz);

3. Как вы уже поняли, вам придется создать свой собственный LayoutManager для этой задачи. 4 Возможно, это не лучшее решение, это всего лишь пример того, как заполнить пробел в DynamicJasper.

0 голосов
/ 21 июня 2012

Я столкнулся с той же проблемой, но у меня было немного другое решение.Существуют различные типы классов Column, но в AbstractLayoutManager для диаграмм поддерживается только класс PropertyColumn.Я обнаружил, что когда вы используете CustomExpression, базовый класс Column, который используется, это ExpressionColumn.Итак, я изменил «защищенный метод Map registerChartVariable() в ar.com.fdvs.dj.core.layout.AbstractLayoutManager для поддержки ExpressionColumn.

. Я изменил следующие 3 строки кода в этом методе:

JRDesignExpression expression = new JRDesignExpression();
expression.setText("$F{" + ((PropertyColumn) col).getColumnProperty().getProperty()  + "}");
expression.setValueClass(clazz);

На следующее:

if (col instanceof ExpressionColumn) {
    ExpressionColumn expCol = (ExpressionColumn) col;
    expression.setText(expCol.getTextForExpression());
    expression.setValueClassName(expCol.getExpression().getClassName());
} else {
    expression.setText("$F{" + ((PropertyColumn) col).getColumnProperty().getProperty()  + "}");
    expression.setValueClass(clazz);
}

Это решило проблему для меня, и я больше не получаю сообщение " Поле не найдено ".

...