|
@@ -4,7 +4,6 @@ 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 com.smppw.modaq.common.dto.FilenamePathDTO;
|
|
|
import net.sf.sevenzipjbinding.ExtractOperationResult;
|
|
|
import net.sf.sevenzipjbinding.IInArchive;
|
|
|
import net.sf.sevenzipjbinding.SevenZip;
|
|
@@ -24,10 +23,19 @@ 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"));
|
|
|
}
|
|
@@ -48,37 +56,40 @@ public class ExcelUtil {
|
|
|
return StrUtil.isNotBlank(fileName) && (fileName.endsWith("rar") || fileName.endsWith("RAR"));
|
|
|
}
|
|
|
|
|
|
- public static List<FilenamePathDTO> extractCompressedFiles(String zipFilePath, String destFilePath) throws IOException, ArchiveException {
|
|
|
- List<FilenamePathDTO> filePathList = CollUtil.newArrayList();
|
|
|
+ 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(fis)) {
|
|
|
+ ArchiveInputStream<? extends ArchiveEntry> ais = new ArchiveStreamFactory()
|
|
|
+ .createArchiveInputStream(ArchiveStreamFactory.detect(fis), fis, encoding)) {
|
|
|
ArchiveEntry entry;
|
|
|
- int i = 1;
|
|
|
while ((entry = ais.getNextEntry()) != null) {
|
|
|
String name = entry.getName();
|
|
|
- if (name.startsWith("__MACOSX/")) {
|
|
|
- continue;
|
|
|
- }
|
|
|
- String zipFilename = FileUtil.getName(destFilePath);
|
|
|
- if (name.contains("确认")) {
|
|
|
- zipFilename += "_确认单";
|
|
|
- }
|
|
|
- String ext = FileUtil.extName(name);
|
|
|
- name = zipFilename + "_" + i + "." + ext;
|
|
|
- File entryFile = FileUtil.file(destFilePath, name);
|
|
|
- i++;
|
|
|
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 = "确认单_" + name;
|
|
|
+ }
|
|
|
+ File entryFile = FileUtil.file(destFilePath, name);
|
|
|
try (FileOutputStream fos = new FileOutputStream(entryFile)) {
|
|
|
IOUtils.copy(ais, fos);
|
|
|
- filePathList.add(new FilenamePathDTO(entryFile.getName(), entryFile.getPath()));
|
|
|
+ filePathList.add(entryFile.getPath());
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -86,7 +97,7 @@ public class ExcelUtil {
|
|
|
if (e.getMessage() != null
|
|
|
&& (e.getMessage().contains("split")
|
|
|
|| e.getMessage().contains("volume"))) {
|
|
|
- filePathList.addAll(extractSplitZip(zipFilePath, destFilePath));
|
|
|
+ filePathList.addAll(extractSplitZip(zipFilePath, destFilePath, encoding));
|
|
|
} else {
|
|
|
throw e;
|
|
|
}
|
|
@@ -95,10 +106,10 @@ public class ExcelUtil {
|
|
|
return filePathList;
|
|
|
}
|
|
|
|
|
|
- public static List<FilenamePathDTO> extractSplitZip(String zipFilePath, String destFilePath) throws IOException {
|
|
|
- List<FilenamePathDTO> resultList = ListUtil.list(false);
|
|
|
+ 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).get()) {
|
|
|
+ try (ZipFile zipFile = ZipFile.builder().setFile(file).setCharset(encoding).get()) {
|
|
|
Enumeration<ZipArchiveEntry> entries = zipFile.getEntries();
|
|
|
while (entries.hasMoreElements()) {
|
|
|
ZipArchiveEntry entry = entries.nextElement();
|
|
@@ -107,21 +118,21 @@ public class ExcelUtil {
|
|
|
Path path = Paths.get(destFilePath, entry.getName());
|
|
|
FileUtil.del(path);
|
|
|
Files.copy(is, path);
|
|
|
- resultList.add(new FilenamePathDTO(entry.getName(), path.toAbsolutePath().toString()));
|
|
|
+ resultList.add(path.toAbsolutePath().toString());
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
return resultList;
|
|
|
}
|
|
|
|
|
|
- public static List<FilenamePathDTO> extractRar5(String rarFilePath, String outputDir) throws Exception {
|
|
|
+ public static List<String> extractRar5(String rarFilePath, String outputDir) throws Exception {
|
|
|
// 初始化 SevenZipJBinding 本地库
|
|
|
SevenZip.initSevenZipFromPlatformJAR();
|
|
|
|
|
|
RandomAccessFile randomAccessFile = null;
|
|
|
IInArchive inArchive = null;
|
|
|
|
|
|
- List<FilenamePathDTO> resultList = ListUtil.list(false);
|
|
|
+ List<String> resultList = ListUtil.list(false);
|
|
|
try {
|
|
|
// 打开 RAR 文件
|
|
|
randomAccessFile = new RandomAccessFile(rarFilePath, "r");
|
|
@@ -131,7 +142,7 @@ public class ExcelUtil {
|
|
|
ISimpleInArchive simpleInArchive = inArchive.getSimpleInterface();
|
|
|
for (ISimpleInArchiveItem item : simpleInArchive.getArchiveItems()) {
|
|
|
if (!item.isFolder()) {
|
|
|
- resultList.add(new FilenamePathDTO(item.getPath(), extractItem(item, outputDir)));
|
|
|
+ resultList.add(extractItem(item, outputDir));
|
|
|
}
|
|
|
}
|
|
|
} finally {
|
|
@@ -176,11 +187,38 @@ public class ExcelUtil {
|
|
|
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<FilenamePathDTO> strings = extractRar5(zipFilePath, destFilePath);
|
|
|
- for (FilenamePathDTO string : strings) {
|
|
|
+ List<String> strings = extractRar5(zipFilePath, destFilePath);
|
|
|
+ for (String string : strings) {
|
|
|
System.out.println(string);
|
|
|
}
|
|
|
// List<String> fileList = extractCompressedFiles(zipFilePath, destFilePath);
|