如何通过导入一个zip压缩包,自动生成左树和右表原创
1人赞赏了该文章
714次浏览
编辑于2022年06月02日 14:29:44
关键词:压缩包、zip、左树右表、附件
一、需求
左树右表结构,通过导入一个压缩包,按压缩包文件夹层级自动生成左树右表
二、思路与方案
1、上传压缩包,到缓存中。IPageCache获取缓存url
2、CacheFactory.getCommonCacheFactory().getTempFileCache()获取缓存中的流文件
3、对解析后的压缩包进行遍历
4、根据解析的层级和左树右表的层级,插入到对应的表单中即可
三、实现过程
1、创建树型基础资料(kdec_basetree_demo01_wfb)和动态表单(kdec_form_demo1_wfb)
图1
图2
2、在树型基础资料列表上添加自定义按钮“上传zip”,openform打开动态表单(kdec_basetree_demo01_wfb)
图3
3、编写动态表单插件ZipFormPluginByWfb01注册到动态表单(kdec_form_demo1_wfb)
/** * 代码思路 * 1、注册按钮“确定”监听 * 2、附件上传成功后,存储在缓存中 * 3、点击“确定”按钮,从缓存中获取文件流,并对zip结构进行解析 * 4、根据解析的层级和左树右表的层级,插入到对应的树型基础资料表单中(kdec_treebase0530) * 5、删除临时文件,并刷新父页面 */ public class ZipFormPluginByWfb01 extends AbstractFormPlugin { @Override public void registerListener(EventObject e) { super.registerListener(e); Button button = this.getControl("btnok"); button.addClickListener(this); } /** * 点击确定触发 * 获取缓存中的文件流 * 解析文件流,并文件按层级结构保存到树型基础资料 * 刷新父页面 * @param evt */ @Override public void click(EventObject evt) { super.click(evt); Object source = evt.getSource(); if(source instanceof Button){ Button button = (Button) source; String key = button.getKey(); if(StringUtils.equals("btnok",key)){ //获取缓存中的文件流 IPageCache pageCache = getView().getPageCache(); String cacheJsonStr = pageCache.get("TampAttCache" + getView().getPageId()); Map<String,Object> attachementInfo = SerializationUtils.fromJsonString(cacheJsonStr,Map.class); List<Map<String,Object>> contractAttaList = null; if(attachementInfo != null) { contractAttaList = (List<Map<String,Object>>)attachementInfo.get("kdec_attachmentpanelap"); } if (contractAttaList != null && !contractAttaList.isEmpty()) { Map<String, Object> attachment = contractAttaList.get(0); String tempUrl = attachment.get("url").toString(); // String fileName = attachment.get("name").toString(); //新生成的临时合同文件的输入流 TempFileCache tempFileCache = CacheFactory.getCommonCacheFactory().getTempFileCache(); InputStream in = tempFileCache.getInputStream(tempUrl); try { this.readZipCvsFile(in); } catch (Exception e) { e.printStackTrace(); } IFormView parentView = this.getView().getParentView(); parentView.showSuccessNotification("操作成功!"); parentView.invokeOperation("refresh"); this.getView().sendFormAction(parentView); this.getView().close(); } } } } /** * 解析zip文件,并保存zip目录结构到树型基础资料 * @param in * @return */ public void readZipCvsFile(InputStream in) throws Exception { //获得输入流,文件为zip格式, //zip可以包含对个文件,如果只有一个文件,则只解析一个文件的,包含多个文件则分别解析 ZipInputStream inzip = new ZipInputStream(in); //不解压直接读取,加上gbk解决乱码问题 BufferedReader br = new BufferedReader(new InputStreamReader(in,"utf-8")); ZipEntry zipFile; String entryName = ""; Map<String,Object> map = new HashMap<>(); MainEntityType mainEntityType = EntityMetadataCache.getDataEntityType("kdec_basetree_demo01_wfb"); long currUserId = RequestContext.get().getCurrUserId(); //循环读取zip中的cvs/txt文件,zip文件名不能包含中文 while ((zipFile = inzip.getNextEntry()) != null) { //如果是目录,不处理 entryName = zipFile.getName(); long id = ID.genLongId(); DynamicObject dynamicObject = new DynamicObject(mainEntityType); dynamicObject.set("id",id); dynamicObject.set("masterid",id);//主数据内码 dynamicObject.set("creator",currUserId);//创建人 String subname = ""; map.put(entryName,id); //构造父节点长名称,方便从map获取父节点id if(zipFile.isDirectory() && entryName.endsWith("/")){ subname = entryName.substring(0,entryName.length() - 1); subname = subname.substring(0,subname.lastIndexOf("/")+1); }else { subname = entryName.substring(0,entryName.lastIndexOf("/")+1); } //社区父节点parent if(StringUtils.isNotEmpty(subname) && map.containsKey(subname)){ dynamicObject.set("parent",map.get(subname)); }else { dynamicObject.set("parent",0); } dynamicObject.set("status","C");//数据状态,A暂存,B提交,C审核 dynamicObject.set("enable","1");//使用状态,0禁用,1可用 String fileName = ""; if(entryName.endsWith("/")){ //截取文件夹名 String str = entryName.substring(0,entryName.length() - 1); if(str.contains("/")){ fileName = str.substring(str.lastIndexOf("/")+1,str.length()); }else { fileName = str; } }else if(entryName.contains("/")){ //截取文件名 fileName = entryName.substring(entryName.lastIndexOf("/")+1,entryName.length()); } dynamicObject.set("number",fileName);//编码 dynamicObject.set("name",fileName);//名称 //长名称、长编码 String longnumber = entryName.endsWith("/") ? entryName.substring(0,entryName.length() - 1).replace("/",".") : entryName.replace("/","."); dynamicObject.set("longnumber",longnumber); dynamicObject.set("fullname",longnumber); //保存入库 SaveServiceHelper.save(mainEntityType,new DynamicObject[]{dynamicObject}); } //关闭流 br.close(); in.close(); } }
四、效果图
图4
五、开发环境版本
不限,本样例采用的轻量级环境,版本是: 苍穹版本号 COSMICV4.0.019.0 星瀚版本号 CONSTELLATIONV4.0.019.0
六、注意事项
1、这是一个树型基础资料,压缩包文件夹层级自动生成左树右表。如果只是要文件夹层级生成左数,文件夹内的文件生成右表,请通过分组基础资料实现。分组基础资料是由两个基础资料构成的,A基础资料引用另外一个B“分组”基础资料,需要我们在解析的时候,把文件夹的层级保存到B“分组”这个基础资料,文件夹内的文件保存到A基础资料即可!!
2、这里是没有做唯一性校验的,可以重复导入。需要自己去实现
七、参考资料
元数据及插件.zip(10.58KB)
推荐阅读