如何实现附件一键下载的功能开发原创
金蝶云社区-陈来珍
陈来珍
18人赞赏了该文章 6,011次浏览 未经作者许可,禁止转载编辑于2022年08月30日 13:38:28
summary-icon摘要由AI智能服务提供

本文档描述了实现单据中附件的一键下载并压缩的需求及实现方案。需求允许用户通过点击按钮,将单据上的所有附件(包括分录中的附件字段和附件面板中的附件)压缩成一个压缩包并下载。实现方案通过创建不同的文件夹对象来存放不同来源的附件,然后使用`BatchDownloadRequest`对象调用批量下载接口,将附件压缩并生成下载链接。过程中需要注意,如果附件为临时文件,需要先保存单据。具体实现包括按钮点击事件处理、附件字段和附件面板的文件夹构建等步骤,以及处理临时文件未保存单据的情况。

关键词:附件面板、附件字段、批量下载、临时文件、压缩包

一、需求

  在单据中,用户需要提供一键下载单据上的所有附件,并且添加到一个压缩包中。

image.png

二、实现方案

         添加分录中附件字段的附件和附件面板中的附件,分别添加到不同的文件夹对象中,最终压缩到一个压缩包中。用户点击一键下载,能够下载到当前表单所在浏览器页面。

         约束:批量下载接口BatchDownloadRequest请求下载的地址必须是服务器中存在的地址,做校验判断是否上传了文件,但是没保存单据(临时文件)。如果附件为临时文件,需要先保存单据。

image.png

三、实现过程

1、详细实现过程-按钮点击一键下载

    @Override
    public void itemClick(ItemClickEvent evt) {
        if (evt.getItemKey().equals("kded_alldown")) {
            this.getPageCache().put("ifContainTempfile", "false");
            FileService fs = FileServiceFactory.getAttachmentFileService();
            // 浏览器用户代理字符串,模拟浏览器userAgent访问
            String userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.93 Safari/537.36";
            // 获取附件面板的附件放在一个文件夹下
            Dir attpanelDir = createDirAndFileByAttPanel("attachmentpanel");
            // 获取单据体附件字段字段的附件放在一个文件夹下
            Dir attFileDir = createDirAndFileByAttFile("attentryentity", "kded_attachmentfield");
            // 构造BatchDownloadRequest对象
            BatchDownloadRequest bdr = new BatchDownloadRequest("alldownload");
            bdr.setDirs(new Dir[] { attpanelDir, attFileDir });
            //BatchDownloadRequest对象的输出流
            OutputStream out = null;
            String url = "";
            try {// 在默认临时文件目录中创建一个空文件,使用给定前缀和后缀生成其名称。
                java.io.File file = java.io.File.createTempFile("test", ".zip");
                out = new FileOutputStream(file);
        // 批量下载接口BatchDownloadRequest请求下载的地址必须是服务器中存在的地址
            fs.batchDownload(bdr, out, userAgent);
// 上传为临时文件,主要作为this.getView().download提供下载地址
TempFileCache cache = CacheFactory.getCommonCacheFactory().getTempFileCache();
 url = cache.saveAsUrl(file.getName(), new FileInputStream(file), 2 * 60);   
} catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            String ifContainTempfile = this.getPageCache().get("ifContainTempfile");
            if (ifContainTempfile.equals("true")) {
                this.getView().showMessage("有附件未保存,请先保存单据");
            } else {
                // 下载后文件的地址为浏览器的下载地址
                this.getView().download(url);
            }
        }
        super.itemClick(evt);
    }

2、详细实现过程-附件字段的文件夹构建

    private Dir createDirAndFileByAttFile(String entityName, String attachmentfield) {
        // 以附件字段标识命名文件夹
        Dir attFileDir = new Dir(attachmentfield);
        DynamicObjectCollection col = this.getModel().getDataEntity(true).getDynamicObjectCollection(entityName);
        ArrayList<File> attFileFile = new ArrayList<>();
        for (DynamicObject dynamicObject : col) {
            DynamicObjectCollection attCol = dynamicObject.getDynamicObjectCollection(attachmentfield);
            for (DynamicObject attObj : attCol) {
                DynamicObject btdata = attObj.getDynamicObject("fbasedataid");
                String atturl = btdata.getString("url");
                if (atturl.indexOf("path=") != -1) {
                    String[] urlsplit = atturl.split("path=");
                    String path = urlsplit[1];
                    String name = btdata.getString("name");
                    File aFile = new File(name, path);
                    attFileFile.add(aFile);
            } else if (atturl.contains("/tempfile/download.do?configKey")) {
                    this.getPageCache().put("ifContainTempfile", "true");
                    break; }}}
        File[] files = attFileFile.toArray(new File[attFileFile.size()]);
        attFileDir.setFiles(files);
        return attFileDir;}

3、详细实现过程-附件面板的文件夹构建

private Dir createDirAndFileByAttPanel(String attpanel) {
        // 以附件面板标识命名文件夹
        Dir attpanelDir = new Dir(attpanel);
        AttachmentPanel att = this.getControl(attpanel);
        List<Map<String, Object>> attachmentData = att.getAttachmentData();
        ArrayList<File> attpanelFile = new ArrayList<>();
        for (Map<String, Object> map : attachmentData) {
            String atturl = (String) map.get("url");
            if (atturl.indexOf("path=") != -1) {
                String[] urlsplit = atturl.split("path=");
                String path = urlsplit[1];
                String name = (String) map.get("name");
                File aFile = new File(name, path);
                attpanelFile.add(aFile);
            } else if (atturl.contains("/tempfile/download.do?configKey")) {
                this.getPageCache().put("ifContainTempfile", "true");
                break;
            }
        }
        File[] files = attpanelFile.toArray(new File[attpanelFile.size()]);
        attpanelDir.setFiles(files);
        return attpanelDir;
    }

四、实现效果

1、点击一键下载,因为批量下载接口BatchDownloadRequest请求下载的地址必须是服务器中存在的地址,所以做了校验判断是否上传了文件,但是没保存单据(临时文件)。

image.png

2、保存之后,下载,表单页面出现下载的压缩包

image.png

image.png

image.png

五、开发环境版本

COSMICV4.0.010.0

六、参考资料

【开发平台】指导手册

学习成长中心


赞 18