导入压缩包(ZIP)的形式生成左树右表原创
7人赞赏了该文章
1,047次浏览
编辑于2022年07月21日 17:10:00
关键词:左树右表,导入,压缩包
一、需求
平台上下载的资源大部分是以压缩包的形式存在。实施通常需要将压缩包自行解压,手动录入到苍穹系统中作为资源存储。
当数据量巨大时,人工操作就显得耗时耗力,也会有人为失误录入导致数据不准确的结果。这样通过压缩包直接导入自动生成左树右表的功能就显得尤为重要了。
二、思路与方案
2.1分析思路
实现这个功能的难点,主要有两个,一是解析压缩包,二是需要根据压缩包内的目录结构对应生成左树右表
2.2实现方案
需要先创建自定义上传的动态表单作为载体,然后通过附件面板获取上传到苍穹的压缩包的临时路径url,接下来就是解析压缩包,将解析出来的内容进行遍历根据判断是文件夹就生成左树,文件就生成右表
三、实现过程
1、创建动态表单,添加附件面板控件,最重要的导入插件在这里注册
2、在需要导入的单据列表,添加导入按钮,弹出上一步创建的动态表单。这一步需要在单据列表注册单据列表插件实现打开弹框功能
@Override public void itemClick(ItemClickEvent evt) { super.itemClick(evt); if(evt.getItemKey().equals("kdec_importmd")) { FormShowParameter showParameter = new FormShowParameter(); showParameter.setFormId("kdec_importmd"); showParameter.setCloseCallBack(new CloseCallBack(this,"kdec_importmd")); showParameter.getOpenStyle().setShowType(ShowType.Modal); this.getView().showForm(showParameter); } } //关闭弹框,刷新列表 @Override public void closedCallBack(ClosedCallBackEvent event) { super.closedCallBack(event); String actionId = event.getActionId(); if (actionId.equals("kdec_importmd")) { this.getView().updateView(); } }
3、创建分组基础资料,作为左树存储
4、从附件面板解析zip文件
@Override //按钮监听 public void registerListener(EventObject e) { super.registerListener(e); this.addClickListeners("btnok"); } @Override public void beforeClick(BeforeClickEvent evt) { super.beforeClick(evt); Control source = (Control) evt.getSource(); if (source.getKey().equals("btnok")) { //解析附件面板 AttachmentPanel attachmentPanel = this.getControl("附件面板标识"); List<Map<String, Object>> attachmentDatas = attachmentPanel.getAttachmentData(); if (attachmentDatas.size() == 0) { evt.setCancel(true); this.getView().showMessage("请先上传附件!"); return; } String zipUrl = (String) attachmentDatas.get(0).get("url");//压缩包临时路径 String name = (String) attachmentDatas.get(0).get("name"); TempFileCache cache = CacheFactory.getCommonCacheFactory().getTempFileCache(); InputStream in = cache.getInputStream(zipUrl);//从缓存中拿到输入流 //需要将压缩包上传到fileserver服务器,获取文件url,解析的时候用 FileService service = FileServiceFactory.getAttachmentFileService(); RequestContext req = RequestContext.get(); String uuid = UUID.randomUUID().toString().replace("-", ""); String pathparam = FileNameUtils.getAttachmentFileName(req.getTenantId(), req.getAccountId(),uuid, name); FileItem fi = new FileItem(name, pathparam, in); String downurl = service.upload(fi); String fileserver = System.getProperty("fileserver"); String zurl = fileserver + downurl;//得到文件url try { //解析压缩包 URL url = new URL(zurl); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); Charset gbk = Charset.forName("GBK"); ZipInputStream zipInputStream = new ZipInputStream(conn.getInputStream(), gbk); BufferedInputStream buf = new BufferedInputStream(zipInputStream); // 遍历每一个文件 ZipEntry zipEntry = zipInputStream.getNextEntry(); while (zipEntry != null) { String filename = zipEntry.getName(); //这里实现的是文件夹和.md类型文件都生成左树,只有.md文件生成右表。 if (!zipEntry.isDirectory()) { // 文件 if (filename.contains(".md")) { String[] names = filename.split("/"); for (int x = 0; x < names.length; x++) { if (!names[x].contains(".md")) { //生成左树 saveSDKCatgory(vsion, names, x); } else { //生成右表 saveSDKApi(vsion, buf, zipEntry, names, x); } } } } zipInputStream.closeEntry(); zipEntry = zipInputStream.getNextEntry(); } } catch (IOException e) { this.getView().showErrorNotification(e.getMessage()); } } }
5、先生成左树
private Object saveSDKCatgory(DynamicObject vsion, String[] names, int index) { String name = names[index]; //排序序号 Integer seq = name.indexOf("-") == -1 ? Integer.MAX_VALUE : Integer.valueOf(name.substring(0,name.indexOf("-"))); name = name.substring(name.indexOf("-")+1); //因为是遍历创建左树,所以需要判断每次进来的name是否在相同层级已经创建,如果已创建则return。name是文件或文件夹名,也是左树节点名称,level是树层级 QFilter[] qFilters = new QFilter[]{new QFilter("name", QCP.equals, name), new QFilter("level", QCP.equals, index + 1)}; DynamicObjectCollection catgorys = QueryServiceHelper.query("分组基础资料标识", "字段标识", qFilters); if (catgorys.size() != 0) { return catgorys.get(0).get("id"); } //获取父级对象 String parentName = index == 0 ? "x" : names[index - 1]; parentName = parentName.substring(parentName.indexOf("-")+1); QFilter[] qFilters3 = new QFilter[]{new QFilter("name", QCP.equals, parentName)}; DynamicObject parent = BusinessDataServiceHelper.loadSingle("分组基础资料标识", "字段标识", qFilters3); //生成左树 DynamicObject newDynamicObject = BusinessDataServiceHelper.newDynamicObject("分组基础资料标识"); newDynamicObject.set("number", ID.genStringId()); newDynamicObject.set("name",name); newDynamicObject.set("level", index + 1); newDynamicObject.set("status", "A"); newDynamicObject.set("enable", 1); newDynamicObject.set("isleaf", false); newDynamicObject.set("parent", parent); newDynamicObject.set("kdec_seq",seq); OperationResult saveOperate = SaveServiceHelper.saveOperate("分组基础资料标识", new DynamicObject[]{newDynamicObject}, OperateOption.create()); if(!saveOperate.isSuccess()){ throw new KDBizException(getOperationResultErrorInfos(saveOperate)); } return saveOperate.getSuccessPkIds().get(0); }
6、最后生成右表
private void saveSDKApi(DynamicObject vsion, BufferedInputStream buf, ZipEntry zipEntry, String[] names, int index) throws IOException { String name = names[index]; name = name.substring(0,name.lastIndexOf(".")); names[index] = name; name = name.substring(name.indexOf("-")+1); Object successPkId = saveSDKCatgory(vsion,names,index);//将文件也生成一级左树节点 QFilter[] qFilters4 = new QFilter[]{new QFilter("id", QCP.equals, successPkId)}; DynamicObject group = BusinessDataServiceHelper.loadSingle("分组基础资料标识", "字段标识", qFilters4); String number = ID.genStringId(); DynamicObject api = BusinessDataServiceHelper.newDynamicObject("右表单据标识"); api.set("number",number); api.set("name", name); api.set("group", group); api.set("enable", 1); api.set("status","A"); api.set("fullname",String.format("%s.%s",group.getString("fullname"),name)); api.set("longnumber",String.format("%s.%s",group.getString("longnumber"),number)); //解析markdown文件内容存入数据库 StringBuilder content = new StringBuilder(); byte[] bytes = new byte[(int) zipEntry.getSize()]; buf.read(bytes, 0, (int) zipEntry.getSize()); InputStream byteinputstream = new ByteArrayInputStream(bytes); BufferedReader br = new BufferedReader(new InputStreamReader(byteinputstream)); String line; while ((line = br.readLine()) != null) { content.append(line + "\r\n"); } StringBuilder imgUrl = new StringBuilder(); for(int i = 0; i < names.length-1; i++){ imgUrl.append(names[i]); imgUrl.append("/"); } String regex = StringUtils.isNotBlank(System.getProperty("sdk.img.regex")) ? System.getProperty("sdk.img.regex") : "<img\\s*src\\s*=\\s*['\"]+?.\\/"; String detail_tag = content.toString().replaceAll(regex,"<img src='/sdk/"+vsion.getString("name").toLowerCase()+"/linkdoc/" + imgUrl); api.set(Consts.DETAIL_TAG,detail_tag);//保存markdown内容 //生成右表 OperationResult saveOperate = SaveServiceHelper.saveOperate("kdec_sdk_api", new DynamicObject[]{api}, OperateOption.create()); if(!saveOperate.isSuccess()){ throw new KDBizException(getOperationResultErrorInfos(saveOperate)); } }
四、效果图
五、开发环境版本
V4.0.018.0
六、注意事项
1、本文讲述的是zip导入生成左树右表,其他压缩包格式不能完全照搬,解压缩获取输入流的方法需要替换成对应的方法。
2、左树的生成需要考虑到相同层级目录名称相同的问题,需要去重
七、参考资料
八、源代码
源码.rar(3.79KB)
推荐阅读