|
@@ -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);
|
|
|
+ }
|
|
|
}
|
|
|
+
|
|
|
}
|
|
|
|
|
|
+
|
|
|
}
|