2011-04-14 168 views
4

我有一個使用DynamicJasper創建報表的項目。到目前爲止它運行良好,但是當我想將圖表添加到以前的功能性報表時,我遇到了問題。在DynamicJasper圖表中使用CustomExpression

我不斷收到這樣的:

net.sf.jasperreports.engine.design.JRValidationException:報告設計無效: 領域未發現:customExpression_for_Ganancia 在net.sf.jasperreports.engine。在net.sf.jasperreports.engine.JasperCompileManager.compileReport(JasperCompileManager。)中的net.sf.jasperreports.engine.design.JRAbstractCompiler.compileReport(JRAbstractCompiler.java:140) 上設計(JRAbstractCompiler.java:258) 。 java:215) at ar.com.fdvs.dj.core.DynamicJasperHelper.generateJasperReport(DynamicJasperHelpe r.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(); 
     } 
    }; 

正如我所說,該報告是正常顯示沒有圖表,用圖表,它失敗只有當表達式列作爲一個序列被包含時。

歡迎任何想法!

回答

1

就被推爲DJ的變化4.0.1在提交05243a3

有時也在今天將推動DJ 3.X

+0

DJ版本3.2.4修復了問題也:承諾是6818489很快釋放sourceforge – 2012-06-25 15:49:59

+0

太棒了!我不希望這些迴應在一年之後纔會到達,最重要的是要固定在項目本身上:D非常感謝! – Johnco 2012-06-26 22:16:17

1

我已經解決了這個同樣的問題做以下幾點:

  1. 設置你的專欄的「fieldDescription」。
  2. 重寫方法 「保護的地圖registerChartVariable(ar.com.fdvs.dj.domain.chart.DJChart圖表)」 類AbstractLayoutManager的「:

JRDesignExpression表達式=新JRDesignExpression(); 。

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

//((PropertyColumn)COL).getColumnProperty()的getProperty();

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

3。正如你已經想到的那樣,你必須爲這個任務創建你自己的LayoutManager。 4。這可能不是最好的解決方案,它只是填補DynamicJasper空白的一個例子。

0

我遇到了同樣的問題,但我有一個稍微不同的解決方案。列類有不同類型,但AbstractLayoutManager中只支持PropertyColumn類。我發現,當您使用CustomExpression時,使用的基礎Column類是ExpressionColumn。因此,我修改了ar.com.fdvs.dj.core.layout.AbstractLayoutManager中的「受保護的地圖registerChartVariable()」方法,以支持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); 
} 

這解決了這個問題,我和我不再收到「場不發現「消息。