todo
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
package com.point.strategy.common;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Comparator;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class FileNameComparator implements Comparator<String> {
|
||||
|
||||
private static final Pattern NUMBER_PATTERN = Pattern.compile("(\\d+)");
|
||||
|
||||
@Override
|
||||
public int compare(String s1, String s2) {
|
||||
String name1 = new File(s1).getName();
|
||||
String name2 = new File(s2).getName();
|
||||
|
||||
Matcher m1 = NUMBER_PATTERN.matcher(name1);
|
||||
Matcher m2 = NUMBER_PATTERN.matcher(name2);
|
||||
|
||||
int pos1 = 0, pos2 = 0;
|
||||
|
||||
while (m1.find() && m2.find()) {
|
||||
// 比较数字前的字符串部分
|
||||
String prefix1 = name1.substring(pos1, m1.start());
|
||||
String prefix2 = name2.substring(pos2, m2.start());
|
||||
|
||||
int prefixCompare = prefix1.compareTo(prefix2);
|
||||
if (prefixCompare != 0) {
|
||||
return prefixCompare;
|
||||
}
|
||||
|
||||
// 比较数字部分(按数值比较)
|
||||
Long num1 = Long.parseLong(m1.group());
|
||||
Long num2 = Long.parseLong(m2.group());
|
||||
|
||||
int numCompare = num1.compareTo(num2);
|
||||
if (numCompare != 0) {
|
||||
return numCompare;
|
||||
}
|
||||
|
||||
pos1 = m1.end();
|
||||
pos2 = m2.end();
|
||||
}
|
||||
|
||||
// 比较剩余部分
|
||||
String suffix1 = name1.substring(pos1);
|
||||
String suffix2 = name2.substring(pos2);
|
||||
|
||||
return suffix1.compareTo(suffix2);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.point.strategy.common;
|
||||
|
||||
import org.ofdrw.converter.ConvertHelper;
|
||||
import org.ofdrw.converter.export.PDFExporterPDFBox;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
@@ -16,12 +17,10 @@ public class OfdToPdfUtil {
|
||||
public static void ofdToPdf(String resourceFilePath, String targetFilePath){
|
||||
try {
|
||||
// 按照OFD导出器的标准模式使用
|
||||
PDFExporterPDFBox exporter = new PDFExporterPDFBox(
|
||||
Paths.get(resourceFilePath),
|
||||
Paths.get(targetFilePath)
|
||||
ConvertHelper.toPdf(
|
||||
Paths.get(resourceFilePath),
|
||||
Paths.get(targetFilePath)
|
||||
);
|
||||
exporter.export();
|
||||
exporter.close();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("OFD转PDF失败: " + e.getMessage(), e);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -202,6 +202,7 @@ public class UreportService {
|
||||
String tarFile = pathName + File.separator+ currentName + ".pdf";
|
||||
PdfFileHelper.mergePdf(arr, tarFile);
|
||||
|
||||
|
||||
}
|
||||
}else{
|
||||
//不是封面pdf
|
||||
|
||||
Reference in New Issue
Block a user