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

本文介绍了在单据中实现一键下载所有附件并打包成压缩包的需求与实现方案。实现过程包括点击按钮触发下载操作,构建附件字段和附件面板的文件夹,通过批量下载接口下载文件并压缩,最终提供下载地址。若存在临时文件,需先保存单据。

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

一、需求

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

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");
                //只需要path后面的值,如果path参数后面还带了其他参数如&a=xx&bb=yy,那么也有去掉&a=xx&bb=yy
                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

六、参考资料

【开发平台】指导手册

学习成长中心


图标赞 19
19人点赞
还没有人点赞,快来当第一个点赞的人吧!
图标打赏
0人打赏
还没有人打赏,快来当第一个打赏的人吧!