如何通过导入一个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)

image.png

图1

image.png

图2


2、在树型基础资料列表上添加自定义按钮“上传zip”,openform打开动态表单(kdec_basetree_demo01_wfb

image.png

图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();
    }
}


四、效果图

zip导入生成树型基础资料.gif

图4

 

五、开发环境版本

不限,本样例采用的轻量级环境,版本是: 苍穹版本号 COSMICV4.0.019.0  星瀚版本号 CONSTELLATIONV4.0.019.0

 

六、注意事项

1、这是一个树型基础资料,压缩包文件夹层级自动生成左树右表。如果只是要文件夹层级生成左数,文件夹内的文件生成右表,请通过分组基础资料实现。分组基础资料是由两个基础资料构成的,A基础资料引用另外一个B“分组”基础资料,需要我们在解析的时候,把文件夹的层级保存到B“分组”这个基础资料,文件夹内的文件保存到A基础资料即可!!

2、这里是没有做唯一性校验的,可以重复导入。需要自己去实现

七、参考资料

开发平台

学习成长中心

文件服务

如何将基础资料页面上的附件填充业务单据数据后绑定到单据附件面板上

如何实现通过FileService上传文件

赞 1