Jasperreport API实现交叉表(Cross table)配置

    工作中有这么个需求:我们想通过B/S配置报表模板,而非JasperReport自带的IReport,目前有很多方案正在调研中,根据领导安排,我暂时研究并实现了通过JasperReport的API来配置一个简单的交叉表,过程如下:
    首先需要配置:Style,Query,Field,Parameter,Variable,Title,Summary等部分,其中省略了一些区域,然后将CrossTab添加到Summary中,CrossTable主要配置了:行分组(行bucket,行Header单元格,行Total单元格),列分组(列bucket,列Header单元格,列Total单元格),Measure度量,数据区单元格等信息。
     我参考了noxmldesign这个Sample,通过Jasperreport的API配置了一个交叉表,配置信息实现为一个JasperDesign对象,接着利用JasperCompileManager将JasperDesign对象编译为JasperReport对象,反过来再利用JasperCompileManager将JasperReport对象转换成JRXML报表模板。


代码:

public class CrossTableNoXml extends AbstractSampleApp{

	public static void main(String[] args) throws JRException {
		CrossTableNoXml crossTabApp = new CrossTableNoXml();
		crossTabApp.test();
	}
	
	public void test() throws JRException {
		
		JasperDesign jDesign = getCrossTabDesign();
		JasperCompileManager.compileReportToFile(jDesign, "build/noxmldesign/CrossTableTest.jasper");
		JasperCompileManager.writeReportToXmlFile("build/noxmldesign/CrossTableTest.jasper");
		Map<String, Object> parameters = new HashMap<String, Object>();
		JasperFillManager.fillReportToFile("build/noxmldesign/CrossTableTest.jasper", parameters, getDemoHsqldbConnection());
		JasperExportManager.exportReportToPdfFile("build/noxmldesign/CrossTableTest.jrprint");
	}
	
	/**
	 * 通过API生成JasperDesign对象
	 * @return
	 * @throws JRException
	 */
	public JasperDesign getCrossTabDesign() throws JRException {
		JasperDesign jDesign = new JasperDesign();
		
		//设置页面信息
		jDesign.setName("CrossTableTest");
		jDesign.setPageWidth(1000);
		jDesign.setPageHeight(842);
		jDesign.setColumnWidth(480);
		jDesign.setColumnSpacing(0);
		jDesign.setLeftMargin(20);
		jDesign.setRightMargin(20);
		jDesign.setTopMargin(20);
		jDesign.setBottomMargin(20);
		
		//设置style
		JRDesignStyle style1 = new JRDesignStyle();
		style1.setName("style1");
		style1.setBlankWhenNull(true);
		style1.setFontName("SansSerif");
		style1.setPdfFontName("Helvetica");
		style1.setPdfEncoding("CP1252");
		style1.setPdfEmbedded(true);
		style1.setBold(true);
		style1.setItalic(true);
		style1.setUnderline(true);
		style1.setStrikeThrough(true);
		//设置ConditionalStyle,用于预警
		JRDesignConditionalStyle conStyle1 = new JRDesignConditionalStyle();
		JRDesignExpression expression = new JRDesignExpression();
		expression.setText("new Boolean($V{ORDERDCOUNT} != 0 && $V{ORDERDCOUNT} % 10 == 0)");  //预警表达式
		conStyle1.setConditionExpression(expression);
		conStyle1.setForecolor(null);
		conStyle1.setBackcolor(new Color(255, 255, 0));  //背景黄色
		conStyle1.setMode(ModeEnum.OPAQUE);   //不透明
		style1.addConditionalStyle(conStyle1);
		jDesign.addStyle(style1);
		
		//设置query
		JRDesignQuery query = new JRDesignQuery();
		query.setText("select SHIPCOUNTRY, ORDERDATE, FREIGHT  from orders");
		jDesign.setQuery(query);
		
		//设置field
		JRDesignField shipCountry = new JRDesignField();
		shipCountry.setName("SHIPCOUNTRY");
		shipCountry.setValueClass(java.lang.String.class);
		jDesign.addField(shipCountry);
		
		
		JRDesignField orderDate = new JRDesignField();
		orderDate.setName("ORDERDATE");
		orderDate.setValueClass(java.sql.Timestamp.class);
		jDesign.addField(orderDate);
		
		JRDesignField freight = new JRDesignField();
		freight.setName("FREIGHT");
		freight.setValueClass(java.lang.Float.class);
		jDesign.addField(freight);
		
		//Variables
		/*JRDesignVariable variable = new JRDesignVariable();
		variable.setName("ORDERDCOUNT");
		variable.setValueClass(java.lang.Integer.class);
		variable.setCalculation(CalculationEnum.SYSTEM);
		jDesign.addVariable(variable);

		variable = new JRDesignVariable();
		variable.setName("MaxDate");
		variable.setValueClass(java.sql.Timestamp.class);
		variable.setCalculation(CalculationEnum.SYSTEM);
		jDesign.addVariable(variable);*/
		
		//设置title
		JRDesignBand band = new JRDesignBand();
		band.setHeight(50);
		JRDesignLine line = new JRDesignLine();
		line.setX(0);
		line.setY(0);
		line.setWidth(515);
		line.setHeight(0);
		band.addElement(line);
		JRDesignStaticText staticText = new JRDesignStaticText();
		staticText.setX(0);
		staticText.setY(10);
		staticText.setWidth(515);
		staticText.setHeight(30);
		staticText.setHorizontalAlignment(HorizontalAlignEnum.CENTER);
		staticText.setFontSize(22);
		staticText.setText("Orders Freight CrossTable");
		band.addElement(staticText);
		jDesign.setTitle(band);
		
		/*//page header
		band = new JRDesignBand();
		jDesign.setPageHeader(band);
		
		//Column header
		band = new JRDesignBand();
		jDesign.setColumnHeader(band);
		
		//Detail
		band = new JRDesignBand();
		((JRDesignSection)jDesign.getDetailSection()).addBand(band);
		
		//column footer
		band = new JRDesignBand();
		jDesign.setColumnFooter(band);
		
		//page footer
		band = new JRDesignBand();
		jDesign.setPageFooter(band);*/
		
		//设置Summary
		band = new JRDesignBand();
		band.setHeight(139);
		JRDesignCrosstab crossTab = new JRDesignCrosstab();
		crossTab.setX(0);
		crossTab.setY(0);
		crossTab.setWidth(850);
		crossTab.setHeight(139);
		
		//设置行bucket
		JRDesignCrosstabBucket bucket = new JRDesignCrosstabBucket();
		expression = new JRDesignExpression();
		expression.setText("$F{SHIPCOUNTRY}");
		bucket.setExpression(expression);
		expression = new JRDesignExpression();
		expression.setText("$V{ORDERDCOUNT}");
		bucket.setOrderByExpression(expression);   //排序表达式
		bucket.setValueClassName("java.lang.String");
		bucket.setOrder(BucketOrder.DESCENDING);
		
		//设置row分组
		JRDesignCrosstabRowGroup rowGroup = new JRDesignCrosstabRowGroup();
		rowGroup.setBucket(bucket);
		rowGroup.setName("SHIPCOUNTRY");
		rowGroup.setPosition(CrosstabRowPositionEnum.TOP);
		rowGroup.setTotalPosition(CrosstabTotalPositionEnum.END);
		rowGroup.setWidth(57);
		
		//设置行header单元格
		JRDesignCellContents header = new JRDesignCellContents();
		JRDesignTextField rowHeaderField = new JRDesignTextField();
		rowHeaderField.setWidth(57);
		rowHeaderField.setHeight(24);
		rowHeaderField.setX(0);
		rowHeaderField.setY(0);
		rowHeaderField.setHorizontalAlignment(HorizontalAlignEnum.RIGHT);
		rowHeaderField.getLineBox().getLeftPen().setLineWidth(1);
		rowHeaderField.getLineBox().getTopPen().setLineWidth(1);
		rowHeaderField.getLineBox().getRightPen().setLineWidth(1);
		rowHeaderField.getLineBox().getBottomPen().setLineWidth(1);
		rowHeaderField.setHorizontalAlignment(HorizontalAlignEnum.CENTER);
		rowHeaderField.setVerticalAlignment(VerticalAlignEnum.MIDDLE);
		expression = new JRDesignExpression();
		expression.setText("$V{SHIPCOUNTRY}");
		rowHeaderField.setExpression(expression);
		header.addElement(rowHeaderField);
		rowGroup.setHeader(header);
		
		//设置行Total单元格
		JRDesignCellContents headerTotal = new JRDesignCellContents();
		JRDesignStaticText rowHeaderTotalField = new JRDesignStaticText();
		rowHeaderTotalField.setText("总和");
		rowHeaderTotalField.setWidth(57);
		rowHeaderTotalField.setHeight(24);
		rowHeaderTotalField.setX(0);
		rowHeaderTotalField.setY(0);
		rowHeaderTotalField.setHorizontalAlignment(HorizontalAlignEnum.RIGHT);
		rowHeaderTotalField.getLineBox().getLeftPen().setLineWidth(1);
		rowHeaderTotalField.getLineBox().getTopPen().setLineWidth(1);
		rowHeaderTotalField.getLineBox().getRightPen().setLineWidth(1);
		rowHeaderTotalField.getLineBox().getBottomPen().setLineWidth(1);
		rowHeaderTotalField.setHorizontalAlignment(HorizontalAlignEnum.CENTER);
		rowHeaderTotalField.setVerticalAlignment(VerticalAlignEnum.MIDDLE);
		headerTotal.addElement(rowHeaderTotalField);
		rowGroup.setTotalHeader(headerTotal);
		crossTab.addRowGroup(rowGroup);
		
		//设置bucket
		bucket = new JRDesignCrosstabBucket();
		expression = new JRDesignExpression();
		expression.setText("Integer.valueOf($F{FREIGHT}.intValue()/100)");
		bucket.setExpression(expression);
		bucket.setValueClassName("java.lang.Integer");
		bucket.setOrder(BucketOrder.ASCENDING);

		//设置column分组
		JRDesignCrosstabColumnGroup columnGroup = new JRDesignCrosstabColumnGroup();
		columnGroup.setBucket(bucket);
		columnGroup.setName("FREIGHTCOLUMN");
		columnGroup.setPosition(CrosstabColumnPositionEnum.LEFT);
		columnGroup.setTotalPosition(CrosstabTotalPositionEnum.END);
		columnGroup.setHeight(19);

		//设置列Header单元格
		header = new JRDesignCellContents();
		JRDesignTextField columnHeaderField = new JRDesignTextField();
		columnHeaderField.setWidth(57);
		columnHeaderField.setHeight(19);
		columnHeaderField.setX(0);
		columnHeaderField.setY(0);
		columnHeaderField.setHorizontalAlignment(HorizontalAlignEnum.RIGHT);
		columnHeaderField.getLineBox().getLeftPen().setLineWidth(1);
		columnHeaderField.getLineBox().getTopPen().setLineWidth(1);
		columnHeaderField.getLineBox().getRightPen().setLineWidth(1);
		columnHeaderField.getLineBox().getBottomPen().setLineWidth(1);
		columnHeaderField.setHorizontalAlignment(HorizontalAlignEnum.CENTER);
		columnHeaderField.setVerticalAlignment(VerticalAlignEnum.MIDDLE);
		expression = new JRDesignExpression();
		//设置列Header表达式
		expression.setText("String.valueOf($V{FREIGHTCOLUMN}.intValue()*100) + \"-\" + String.valueOf(($V{FREIGHTCOLUMN}.intValue()+1)*100)");
		columnHeaderField.setExpression(expression);
		header.addElement(columnHeaderField);
		columnGroup.setHeader(header);
		
		//设置列Total单元格
		headerTotal = new JRDesignCellContents();
		JRDesignStaticText columnHeaderTotalField = new JRDesignStaticText();
		columnHeaderTotalField.setText("总和");
		columnHeaderTotalField.setWidth(57);
		columnHeaderTotalField.setHeight(19);
		columnHeaderTotalField.setX(0);
		columnHeaderTotalField.setY(0);
		columnHeaderTotalField.setHorizontalAlignment(HorizontalAlignEnum.RIGHT);
		columnHeaderTotalField.getLineBox().getLeftPen().setLineWidth(1);
		columnHeaderTotalField.getLineBox().getTopPen().setLineWidth(1);
		columnHeaderTotalField.getLineBox().getRightPen().setLineWidth(1);
		columnHeaderTotalField.getLineBox().getBottomPen().setLineWidth(1);
		columnHeaderTotalField.setHorizontalAlignment(HorizontalAlignEnum.CENTER);
		columnHeaderTotalField.setVerticalAlignment(VerticalAlignEnum.MIDDLE);
		headerTotal.addElement(columnHeaderTotalField);
		columnGroup.setTotalHeader(headerTotal);
		
		crossTab.addColumnGroup(columnGroup);
		
		//设置measure
		JRDesignCrosstabMeasure measure = new JRDesignCrosstabMeasure();
		measure.setName("ORDERDCOUNT");
		measure.setValueClassName("java.lang.Integer");
		expression = new JRDesignExpression();
		expression.setText("$F{ORDERDATE}");
		measure.setValueExpression(expression);
		measure.setCalculation(CalculationEnum.COUNT);
		crossTab.addMeasure(measure);
		
		measure = new JRDesignCrosstabMeasure();
		measure.setName("MAXORDERDATE");
		measure.setValueClassName("java.sql.Timestamp");
		expression = new JRDesignExpression();
		expression.setText("$F{ORDERDATE}");
		measure.setValueExpression(expression);
		measure.setCalculation(CalculationEnum.HIGHEST);
		crossTab.addMeasure(measure);
		
		//设置数据区单元格
		JRDesignTextField textField = new JRDesignTextField();
		JRDesignCrosstabCell cell = new JRDesignCrosstabCell();
	    JRDesignExpression expressionTextField = new JRDesignExpression();
	    JRDesignCellContents cellContents = new JRDesignCellContents();
        textField.setX(0);
        textField.setY(0);
        textField.setWidth(57);
        textField.setHeight(24);
        textField.setHorizontalAlignment(HorizontalAlignEnum.RIGHT);
        textField.getLineBox().getLeftPen().setLineWidth(1);
        textField.getLineBox().getTopPen().setLineWidth(1);
        textField.getLineBox().getRightPen().setLineWidth(1);
        textField.getLineBox().getBottomPen().setLineWidth(1);
        cell.setHeight(24);
        cell.setWidth(57);
        expressionTextField.setText("$V{ORDERDCOUNT}");   
        textField.setExpression(expressionTextField);  //设置数据区表达式
        textField.setHorizontalAlignment(HorizontalAlignEnum.CENTER);
        textField.setVerticalAlignment(VerticalAlignEnum.MIDDLE);
        cellContents.addElement(textField);
        cellContents.setStyle(style1);
        cell.setContents(cellContents);
        crossTab.addCell(cell);
		band.addElement(crossTab);
		jDesign.setSummary(band);
		
		return jDesign;
	}
}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值