Ver código fonte

fix:导出流程文件

xuezizhuo 1 ano atrás
pai
commit
411f86121d

+ 12 - 4
ruoyi-admin/src/main/java/com/ruoyi/web/controller/BpmProcessController.java

@@ -1,15 +1,24 @@
 package com.ruoyi.web.controller;
 
+import java.io.*;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
+import com.ruoyi.common.annotation.Anonymous;
 import com.ruoyi.system.entity.BpmProcess;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiImplicitParam;
 import io.swagger.annotations.ApiImplicitParams;
 import io.swagger.annotations.ApiOperation;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.util.CollectionUtils;
 import org.springframework.web.bind.annotation.*;
 import com.ruoyi.common.annotation.Log;
 import com.ruoyi.common.core.controller.BaseController;
@@ -117,11 +126,10 @@ public class BpmProcessController extends BaseController {
     @ApiOperation(value = "导出流程文件文件")
     @ApiImplicitParams({
             @ApiImplicitParam(name = "processId", value = "编号", dataType = "Long"),
-            @ApiImplicitParam(name = "fileType", value = "文件类型", dataType = "String")
     })
-    @GetMapping("/export")
-    public void export(@RequestParam("processId") Long processId, @RequestParam("fileType") String fileType, HttpServletRequest request, HttpServletResponse response) {
-        bpmProcessService.export(processId, fileType, request, response);
+    @GetMapping("/exportProcessFile")
+    public void exportProcessFile(@RequestParam("processIds") List<Long> processIds, HttpServletRequest request, HttpServletResponse response) throws Exception {
+        bpmProcessService.exportProcessFile(processIds, request, response);
     }
 
 

+ 5 - 0
ruoyi-system/src/main/java/com/ruoyi/system/mapper/BpmProcessMapper.java

@@ -60,4 +60,9 @@ public interface BpmProcessMapper
      */
     public int deleteBpmProcessByProcessIds(Long[] processIds);
 
+    /**
+     * 根据流程编号查询
+     */
+    List<BpmProcess> selectBpmProcessByProcessIds(List<Long> processIds);
+
 }

+ 3 - 1
ruoyi-system/src/main/java/com/ruoyi/system/service/IBpmProcessService.java

@@ -73,6 +73,8 @@ public interface IBpmProcessService {
     /**
      * 导出流程文件
      */
-    void export(Long processId, String fileType, HttpServletRequest request, HttpServletResponse response);
+    void exportProcessFile(List<Long> processIds, HttpServletRequest request, HttpServletResponse response) throws Exception;
+
+
 
 }

+ 154 - 24
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/BpmProcessServiceImpl.java

@@ -1,15 +1,21 @@
 package com.ruoyi.system.service.impl;
 
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileOutputStream;
 import java.io.IOException;
-import java.io.OutputStream;
-import java.io.StringReader;
+import java.io.*;
 import java.net.URLEncoder;
 import java.nio.charset.StandardCharsets;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.nio.file.StandardCopyOption;
+import java.util.Base64;
 import java.util.List;
+import java.util.stream.Collectors;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
 
 import com.ruoyi.common.config.RuoYiConfig;
 import com.ruoyi.common.constant.Constants;
@@ -19,10 +25,13 @@ import com.ruoyi.common.utils.StringUtils;
 import com.ruoyi.common.utils.file.FileUploadUtils;
 import com.ruoyi.common.utils.file.FileUtils;
 import com.ruoyi.system.entity.BpmProcess;
+import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
+import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import com.ruoyi.system.mapper.BpmProcessMapper;
 import com.ruoyi.system.service.IBpmProcessService;
+import org.springframework.util.CollectionUtils;
 import org.springframework.web.multipart.MultipartFile;
 import org.w3c.dom.Document;
 import org.xml.sax.InputSource;
@@ -179,32 +188,153 @@ public class BpmProcessServiceImpl implements IBpmProcessService {
     }
 
     @Override
-    public void export(Long processId, String fileType, HttpServletRequest request, HttpServletResponse response) {
-        BpmProcess process = bpmProcessMapper.selectBpmProcessByProcessId(processId);
-        String fileName = process.getProcessName() + "." + fileType;
+    public void exportProcessFile(List<Long> processIds, HttpServletRequest request, HttpServletResponse response) throws Exception {
+
+        List<BpmProcess> bpmProcessList = bpmProcessMapper.selectBpmProcessByProcessIds(processIds);
+        String localPath = RuoYiConfig.getProfile();
+        List<String> list = bpmProcessList.stream().map(m ->localPath + StringUtils.substringAfter(m.getProcessXmlPath(), Constants.RESOURCE_PREFIX)).collect(Collectors.toList());
+
+        if (CollectionUtils.isEmpty(list)){
+            throw new Exception("请选择要下载文件/图片");
+        }
+
+        //设置响应头信息
+        response.reset();
+        response.setCharacterEncoding("utf-8");
+        response.setContentType("multipart/form-data");
+        //设置压缩包的名字,date为时间戳
+        String date = String.valueOf(System.currentTimeMillis());
+        String downloadName = "压缩包" + date + ".zip";
+        //返回客户端浏览器的版本号、类型
+        String agent = request.getHeader("USER-AGENT");
         try {
-            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
-            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
-            Document doc = dBuilder.parse(new InputSource(new StringReader(process.getProcessXmlContent())));
-            // 规范化XML结构
-            doc.getDocumentElement().normalize();
-            // 创建转换器以生成XML
-            TransformerFactory transformerFactory = TransformerFactory.newInstance();
-            Transformer transformer = transformerFactory.newTransformer();
-            transformer.setOutputProperty(OutputKeys.INDENT, "yes");
-            DOMSource source = new DOMSource(doc);
-            // 创建输出流,将XML写入响应
-            OutputStream outputStream = response.getOutputStream();
-            response.setContentType("application/xml");
-            String encodedFileName = URLEncoder.encode(fileName, StandardCharsets.UTF_8.toString());
-            response.setHeader("Content-Disposition", "attachment; filename=" + encodedFileName);
-            // 将XML写入响应输出流
-            StreamResult result = new StreamResult(outputStream);
-            transformer.transform(source, result);
-            System.out.println("XML file downloaded");
+            //针对IE或者以IE为内核的浏览器:
+            if (agent.contains("MSIE") || agent.contains("Trident")) {
+                downloadName = URLEncoder.encode(downloadName, "UTF-8");
+            } else {
+                //非IE浏览器的处理:
+                downloadName = new String(downloadName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);
+            }
         } catch (Exception e) {
+//            log.error("系统异常", e);
+        }
+
+        if (list.size()>1){
+            //多文件/图压缩下载
+            batchFileDownLoad(list,downloadName,response);
+
+        }else {
+            //单文件/图直接下载
+            singleFileDownLoad(list,bpmProcessList.get(0).getProcessName(),response);
+
+        }
+
+    }
+
+    private void batchFileDownLoad(List<String> list, String downloadName, HttpServletResponse response) {
+        //设置压缩包名称
+        response.setHeader("Content-Disposition", "attachment;fileName=\"" + downloadName + "\"");
+        //设置压缩流:直接写入response,实现边压缩边下载
+        ZipOutputStream zipOs = null;
+        //循环将文件写入压缩流
+        DataOutputStream os = null;
+
+        try {
+            zipOs = new ZipOutputStream(new BufferedOutputStream(response.getOutputStream()));
+            //设置压缩方法
+            zipOs.setMethod(ZipOutputStream.DEFLATED);
+            //遍历文件信息(主要获取文件名/文件路径等)
+            for (String t : list) {
+                try {
+                    //文件存储路径
+                    String path = t;
+                    //压缩文件中每个文件的文件名称
+                    String name = t.substring(t.lastIndexOf("\\")+1);
+//                    log.info("batchDownloadFile:[filePath:{}]", path);
+                    File file = new File(path);
+                    if (!file.exists()) {
+                        throw new RuntimeException("文件不存在");
+                    }
+                    FileInputStream fs = null;
+                    try {
+                        //添加ZipEntry,并将ZipEntry中写入文件流
+                        zipOs.putNextEntry(new ZipEntry(name));
+                        os = new DataOutputStream(zipOs);
+                        fs = new FileInputStream(file);
+                        byte[] b = new byte[100];
+                        int length;
+                        //读入需要下载的文件的内容,打包到zip文件
+                        while ((length = fs.read(b)) != -1) {
+                            os.write(b, 0, length);
+                        }
+                    } catch (Exception e) {
+//                        log.error("系统异常", e);
+                    } finally {
+                        //关闭流
+                        assert fs != null;
+                        fs.close();
+                        zipOs.closeEntry();
+                    }
+
+                } catch (Exception e) {
+//                    log.error("下载文件出错![{}]", e.getMessage());
+                }
+            }
+        } catch (Exception e) {
+//            log.error("系统异常", e);
+        } finally {
+            //关闭流
+            try {
+                if (os != null) {
+                    os.flush();
+                    os.close();
+                }
+                if (zipOs != null) {
+                    zipOs.close();
+                }
+            } catch (IOException e) {
+//                log.error("系统异常", e);
+            }
+        }
+    }
+
+    /**
+     * 单文件直接下载
+     * @param list 文件/图片路径
+     * @param response
+     */
+    private void singleFileDownLoad(List<String> list,String processName, HttpServletResponse response) throws UnsupportedEncodingException {
+
+        FileInputStream fis = null;
+        OutputStream out = null;
+        String path = list.get(0);
+        String name = path.substring(path.lastIndexOf("\\")+1);
+        response.setHeader("Content-Disposition", "attachment;filename="+URLEncoder.encode(processName, StandardCharsets.UTF_8.toString())+".bpmn");
+        try {
+            fis = new FileInputStream(path);
+            out = response.getOutputStream();
+            byte[] b = new byte[1024];
+            int len = 0;
+            while((len = fis.read(b))!=-1){
+                out.write(b, 0, len);
+            }
+        }catch (Exception e){
             e.printStackTrace();
+        }finally {
+            try {
+                if (out != null) {
+                    out.flush();
+                    out.close();
+                }
+                if (fis != null) {
+                    fis.close();
+                }
+            } catch (IOException ex) {
+//                log.error("系统异常", ex);
+            }
         }
+
     }
 
+
 }

+ 8 - 0
ruoyi-system/src/main/resources/mapper/BpmProcessMapper.xml

@@ -141,4 +141,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             #{processId}
         </foreach>
     </delete>
+
+    <select id="selectBpmProcessByProcessIds" resultMap="BpmProcessResult">
+        <include refid="selectBpmProcessVo"/>
+        where process_id in
+        <foreach collection="list" item="processId" open="(" close=")" separator=",">
+            #{processId}
+        </foreach>
+    </select>
 </mapper>