我在 FineReport应用 - 程序网络报表Hello,World 一文中,阐述了编程实现基本报表的方法,在本文中,我将介绍如何创建一个带有数据集的分组数据报表。
设计目标
设计一张报表,按付款方式分组查出订单编号和金额,最终效果如下图:
配置数据连接
要使用数据集,需要先在服务器中配置数据连接。配置文件位于
%FR_HOME%\WebReport\ WEB-INF\resources\datasource.xml
以FRDemo为例,配置如下:
<?xml version="1.0" encoding="UTF-8"?> <DatasourceManager> <ConnectionMap> <Connection name="FRDemo" class="com.fr.data.impl.JDBCDatabaseConnection"> <DatabaseAttr /> <JDBCDatabaseAttr url="jdbc:odbc:Driver={Microsoft Access Driver (*.mdb)};DBQ=D:\FineReport6.5\WebReport\WEB-INF\resources\data\FRDemo.mdb" driver="sun.jdbc.odbc.JdbcOdbcDriver" user="" password="" encryptPassword="true" /> </Connection> </ConnectionMap> </DatasourceManager>
添加报表数据集
在前文中,已经介绍过如何建立一个基本的程序报表,这时不再赘述。
建立一个报表:
package fr.report;
import com.fr.base.Constants;
import com.fr.base.FRContext;
import com.fr.base.NameStyle;
//...
/**
* 普通分组报表
*
* http://localhost:8080/FineReport/ReportServer?reportlet=fr.report.GroupReportletDemo
*/
public class GroupReportletDemo implements Reportlet {
public Report createReport(ReportletRequest req) {
// 新建报表
WorkSheet workSheet = new WorkSheet();
return workSheet;
}
}
要添加数据集,在createReport(...)方法中添加如下代码:
try {
// 使用数据连接FRDemo
DatabaseConnection dbConn = new NameDatabaseConnection("FRDemo");
// 定义数据集,这里我们只取前20条记录
TableData tableData = new DBTableData(dbConn, "SELECT top 20 * FROM ORDERS");
// 将定义的数据集添加到报表中,命名为ds1
workSheet.putTableData("ds1", tableData);
} catch (Exception exp) {
FRContext.getLogger().severe(exp.getMessage());
exp.printStackTrace();
}
添加数据列
表样:
数据列:
添加数据列:
// 建立扩展属性并指定为从上到下扩展
CellExpandAttr cellExpandAttr = new CellExpandAttr();
cellExpandAttr.setDirection(Constants.TOP_TO_BOTTOM);
// 新建一个取自ds1数据集PAYMETHOD字段的数据列
DSColumn a2data = new DSColumn();
a2data.setDSName("ds1");
a2data.setColumn(TableDataColumn.createColumn("PAYMETHOD"));
// 设置数据配置为“分组 普通”
a2data.setGrouper(new FunctionGrouper());
// 将建立的数据列绑定到A2单元格中
CellElement a2 = new DefaultCellElement(0, 1, a2data);
// 应用扩展属性
a2.setCellExpandAttr(cellExpandAttr);
// 添加单元格到报表中
workSheet.addCellElement(a2);
依例设置b2、c2单元格,添加表头的方法前文已经介绍过,这里略过。
注意
new DefaultCellElement(col, row, value)中,col和row分别为列和行的索引,如0,0表示a1,1,1表示B2
美化报表
通常为了美观,我们会给不同的单元格加上样式,FineReport为我们提供了几种预定义的样式,
见:%FR_HOME%\WebReport\WEB-INF\resources\config.xml
要使用预定义的样式,只需要加入如下的代码即可:
// 表头样式
Style headStyle = NameStyle.getInstance("Head");
// 表体样式
Style cellStyle = NameStyle.getInstance("Cell");
a1.setStyle(headStyle);
a2.setStyle(headStyle);
完整代码
package fr.report;
import com.fr.base.Constants;
import com.fr.base.FRContext;
import com.fr.base.NameStyle;
import com.fr.base.Style;
import com.fr.data.TableData;
import com.fr.data.impl.DBTableData;
import com.fr.data.impl.DatabaseConnection;
import com.fr.data.impl.NameDatabaseConnection;
import com.fr.report.CellElement;
import com.fr.report.DefaultCellElement;
import com.fr.report.Report;
import com.fr.report.WorkSheet;
import com.fr.report.cellElement.CellExpandAttr;
import com.fr.report.cellElement.TableDataColumn;
import com.fr.report.cellElement.core.DSColumn;
import com.fr.report.cellElement.core.FunctionGrouper;
import com.fr.web.Reportlet;
import com.fr.web.ReportletRequest;
/**
* 普通分组报表
*
* http://localhost:8080/FineReport/ReportServer?reportlet=fr.report.GroupReportletDemo
*/
public class GroupReportletDemo implements Reportlet {
public Report createReport(ReportletRequest req) {
// 新建报表
WorkSheet workSheet = new WorkSheet();
try {
// 定义数据连接
DatabaseConnection dbConn = new NameDatabaseConnection("FRDemo");
// 定义数据集
TableData tableData = new DBTableData(dbConn, "SELECT top 20 * FROM ORDERS");
// 添加数据集ds1
workSheet.putTableData("ds1", tableData);
// 表头样式
Style headStyle = NameStyle.getInstance("Head");
// 表体样式
Style cellStyle = NameStyle.getInstance("cell");
// 添加表头
CellElement a1 = new DefaultCellElement(0, 0, "PAYMETHOD");
a1.setStyle(headStyle);
workSheet.addCellElement(a1);
CellElement b1 = new DefaultCellElement(1, 0, "ORDERID");
b1.setStyle(headStyle);
workSheet.addCellElement(b1);
CellElement c1 = new DefaultCellElement(2, 0, "AMOUNT");
c1.setStyle(headStyle);
workSheet.addCellElement(c1);
// 添加表体
CellExpandAttr cellExpandAttr = new CellExpandAttr();
cellExpandAttr.setDirection(Constants.TOP_TO_BOTTOM);
DSColumn a2data = new DSColumn();
a2data.setDSName("ds1");
a2data.setGrouper(new FunctionGrouper());
a2data.setColumn(TableDataColumn.createColumn("PAYMETHOD"));
CellElement a2 = new DefaultCellElement(0, 1, a2data);
a2.setCellExpandAttr(cellExpandAttr);
workSheet.addCellElement(a2);
a2.setStyle(cellStyle);
DSColumn b2data = new DSColumn();
b2data.setDSName("ds1");
b2data.setGrouper(new FunctionGrouper());
b2data.setColumn(TableDataColumn.createColumn("ORDERID"));
CellElement b2 = new DefaultCellElement(1, 1, b2data);
b2.setCellExpandAttr(cellExpandAttr);
workSheet.addCellElement(b2);
b2.setStyle(cellStyle);
DSColumn c2data = new DSColumn();
c2data.setDSName("ds1");
c2data.setGrouper(new FunctionGrouper());
c2data.setColumn(TableDataColumn.createColumn("AMOUNT"));
CellElement c2 = new DefaultCellElement(2, 1, c2data);
c2.setCellExpandAttr(cellExpandAttr);
workSheet.addCellElement(c2);
c2.setStyle(cellStyle);
} catch (Exception exp) {
FRContext.getLogger().severe(exp.getMessage());
exp.printStackTrace();
}
return workSheet;
}
}
要预览报表,访问
http://localhost:8080/FineReport/ReportServer?reportlet=fr.report.GroupReportletDemo