【适用版本】
s-HR V8.6.1.2 及以上版本
【开发逻辑】
导入的处理类ImportInfoHandler,主要包含两块逻辑:导出Excel模板和导入Excel
1.导出Excel模板
下载模板的处理方法:downloadImportTemplateAction,组装参数:权限id,url参数,数据库模板信息,本地临时文件路径
2.核心处理类TemplateService
Excel模板生成其实调用TemplateService的generateExcelFile()方法
3.功能点一:动态添加列
动态添加列的处理在列初始化setExportTemplateFieldData中
两个功能点:
① 根据具体的importService.getDynamicColumn添加动态列,
② 可根据列属性ColumnIndex调整列的位置
ColumnIndex列排序的逻辑:
①默认为-1,追加到列表末尾。
②不为-1,直接插入到列表下标为columnIndex的位置。
4.功能点二:列数据填充
列数据填充的处理在也列初始化setExportTemplateFieldData中
• 连接属性、枚举属性、boolean类型等的数据填充
• 默认值填充
默认值填充简单,重点关注一下连接属性、枚举属性、boolean属性填充,
需要设置列属性有连接实体||列属性isCludeData
获取填充数据逻辑在AbstractBaseImportService.getColumnSelectValue中
5.功能点三:提供勾子方法,可对Excel做最后的处理
勾子方法在TemplateService.completeGenerateExcel中,
利用模板处理类importService.completeGenerateExcel可做最后的处理,默认空方法
6.小总结:
1、 importService的getDynamicColumn()方法可以在导出模板中动态添加列。
2、 设置列属性的 连接实例或者isCludeDate,平台已支持列属性数据的填充
枚举类型:填充枚举alias
Boolean类型:填充是,否
关联属性:如果存在名称重复,填充number##name,反之,填充name。
3、 提供勾子方法,可对Excel做最终处理
简单时序图:在已有平台之上开发,只需要修改importservice的方法即可
【实际应用】
以开发编制概要为例:人力编制表的导出模板中列,需要根据定编维度变化。
概要一:根据定编维度动态添加列
概要二:定编维度列,需要填充下拉框数据
概要三:“是否包含下级”列需要“行政组织”列的后面
概要二中的截图:通过改变BaseColumnInfo的columnIndex属性调整列位置。
原始模板列表顺序是:0=是否包含下级,1=控编方式
现在设置定编维度从1开始自增,所以0=是否包含下级,定编维度(包含行政组织),n=控编方式
最后将行政组织提到第一位:0=行政组织,1=是否包含下级,定编维度(不包含行政组织),n=控编方式
最终模板结果:红框为动态添加列,有填充数据,顺序正确
1.导入Excel
导入逻辑也比较简单。
1、 对于导入的excel文件,封装一个任务(runnable),放入到一个线程池中,然后返回。
2、 然后就是前后台并行处理逻辑:
线程池如果有空闲线程,就会执行任务(runnable),没有则等待。
前段页面会发送请求,获取任务执行情况,等待线程中—即将执行—执行中—执行完毕。
接下来逐步解析:
2.添加导入任务TaskExcutor
ImportInfoHandler.newImportTaskAction()
ImportTaskManager:顾名思义,导入任务的管理器,
单例的,里面定义了两个线程池:执行导入任务的线程池和删除本地导入文件的线程池
创建一个导入任务importTaskExecutor,将导入文件保存到本地/shr_web.war/shrImport中
执行任务中,记录了列属性、是否回调、权限项、自定义参数、模板实体类型、模板类型
导入任务完毕,接下来环节是并行的:
3.线程池执行导入任务
导入任务的可控制
这一段是真的绕,主要目的:弃用线程池自带的等待队列LinkedBlockedQueue,自定义一个可控的队列queueService来代替等待队列,以便于控制导入任务的中断,停止,取消等。
下面是自定义queue的相关操作方法。
导入任务的实现
默认逐条导入,但是可以通过两个方法来自实现批量导入的,
需要importService.isBatch() == true, 并且实现startBatchImport方法
4.页面循环查询导入进度。