shicf
2024-06-12 a0a4e4027514ca678b6b7ec4dde3530e30b5ae25
src/main/java/com/product/file/util/FileUtil.java
@@ -1,11 +1,17 @@
package com.product.file.util;
import cn.hutool.core.lang.UUID;
import com.aspose.words.Document;
import com.aspose.words.SaveFormat;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.xwpf.NiceXWPFDocument;
import com.google.common.collect.Maps;
import com.product.common.lang.StringUtils;
import com.product.core.config.Global;
import com.product.core.exception.BaseException;
import com.product.file.config.CmnConst;
import com.product.file.config.FileCode;
import org.apache.log4j.Logger;
import lombok.extern.slf4j.Slf4j;
import java.io.*;
import java.util.List;
@@ -21,167 +27,237 @@
 * @Author: 6c
 * @Description:
 */
@Slf4j
public class FileUtil {
    private static Logger logger = Logger.getLogger(FileUtil.class);
    private static Properties properties;
   private FileUtil() {
   }
   /**
    * 合并word文档
    *
    * @param source 源文件
    * @param target 目标文件
    * @return
    */
   public static File mergeFile(File source, File target) throws Exception {
      //判断文件是否为 docx或doc格式
      if (!source.getName().endsWith(".docx") && !source.getName().endsWith(".doc")) {
         throw new BaseException(FileCode.ADD_FILE_NOT_ALLOWED);
      }
      //如果是doc格式则转换为docx格式
      if (source.getName().endsWith(".doc")) {
         source = toDocx(source);
      }
      if (target.getName().endsWith(".doc")) {
         target = toDocx(target);
      }
      XWPFTemplate template = XWPFTemplate.compile(source);
      NiceXWPFDocument xwpfDocument = template.getXWPFDocument();
      try {
         NiceXWPFDocument sub = new NiceXWPFDocument(new FileInputStream((target)));
         NiceXWPFDocument newDoc = xwpfDocument.merge(sub);
         String tempFile = Global.getSystemConfig("temp.dir", "./attachment/temp") + File.separator + UUID.randomUUID() + ".docx";
         try (FileOutputStream out = new FileOutputStream(tempFile)) {
            newDoc.write(out);
            newDoc.close();
            return new File(tempFile);
         } catch (IOException e) {
            throw e;
         } finally {
            newDoc.close();
            sub.close();
         }
      } catch (IOException e) {
         throw e;
      } catch (Exception e) {
         throw e;
      }
   }
    private FileUtil() {
    }
   public static File toDocx(File file) {
      if (!AsposeUtil.getLicense(2)) {
         return file;
      }
      String docxName = UUID.randomUUID().toString() + ".docx";
      File docxFile = new File(file.getParent() + File.separator + docxName);
      String tempDir = Global.getSystemConfig("temp.dir", "./attachment/temp");
      File tempFile = new File(tempDir + File.separator + docxName);
      try {
         Document document = new Document(new FileInputStream(file));
         document.save(tempFile.getAbsolutePath(), com.aspose.words.SaveFormat.DOCX);
         return tempFile;
      } catch (Exception e) {
         e.printStackTrace();
      }
      return docxFile;
   }
   public static File toDoc(File file) {
      if (!AsposeUtil.getLicense(2)) {
         return file;
      }
      String docxName = UUID.randomUUID().toString() + ".doc";
      File docxFile = new File(file.getParent() + File.separator + docxName);
      String tempDir = Global.getSystemConfig("temp.dir", "./attachment/temp");
      File tempFile = new File(tempDir + File.separator + docxName);
      try {
         Document document = new Document(new FileInputStream(file));
         document.save(tempFile.getAbsolutePath(), SaveFormat.DOC);
         return tempFile;
      } catch (Exception e) {
         e.printStackTrace();
      }
      return docxFile;
   }
    /**
     * 批量打包
     *
     * @param pathList 文件路径集合
     * @param os       输出流
     * @return zip文件保存绝对路径
     */
    public static long createZip(List<Map<String, String>> pathList, OutputStream os) {
        logger.info("正在打包文件...");
        try {
            long size = 0;
            ZipOutputStream out = new ZipOutputStream(os);
   /**
    * 批量打包
    *
    * @param pathList 文件路径集合
    * @param os       输出流
    * @return zip文件保存绝对路径
    */
   public static long createZip(List<Map<String, String>> pathList, OutputStream os) {
      try {
         long size = 0;
         ZipOutputStream out = new ZipOutputStream(os);
            String downloadPath;
            int symbol;
            Map<String, Integer> fileNameCountMap = Maps.newHashMap();
            int showCount = 0;
            String fileName;
            String head;
            String tail;
            for (Map<String, String> pathMap : pathList) {
                downloadPath = pathMap.get(CmnConst.SOURCE_PATH);
                symbol = "1".equals(pathMap.get(CmnConst.ENCRPT_SIGN)) ? -1 : 0;
         String downloadPath;
         int symbol;
         Map<String, Integer> fileNameCountMap = Maps.newHashMap();
         int showCount = 0;
         String fileName;
         String head;
         String tail;
         for (Map<String, String> pathMap : pathList) {
            downloadPath = pathMap.get(CmnConst.SOURCE_PATH);
            symbol = "1".equals(pathMap.get(CmnConst.ENCRPT_SIGN)) ? -1 : 0;
                //获得文件名
                fileName = pathMap.get(CmnConst.REAL_FILE_NAME);
                head = fileName.substring(0, fileName.lastIndexOf("."));
                tail = fileName.substring(fileName.lastIndexOf(".") + 1);
                showCount = fileNameCountMap.get(fileName) == null ? 0 : fileNameCountMap.get(fileName);
                if (showCount > 0) {
                    fileName = head + "(" + showCount + ")." + tail;
                }
                fileNameCountMap.put(fileName, ++showCount);
                logger.info(String.format("正在打包文件 %s", fileName));
            //获得文件名
            fileName = pathMap.get(CmnConst.REAL_FILE_NAME);
            head = fileName.substring(0, fileName.lastIndexOf("."));
            tail = fileName.substring(fileName.lastIndexOf(".") + 1);
            showCount = fileNameCountMap.get(fileName) == null ? 0 : fileNameCountMap.get(fileName);
            if (showCount > 0) {
               fileName = head + "(" + showCount + ")." + tail;
            }
            fileNameCountMap.put(fileName, ++showCount);
                //以论文标题为每个文件命名
                FileInputStream fis = new FileInputStream(downloadPath);
                out.putNextEntry(new ZipEntry(fileName));
            //以论文标题为每个文件命名
            FileInputStream fis = new FileInputStream(downloadPath);
            out.putNextEntry(new ZipEntry(fileName));
                //写入压缩包
                int len;
                byte[] buffer = new byte[1024];
                while ((len = fis.read(buffer)) > 0) {
                    if (symbol == 1) {
                        // 加密
                        logger.info("正在加密...");
                        out.write(encryption(buffer), 0, len);
                    } else if (symbol == -1) {
                        // 解密
                        logger.info("正在解密...");
                        out.write(decryption(buffer), 0, len);
                    } else {
                        // 单纯的复制
                        out.write(buffer, 0, len);
                    }
                    size += len;
                }
                out.closeEntry();
                fis.close();
            }
            out.close();
            out.flush();
            return size;
        } catch (Exception e) {
            throw new BaseException(FileCode.LOAD_FTP_PROPERTIES_FAIL.getValue(), FileCode.LOAD_FTP_PROPERTIES_FAIL.getText(), e);
        }
    }
            //写入压缩包
            int len;
            byte[] buffer = new byte[1024];
            while ((len = fis.read(buffer)) > 0) {
               if (symbol == 1) {
                  // 加密
                  out.write(encryption(buffer), 0, len);
               } else if (symbol == -1) {
                  // 解密
                  out.write(decryption(buffer), 0, len);
               } else {
                  // 单纯的复制
                  out.write(buffer, 0, len);
               }
               size += len;
            }
            out.closeEntry();
            fis.close();
         }
         out.close();
         out.flush();
         return size;
      } catch (Exception e) {
         throw new BaseException(FileCode.LOAD_FTP_PROPERTIES_FAIL.getValue(), FileCode.LOAD_FTP_PROPERTIES_FAIL.getText(), e);
      }
   }
    /**
     * 拷贝文件
     *
     * @param sourceFile
     * @param aimPath
     * @param symbol     1:加密,-1:解密,0:不动
     */
    public static File copyFile(File sourceFile, String aimPath, int symbol) {
        if (StringUtils.isEmpty(aimPath)) {
            throw new BaseException(FileCode.INVALID_FILE_PATH.getValue(), FileCode.INVALID_FILE_PATH.getText());
        }
        File aimFile = new File(aimPath);
        File aimDir = aimFile.getParentFile();
        if (!aimDir.exists()) {
            aimDir.mkdirs();
        }
        try (InputStream is = new FileInputStream(sourceFile);
             OutputStream os = new FileOutputStream(aimFile);) {
            int len;
            byte[] b = new byte[1024];
            while ((len = is.read(b)) > 0) {
                if (symbol == 1) {
                    // 加密
                    os.write(encryption(b), 0, len);
                } else if (symbol == -1) {
                    // 解密
                    os.write(decryption(b), 0, len);
                } else {
                    // 单纯的复制
                    os.write(b, 0, len);
                }
            }
            os.flush();
            return aimFile;
        } catch (IOException e) {
            throw new BaseException(FileCode.COPY_FILE_FAIL.getValue(), FileCode.COPY_FILE_FAIL.getText(), e);
        }
    }
   /**
    * 拷贝文件
    *
    * @param sourceFile
    * @param aimPath
    * @param symbol     1:加密,-1:解密,0:不动
    */
   public static File copyFile(File sourceFile, String aimPath, int symbol) {
      if (StringUtils.isEmpty(aimPath)) {
         throw new BaseException(FileCode.INVALID_FILE_PATH.getValue(), FileCode.INVALID_FILE_PATH.getText());
      }
      File aimFile = new File(aimPath);
      File aimDir = aimFile.getParentFile();
      if (!aimDir.exists()) {
         aimDir.mkdirs();
      }
      try (InputStream is = new FileInputStream(sourceFile);
          OutputStream os = new FileOutputStream(aimFile);) {
         int len;
         byte[] b = new byte[1024];
         while ((len = is.read(b)) > 0) {
            if (symbol == 1) {
               // 加密
               os.write(encryption(b), 0, len);
            } else if (symbol == -1) {
               // 解密
               os.write(decryption(b), 0, len);
            } else {
               // 单纯的复制
               os.write(b, 0, len);
            }
         }
         os.flush();
         return aimFile;
      } catch (IOException e) {
         throw new BaseException(FileCode.COPY_FILE_FAIL.getValue(), FileCode.COPY_FILE_FAIL.getText(), e);
      }
   }
    public static void copyFile(File sourceFile, String aimPath) {
        copyFile(sourceFile, aimPath, 0);
    }
   public static void copyFile(File sourceFile, String aimPath) {
      copyFile(sourceFile, aimPath, 0);
   }
    /**
     * 加密
     *
     * @param bytes
     * @return
     */
    public static byte[] encryption(byte[] bytes) {
        /**
         * 设置一个加密算法,要求可逆,还可以通过解密得到原来的东西
         * 我们这样做:每一个字节的值,都加上它的索引号
         * 然后,交换第一个字节和最后一个字节的位置,即加密结束
         */
        for (int i = 0; i < bytes.length; i++) {
            bytes[i] = (byte) (bytes[i] + i);
        }
        byte temp = bytes[0];
        bytes[0] = bytes[bytes.length - 1];
        bytes[bytes.length - 1] = temp;
        return bytes;
   /**
    * 加密
    *
    * @param bytes
    * @return
    */
   public static byte[] encryption(byte[] bytes) {
      /**
       * 设置一个加密算法,要求可逆,还可以通过解密得到原来的东西
       * 我们这样做:每一个字节的值,都加上它的索引号
       * 然后,交换第一个字节和最后一个字节的位置,即加密结束
       */
      for (int i = 0; i < bytes.length; i++) {
         bytes[i] = (byte) (bytes[i] + i);
      }
      byte temp = bytes[0];
      bytes[0] = bytes[bytes.length - 1];
      bytes[bytes.length - 1] = temp;
      return bytes;
    }
   }
    /**
     * 解密
     *
     * @param bytes
     * @return
     */
    public static byte[] decryption(byte[] bytes) {
        /**
         * 解密算法,是加密的逆过程
         * 先交换第一个字节和最后一个字节的位置
         * 然后,每一个字节的值,都减去它的索引号
         */
        byte temp = bytes[0];
        bytes[0] = bytes[bytes.length - 1];
        bytes[bytes.length - 1] = temp;
        for (int i = 0; i < bytes.length; i++) {
            bytes[i] = (byte) (bytes[i] - i);
        }
        return bytes;
    }
   /**
    * 解密
    *
    * @param bytes
    * @return
    */
   public static byte[] decryption(byte[] bytes) {
      /**
       * 解密算法,是加密的逆过程
       * 先交换第一个字节和最后一个字节的位置
       * 然后,每一个字节的值,都减去它的索引号
       */
      byte temp = bytes[0];
      bytes[0] = bytes[bytes.length - 1];
      bytes[bytes.length - 1] = temp;
      for (int i = 0; i < bytes.length; i++) {
         bytes[i] = (byte) (bytes[i] - i);
      }
      return bytes;
   }
}