| | |
| | | package com.product.file.util; |
| | | |
| | | import cn.hutool.core.lang.UUID; |
| | | import cn.hutool.core.util.IdUtil; |
| | | import cn.hutool.poi.word.WordUtil; |
| | | import com.aspose.words.Document; |
| | | 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 lombok.extern.slf4j.Slf4j; |
| | | import org.apache.commons.text.WordUtils; |
| | | import org.apache.log4j.Logger; |
| | | import org.apache.poi.openxml4j.opc.OPCPackage; |
| | | import org.apache.poi.xwpf.usermodel.XWPFDocument; |
| | | |
| | | import java.io.*; |
| | | import java.util.List; |
| | |
| | | * @Author: 6c |
| | | * @Description: |
| | | */ |
| | | @Slf4j |
| | | public class FileUtil { |
| | | private static Logger logger = Logger.getLogger(FileUtil.class); |
| | | private static Properties properties; |
| | | private static Properties properties; |
| | | |
| | | |
| | | private FileUtil() { |
| | | } |
| | | |
| | | 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; |
| | | } |
| | | } |
| | | |
| | | public static File toDocx(File 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; |
| | | } |
| | | |
| | | /** |
| | | * 批量打包 |
| | | * |
| | | * @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) { |
| | | log.info("正在打包文件..."); |
| | | 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); |
| | | log.info(String.format("正在打包文件 %s", fileName)); |
| | | |
| | | //以论文标题为每个文件命名 |
| | | 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) { |
| | | // 加密 |
| | | log.info("正在加密..."); |
| | | out.write(encryption(buffer), 0, len); |
| | | } else if (symbol == -1) { |
| | | // 解密 |
| | | log.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); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 拷贝文件 |
| | | * |
| | | * @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; |
| | | } |
| | | } |