导入导出功能在EAS中是比较多见的,基本上都是遵循基础框架来做的,本文就以从基础框架继承来开发为例,讲解导入导出的开发。
导入导出从大的方面来讲,分两部分:
1、模板定义
2、导入导出实现类(java类)的开发
3、客户端导入导出菜单事件的代码实现
即我们只要按系统规定,在系统平台中定义好引入引出模板,然后针对模板开发出引入引出的实现类,就完成了功能的开发,基于此思路,我以库存管理的库存初始化单据的导入导出来说明,步骤如下:
1、用administrator登录EAS,从菜单打开引入引出模板
2、进入后,在左边选择自己的目录,如果自己想要的目录不存在,可以直接在左边界面上新增一个目录,然后点击菜单“文件-新增”,系统弹出一个空模板
3、编辑完毕如下图:
红字部分分别是“模板编码”、“模板引入引出实现类”及“引入引出的字段”,这仅仅是个模板,后面的excel文件就是由这个模板定义生成的,也就是说这个模板仅仅会生成excel,和数据库没有直接的关系,和数据库或接口的关系是靠“引入引出实现类”。
4、在bos中新增开发实现类com.kingdee.eas.scm.im.inv.app.InvInitBillDataImport,由于这是系统中已经存在的实现类,读者可以直接反编译此类,这里对此类中的主要方法进行解释。
在InvInitBillDataImport类中我们重点关注以下几个方法:
(a)getSubmitType(),这个方法是设定是将excel中的行一次性打包成Map结构来导入还是每次读一行,反映到当前类中就是transmit(Hashtable hsData, Context ctx)方法的hsData参数,1为全部一次,0为每次一行,可以看到当前的类中覆盖了父类方法,设为1,表示一次返回所有的
(b)transmit(Hashtable hsData, Context ctx) 这是从excel中读入数据后第一个调的方法,hsData参数中就是从excel中读入的数据,如果是一次性读入所有的数据,则hsData中是key从Integer型的1、2、3等等行,每行取出来就是excel中对应行的Map结构数据,然后在这个方法中你可以对传回来的数据做任何的处理,目的是要构造出单据的info,当然其中要包含分录,具体可以读此代码,在当前类中,程序增加了transmitHead(Hashtable lineData, Context ctx)和transmitEntry(Hashtable hsData, Context ctx)两个方法,分别处理单据头和单据体的构造。在构造info的过程中,如果是自有属性,基本上转换成对应类型即可,如果是连接属性,那么一般excel中填入的都是编码,程序中要按编码取出其Info对象,比如transmitHead(...)方法中的“storageOrgUnit”属性
(c)submit(CoreBaseInfo coreBaseInfo, Context ctx)方法,这个方法是用来提交transmit()返回的Info对象的,这个就没什么要解释的,应该能明白
(d)getController(Context ctx)这也是框架提供的,用来取得实例接口的,为类中需要的地方调用,比如submit()方法
【前面的方法都是针对导入的,下面是针对导出的】
(e)getExportQueryInfo(Context ctx)用来指定导出的query,因为导出是通过query来返回结果集,再分别将结果集中的一行数据填入到模板对应的属性中,当然如果不在程序中指定,也可以在模板定义的界面上设置
(f)getExportFilterForQuery(Context ctx),如果需要对(e)中的query设置过滤条件,这个方法就可以用了
(g)exportTransmit(IRowSet rs, Context ctx),从字面意思上看,就是导出了,这个方法就是将query中查出来的结果集(IRowSet)变换成Hastable结构,最后由框架自动生成excel文件
具体InvInitBillDataImport类的代码由于太多,这里就不显示了,读者可以直接反编译出来看。
接下来是客户端的代码实现,客户端的导入导出框架事件如下:
public void actionExportData_actionPerformed(ActionEvent e) throws Exception
{
ArrayList para = getExportParam();
if(para == null || para.size() <= 0)
throw new FrameWorkException(FrameWorkException.EXPORTDATAPARANULL);
Object tmp = para.get(0);
if(tmp instanceof DatataskParameter)
{
DatataskParameter dp = (DatataskParameter)tmp;
dp.putContextParam("mainQueryPK", new MetaDataPK("com.kingdee.eas.scm.im.inv.InventoryInitExportQuery"));
dp.putContextParam("mainQuery", mainQuery);
}
DatataskCaller dc = new DatataskCaller();
dc.setParentComponent(this);
dc.invoke(para, 1);
}
这个事件程序中指定了导出的query,当然可以不指定,因为我们的导入导出类中已经指定了,下面是导出参数设置方法:
protected ArrayList getExportParam()
{
DatataskParameter param = new DatataskParameter();
param.solutionName = "eas.im.inventoryInitBill";
param.alias = InvClientUtils.getResource("InventoryInitBill");
param.varList = new ArrayList();
param.datataskMode = 1;
ArrayList paramList = new ArrayList();
paramList.add(param);
return paramList;
}
其中“eas.im”是模板所在的分类,即模板编辑左边的树编码目录,“inventoryInitBill”是模板编码,导入导出运行过程中框架会根据编码找到模板,从模板中拿到导入导出类来执行,那么你可能会问“eas.im”我怎么知道,这个你可以通过点模板编辑左树的节点,然后点击修改,就可以看到编码,如下图:
下面是导入的事件和参数:
public void actionImportData_actionPerformed(ActionEvent e) throws Exception
{
super.actionImportData_actionPerformed(e);
}
protected ArrayList getImportParam()
{
DatataskParameter param = new DatataskParameter();
String solutionName = "eas.im.inventoryInitBill";
param.solutionName = solutionName;
param.alias = InvClientUtils.getResource("InventoryInitBill");
ArrayList paramList = new ArrayList();
paramList.add(param);
return paramList;
}
导入的参数设置和导出基本相同。
还有一个特殊的功能,就是我们有时候需要在客户端导入时,将界面上的值作为参数传入实现类,这样如何实现呢?
步骤如下(红字部分为增加的参数传入和读取):
(a)修改导入参数
protected ArrayList getImportParam()
{
DatataskParameter param = new DatataskParameter();
String solutionName = "eas.im.inventoryInitBill";
param.solutionName = solutionName;
param.alias = InvClientUtils.getResource("InventoryInitBill");
//将当前单据id传入导入类中
Hashtable table = new Hashtable();
table.put("billID", editData.getId().toString());
param.setContextParam(table);
ArrayList paramList = new ArrayList();
paramList.add(param);
return paramList;
}