This commit is contained in:
2025-10-27 13:47:03 +08:00
parent 8e5774955d
commit 135cc18c4e
5 changed files with 514 additions and 475 deletions

View File

@@ -20,9 +20,11 @@ import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.Arrays;
import java.util.Date;
import java.util.Iterator;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.List;
@Slf4j
public class PdfFileHelper {
@@ -390,7 +392,17 @@ public class PdfFileHelper {
return false;
}
}
Arrays.sort(fileArray);
// 按文件名中的数字片段正序排序(如 xxx.001.pdf, xxx.002.pdf
try {
log.info("mergePdf 接收到 {} 个PDF按文件名数字片段正序合并。", (fileArray == null ? 0 : fileArray.length));
if (fileArray != null) {
Arrays.sort(fileArray, new FileNameComparator());
for (int idx = 0; idx < fileArray.length; idx++) {
log.info("排序后合并顺序 {} -> {}", idx + 1, fileArray[idx]);
}
}
} catch (Exception ignore) {
}
Document document = null;
PdfCopy pdfCopy = null;
try {
@@ -768,6 +780,172 @@ public class PdfFileHelper {
mergePdf(fileArray, tarFile);
}
public static boolean mergeOfdAndPdf(String[] sourceFiles, String targetFile, String tempDir) {
if (sourceFiles == null || sourceFiles.length == 0) {
log.warn("输入文件数组为空");
return true;
}
Path tempPath = Paths.get(tempDir);
try {
if (!Files.exists(tempPath)) {
Files.createDirectories(tempPath);
}
} catch (Exception e) {
log.error("创建临时目录失败: {}", tempDir, e);
return false;
}
List<String> pdfFiles = new ArrayList<>();
List<String> tempFilesToDelete = new ArrayList<>();
try {
// 不在此处改变顺序,保持调用方传入顺序(调用方如需排序,请在外部完成)
try {
log.info("mergeOfdAndPdf 接收到 {} 个源文件(保持传入顺序)", (sourceFiles == null ? 0 : sourceFiles.length));
if (sourceFiles != null) {
for (int i = 0; i < sourceFiles.length; i++) {
log.info("顺序 {} -> {}", i + 1, sourceFiles[i]);
}
}
} catch (Exception ignore) {}
for (String filePath : sourceFiles) {
if (filePath == null || filePath.trim().isEmpty()) {
continue;
}
String lowerPath = filePath.toLowerCase();
if (lowerPath.endsWith(".pdf")) {
pdfFiles.add(filePath);
} else if (lowerPath.endsWith(".ofd")) {
// 将 OFD 转换后的 PDF 命名为原始文件名.pdf而非 UUID保证排序与可读性
String originalName = new File(filePath).getName();
String baseName = originalName.endsWith(".ofd") ? originalName.substring(0, originalName.length() - 4) : originalName;
// 简单清洗,防止异常字符
// 仅保留字母、数字、下划线、点和连字符,其他替换为下划线
String sanitized = baseName.replaceAll("[^\\w.-]+", "_");
Path outPath = Paths.get(tempDir, sanitized + ".pdf");
int suffix = 1;
while (Files.exists(outPath)) {
outPath = Paths.get(tempDir, sanitized + "(" + (suffix++) + ").pdf");
}
String tempPdfPath = outPath.toString();
try {
OfdToPdfUtil.ofdToPdf(filePath, tempPdfPath);
pdfFiles.add(tempPdfPath);
tempFilesToDelete.add(tempPdfPath);
log.info("OFD转换成功: {} -> {}", filePath, tempPdfPath);
} catch (Exception e) {
log.error("OFD转换失败: {}", filePath, e);
}
} else {
log.warn("不支持的文件格式: {}", filePath);
}
}
if (pdfFiles.isEmpty()) {
log.warn("没有可合并的PDF文件");
return false;
}
try {
log.info("最终参与合并的PDF顺序已按源文件名排序共 {} 个:", pdfFiles.size());
for (int i = 0; i < pdfFiles.size(); i++) {
log.info("合并顺序 {} -> {}", i + 1, pdfFiles.get(i));
}
} catch (Exception ignore) {}
boolean mergeSuccess = mergePdfFiles(
pdfFiles.toArray(new String[0]),
targetFile
);
return mergeSuccess;
} finally {
cleanupTempFiles(tempFilesToDelete);
}
}
/**
* 合并PDF文件(改进版)
*/
private static boolean mergePdfFiles(String[] fileArray, String targetFile) {
// 删除已存在的目标文件
File target = new File(targetFile);
if (target.exists() && !target.delete()) {
log.error("无法删除已存在的目标文件: {}", targetFile);
return false;
}
Document document = null;
PdfCopy pdfCopy = null;
try {
document = new Document();
pdfCopy = new PdfCopy(document, new FileOutputStream(targetFile));
document.open();
int successCount = 0;
int totalPages = 0;
try {
log.info("mergePdfFiles 将合并 {} 个PDF按如下顺序", (fileArray == null ? 0 : fileArray.length));
if (fileArray != null) {
for (int i = 0; i < fileArray.length; i++) {
log.info("合并顺序 {} -> {}", i + 1, fileArray[i]);
}
}
} catch (Exception ignore) {}
for (String filePath : fileArray) {
PdfReader reader = null;
try {
reader = new PdfReader(filePath);
int pages = reader.getNumberOfPages();
// 逐页添加
for (int i = 1; i <= pages; i++) {
pdfCopy.addPage(pdfCopy.getImportedPage(reader, i));
}
totalPages += pages;
successCount++;
log.info("已合并文件: {} ({}页)", filePath, pages);
} catch (Exception e) {
log.error("处理文件失败: {}", filePath, e);
} finally {
if (reader != null) {
try {
reader.close();
} catch (Exception e) {
log.warn("关闭reader失败", e);
}
}
}
}
log.info("合并完成: {}/{} 个文件, 共{}页",
successCount, fileArray.length, totalPages);
return successCount > 0;
} catch (Exception e) {
log.error("合并PDF失败", e);
return false;
} finally {
if (document != null && document.isOpen()) {
document.close();
}
}
}
/**
* 清理临时文件
*/
private static void cleanupTempFiles(List<String> tempFiles) {
for (String tempFile : tempFiles) {
try {
Files.deleteIfExists(Paths.get(tempFile));
log.debug("删除临时文件: {}", tempFile);
} catch (Exception e) {
log.warn("删除临时文件失败: {}", tempFile, e);
}
}
}
}