设计器中添加数据集类型(excel数据集)
需求背景:
润乾设计器提供了多种数据集类型,包括sql检索、存储过程、复杂SQL、Text文件等,并且预留了自定义接口,用户可以编写自己的自定义数据集类构造定制化的数据集。本文介绍如何在设计器中添加数据集类型,以读取excel内容作为数据集内容为例在设计器中添加Excel数据集类型,用户可以选择excel,报表数据集会以excel文件内容构造数据集。
实现思路:
1. 实现自定义数据集,需要实现润乾报表提供的com.runqian.report4.dataset.IDataSetFactory接口
2.实现用户的数据集编辑对话框类,必须实现com.runqian.report4.ide.usermodel.IDataSetEditor
3.实现自定义数据集配置类,该类必须继承com.runqian.report4.usermodel.DataSetConfig 抽象类
4. 修改润乾安装目录下designer/config/systemconfig.xml,增加数据集类配置,添加节点格式如下:
<DATASETTYPE>
<TestDataSetType config”api.DocDataSetConfig” dialog” api.DialogDocDataSet”>
</DATASETTYPE>
其中TestDataSetType编辑窗口中显示的数据集的名称。configClass 用户的数据集配置类, 必须继承com.runqian.report4.usermodel.DataSetConfig 抽象类。dialogClass 用户的数据集编辑对话框类,必须实现com.runqian.report4.ide.usermodel.IDataSetEditor 接口且继承DialogInputFile 类。
具体实现:
1.自定义数据集类ExcelDataSetFactory
部分代码:
public class ExcelDataSetFactory implements IDataSetFactory
{
public DataSet createDataSet( Context ctx, DataSetConfig dsc, boolean retrieve ) {
MessageManager mm = DataSetMessage.get();
IDataSetFactoryListener dsfListener = null;
String dsListener = dsc.getListenerClass();
if (dsListener != null && !dsListener.trim().equals(“”)) {
try{
dsfListener = (IDataSetFactoryListener)Class.forName(dsListener).newInstance();
catch (Exception e){
throw new ReportError(mm.getMessage(“error.noListener”, dsListener));
}
}
String dsName = dsc.getName();
DataSet ds = new DataSet(dsName);
if (dsfListener != null)
dsfListener.beforeCreated(ctx, dsc, ds);
String fileName = ((ExcelDataSetConfig) dsc).getFileName();
HSSFWorkbook wb = null; //Excel工作薄
int sheetNum = 0; //sheet所在的位置
InputStream is = null;
try{
is = new FileInputStream(fileName);
wb = new HSSFWorkbook(is);
catch (Exception e){
String mainDir = ctx.getMainDir();
if (!fileName.startsWith(“/”))
fileName = “/” + fileName;
String fName = mainDir + fileName;
File ffile = new File(fName);
if (ffile.exists() && !mainDir.equals(“/”)) {
try {
is = new FileInputStream(fName);
wb = new HSSFWorkbook(is);
}
catch (Exception ef) {}
}
if (is == null) {
ServletContext application = ctx.getApplication();
if (application == null) {
throw new ReportError(ServerMsg.getMessage(“config.reload”)); //没有在reportConfig.xml中配置报表证书文件或证书文件错误!
}
is = application.getResourceAsStream(fName);
}
if (is == null) {
throw new ReportError(mm.getMessage(“error.noFile”, fName));
}
}
HSSFSheet hs = wb.getSheetAt( 0 ); //获得EXCEL的工作表
HSSFRow hr = hs.getRow(0);
HSSFCell hc = null;
//从EXCEL文件里获得数据集的列名
int rowCount = hs.getLastRowNum() + 1;
int colCount = hr.getLastCellNum();
//根据Excel的列数据,生成对应的数据集列数
for(int i = 0;i <= colCount – 1; i++){
hc = hr.
getCell
((short)i);
String s1 = hc.
getStringCellValue
();
ds.addCol(s1);
}
//获得数据集数据,从第二行开始
for(int j = 1;j < rowCount;j++){
Row row = ds.addRow();
//根据Excel中的数据对数据集每一行进行设置数据
for(int k = 1;k <= colCount;k++){
hr = hs.getRow(j);
hc = hr.
getCell
((short)(k – 1));
if(hc.getCellType() == HSSFCell.CELL_TYPE_STRING){
row.setData(k,hc.
getStringCellValue
());
}else if(hc.getCellType() == HSSFCell.CELL_TYPE_NUMERIC){
row.setData(k,new Double(hc.getNumericCellValue()));
}
}
}
if (dsfListener != null)
dsfListener.afterCreated(ctx, dsc, ds);
return ds;
}
}
2.数据集编辑对话框类DialogExcelDataSet
部分代码
public class DialogExcelDataSet extends DialogInputFile implements IDataSetEditor {
//设置对话框标题
public DialogDocDataSet(String title, String ext) {
super(“选择Excel文件”, “xls”);
}
//实线接口中的方法
public void setDataSetConfig(DataSetConfig dsConfig) {
……
}
public DataSetConfig getDataSetConfig() {
……
}
}
3. 数据集配置类
public class ExcelDataSetConfig
extends DataSetConfig
implements Externalizable, ICloneable {
private static final long serialVersionUID = 1L;
private String fileName;
/**
* 取数据集工厂类名
*/
public String getFactoryClass() {
return “api.ExcelDataSetFactory”;
}
/**
* 设文件名
*@param fileName 文件名
*/
public void setFileName(String fileName) {
this.fileName = fileName;
}
/**
* 取文件名
*/
public String getFileName() {
return this.fileName;
}
……
}
4.修改配置文件designer/config/systemconfig.xml
添加节点:
<DATASETTYPE>
<Excel数据集 config”api.ExcelDataSetConfig” dialog”api.DialogExcelDataSet”/>
</DATASETTYPE>
拷贝编译后的.class文件放在designer\classes\自定义类所在的包名下面。若要在web端生效需要将编译后的.class文件放在应用的类路径下(\webapps\demo\WEB-INF\classes\)。
选择Excel文件对话框: