工作中有这么个需求:我们想通过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 parameters = new HashMap();
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;
}
}