123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231 |
- package com.smppw.modaq.infrastructure.util;
- import cn.hutool.core.collection.CollUtil;
- import cn.hutool.core.collection.ListUtil;
- import cn.hutool.core.io.FileUtil;
- import cn.hutool.core.util.StrUtil;
- import net.sf.sevenzipjbinding.ExtractOperationResult;
- import net.sf.sevenzipjbinding.IInArchive;
- import net.sf.sevenzipjbinding.SevenZip;
- import net.sf.sevenzipjbinding.SevenZipException;
- import net.sf.sevenzipjbinding.impl.RandomAccessFileInStream;
- import net.sf.sevenzipjbinding.simple.ISimpleInArchive;
- import net.sf.sevenzipjbinding.simple.ISimpleInArchiveItem;
- import org.apache.commons.compress.archivers.ArchiveEntry;
- import org.apache.commons.compress.archivers.ArchiveException;
- import org.apache.commons.compress.archivers.ArchiveInputStream;
- import org.apache.commons.compress.archivers.ArchiveStreamFactory;
- import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
- import org.apache.commons.compress.archivers.zip.ZipFile;
- import org.apache.commons.io.IOUtils;
- import java.io.*;
- import java.nio.file.Files;
- import java.nio.file.Path;
- import java.nio.file.Paths;
- import java.util.Arrays;
- import java.util.Enumeration;
- import java.util.List;
- public class ExcelUtil {
- // 候选编码列表(按常见顺序排列)
- private static final List<String> CANDIDATE_ENCODINGS = Arrays.asList(
- "GBK", // 中文环境常用
- "UTF-8", // 标准编码
- "GB2312", // 旧版中文
- "ISO-8859-1" // 默认回退
- );
- public static boolean isExcel(String fileName) {
- return StrUtil.isNotBlank(fileName) && (fileName.endsWith("xls") || fileName.endsWith("xlsx") || fileName.endsWith("XLS") || fileName.endsWith("XLSX"));
- }
- public static boolean isPdf(String fileName) {
- return StrUtil.isNotBlank(fileName) && (fileName.endsWith("pdf") || fileName.endsWith("PDF"));
- }
- public static boolean isZip(String fileName) {
- return StrUtil.isNotBlank(fileName) && (fileName.endsWith("zip") || fileName.endsWith("ZIP"));
- }
- public static boolean isHTML(String fileName) {
- return StrUtil.isNotBlank(fileName) && fileName.endsWith("html");
- }
- public static boolean isRAR(String fileName) {
- return StrUtil.isNotBlank(fileName) && (fileName.endsWith("rar") || fileName.endsWith("RAR"));
- }
- public static List<String> extractCompressedFiles(String zipFilePath, String destFilePath) throws IOException, ArchiveException {
- List<String> filePathList = CollUtil.newArrayList();
- File destFile = FileUtil.file(destFilePath);
- if (!destFile.exists()) {
- Files.createDirectories(destFile.toPath());
- }
- String encoding = detectEncoding(zipFilePath);
- if (encoding == null) {
- encoding = "GBK";
- }
- try (BufferedInputStream fis = new BufferedInputStream(new FileInputStream(zipFilePath));
- ArchiveInputStream<? extends ArchiveEntry> ais = new ArchiveStreamFactory()
- .createArchiveInputStream(ArchiveStreamFactory.detect(fis), fis, encoding)) {
- ArchiveEntry entry;
- while ((entry = ais.getNextEntry()) != null) {
- String name = entry.getName();
- if (entry.isDirectory()) {
- File entryFile = FileUtil.file(destFilePath, name);
- Files.createDirectories(entryFile.toPath());
- } else {
- if (name.startsWith("__MACOSX/")) {
- continue;
- }
- String zipFilename = FileUtil.getName(destFilePath);
- if (zipFilename.contains("确认") && !name.contains("确认")) {
- String ext = FileUtil.extName(name);
- name = StrUtil.subBefore(name, ".", true);
- name = name + "_确认单." + ext;
- }
- File entryFile = FileUtil.file(destFilePath, name);
- try (FileOutputStream fos = new FileOutputStream(entryFile)) {
- IOUtils.copy(ais, fos);
- filePathList.add(entryFile.getPath());
- }
- }
- }
- } catch (Exception e) {
- if (e.getMessage() != null
- && (e.getMessage().contains("split")
- || e.getMessage().contains("volume"))) {
- filePathList.addAll(extractSplitZip(zipFilePath, destFilePath, encoding));
- } else {
- throw e;
- }
- }
- return filePathList;
- }
- public static List<String> extractSplitZip(String zipFilePath, String destFilePath, String encoding) throws IOException {
- List<String> resultList = ListUtil.list(false);
- File file = new File(zipFilePath);
- try (ZipFile zipFile = ZipFile.builder().setFile(file).setCharset(encoding).get()) {
- Enumeration<ZipArchiveEntry> entries = zipFile.getEntries();
- while (entries.hasMoreElements()) {
- ZipArchiveEntry entry = entries.nextElement();
- // 解压到目标目录
- try (InputStream is = zipFile.getInputStream(entry)) {
- Path path = Paths.get(destFilePath, entry.getName());
- FileUtil.del(path);
- Files.copy(is, path);
- resultList.add(path.toAbsolutePath().toString());
- }
- }
- }
- return resultList;
- }
- public static List<String> extractRar5(String rarFilePath, String outputDir) throws Exception {
- // 初始化 SevenZipJBinding 本地库
- SevenZip.initSevenZipFromPlatformJAR();
- RandomAccessFile randomAccessFile = null;
- IInArchive inArchive = null;
- List<String> resultList = ListUtil.list(false);
- try {
- // 打开 RAR 文件
- randomAccessFile = new RandomAccessFile(rarFilePath, "r");
- inArchive = SevenZip.openInArchive(null, new RandomAccessFileInStream(randomAccessFile));
- // 获取压缩包中的文件列表
- ISimpleInArchive simpleInArchive = inArchive.getSimpleInterface();
- for (ISimpleInArchiveItem item : simpleInArchive.getArchiveItems()) {
- if (!item.isFolder()) {
- resultList.add(extractItem(item, outputDir));
- }
- }
- } finally {
- // 释放资源
- if (inArchive != null) {
- inArchive.close();
- }
- if (randomAccessFile != null) {
- randomAccessFile.close();
- }
- }
- return resultList;
- }
- private static String extractItem(ISimpleInArchiveItem item, String outputDir) throws SevenZipException {
- String filePath = outputDir + File.separator + item.getPath();
- File outputFile = FileUtil.file(filePath);
- // 创建父目录
- File parentDir = outputFile.getParentFile();
- if (!parentDir.exists() && !parentDir.mkdirs()) {
- throw new SevenZipException("无法创建目录: " + parentDir.getAbsolutePath());
- }
- // 提取文件内容
- try (FileOutputStream fos = new FileOutputStream(outputFile)) {
- ExtractOperationResult result = item.extractSlow(data -> {
- try {
- fos.write(data);
- return data.length; // 返回写入的字节数
- } catch (IOException e) {
- throw new SevenZipException("写入文件失败", e);
- }
- });
- if (result != ExtractOperationResult.OK) {
- throw new SevenZipException("解压失败: " + result);
- }
- } catch (IOException e) {
- throw new SevenZipException("文件操作失败", e);
- }
- return outputFile.getAbsolutePath();
- }
- // 检测压缩包编码
- private static String detectEncoding(String zipPath) {
- for (String encoding : CANDIDATE_ENCODINGS) {
- try (BufferedInputStream fis = new BufferedInputStream(new FileInputStream(zipPath));
- ArchiveInputStream<? extends ArchiveEntry> ais = new ArchiveStreamFactory()
- .createArchiveInputStream(ArchiveStreamFactory.detect(fis), fis, encoding)) {
- ArchiveEntry entry = ais.getNextEntry();
- if (entry == null) continue; // 空压缩包
- String fileName = entry.getName();
- if (!hasInvalidCharacters(fileName)) {
- return encoding; // 找到有效编码
- }
- } catch (Exception e) {
- // 编码不支持或文件错误,继续尝试下一个
- }
- }
- return null;
- }
- // 检查文件名是否包含无效字符(如替换符)
- private static boolean hasInvalidCharacters(String fileName) {
- // 检查常见乱码符号:�或连续问号
- return fileName.contains("�") || fileName.matches(".*\\?{2,}.*");
- }
- public static void main(String[] args) throws Exception {
- String zipFilePath = "D:\\home\\wwwroot\\mo_report_file\\wangzaijun@simuwang.com\\20250321\\20250321143709排排网确认单.rar";
- String destFilePath = "D:\\home\\wwwroot\\mo_report_file\\wangzaijun@simuwang.com\\20250321";
- List<String> strings = extractRar5(zipFilePath, destFilePath);
- for (String string : strings) {
- System.out.println(string);
- }
- // List<String> fileList = extractCompressedFiles(zipFilePath, destFilePath);
- // for (String s : fileList) {
- // System.out.println(s);
- // }
- }
- }
|