解决报错
This commit is contained in:
@@ -10,10 +10,12 @@ import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
/**
|
||||
* 策略工厂(根据文件类型选择策略)
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
public class FileComparisonStrategyFactory {
|
||||
|
||||
private final List<FileComparisonStrategy> strategies;
|
||||
@@ -36,12 +38,14 @@ public class FileComparisonStrategyFactory {
|
||||
String ext1 = getFileExtension(task.getFirstContractUrl());
|
||||
String ext2 = getFileExtension(task.getSecondContractUrl());
|
||||
|
||||
log.info("选择比对策略,扩展名: first={}, second={}", ext1, ext2);
|
||||
if (!ext1.equalsIgnoreCase(ext2)) {
|
||||
throw new ServiceException("两份文件类型不一致,无法对比");
|
||||
}
|
||||
|
||||
for (FileComparisonStrategy strategy : strategies) {
|
||||
if (strategy.supports(ext1)) {
|
||||
log.info("匹配到策略: {}", strategy.getClass().getSimpleName());
|
||||
return strategy;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -212,6 +212,14 @@ public class WordComparisonStrategy extends AbstractFileComparisonStrategy imple
|
||||
pdfFile = targetFile;
|
||||
}
|
||||
}
|
||||
// 校验目标PDF是否可读,提前捕获异常并提升错误可见性
|
||||
try (PDDocument doc = Loader.loadPDF(pdfFile)) {
|
||||
if (doc == null || doc.getNumberOfPages() <= 0) {
|
||||
throw new ServiceException("生成的PDF无法解析或页数为0");
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new ServiceException("生成的PDF无法被PDFBox加载: " + e.getMessage());
|
||||
}
|
||||
// 更新合同URL为新的PDF文件路径
|
||||
String newUrl = "/profile/upload/" + needUploadName;
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import com.documents4j.api.IConverter;
|
||||
import com.documents4j.job.LocalConverter;
|
||||
import com.qingyun.common.config.QingYunConfig;
|
||||
import com.qingyun.common.utils.file.FileUploadUtils;
|
||||
import com.qingyun.common.constant.Constants;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.apache.pdfbox.Loader;
|
||||
@@ -19,6 +20,8 @@ import javax.imageio.ImageIO;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Future;
|
||||
@@ -99,9 +102,37 @@ public class PdfUtil {
|
||||
String newName = name.substring(0, name.lastIndexOf("."));
|
||||
String projectUrl = QingYunConfig.getProjectUrl();
|
||||
File tempFile = File.createTempFile(newName + System.currentTimeMillis(), getFileExtension(name));
|
||||
long file = HttpUtil.downloadFile(projectUrl + pdfUrl, tempFile);
|
||||
if (file <= 0) {
|
||||
throw new IOException("无法下载 PDF 文件");
|
||||
|
||||
/**
|
||||
* 下载或本地复制文件到临时目录
|
||||
* - 当路径以 /profile 开头时,直接从容器本地文件系统复制,避免网关/反代造成的HTML错误页
|
||||
* - 否则通过 HTTP 下载
|
||||
*/
|
||||
if (pdfUrl != null && pdfUrl.startsWith(Constants.RESOURCE_PREFIX)) {
|
||||
String localPath = pdfUrl.replaceFirst(Constants.RESOURCE_PREFIX, QingYunConfig.getProfile());
|
||||
File source = new File(localPath);
|
||||
if (!source.exists() || !source.isFile()) {
|
||||
throw new IOException("本地文件不存在或无效: " + localPath);
|
||||
}
|
||||
Files.copy(source.toPath(), tempFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
|
||||
} else {
|
||||
long size = HttpUtil.downloadFile(projectUrl + pdfUrl, tempFile);
|
||||
if (size <= 0) {
|
||||
throw new IOException("无法下载文件: " + projectUrl + pdfUrl);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 若为PDF后缀,进行签名与解析预检测
|
||||
*/
|
||||
if (".pdf".equalsIgnoreCase(getFileExtension(name))) {
|
||||
try (PDDocument doc = Loader.loadPDF(tempFile)) {
|
||||
if (doc == null || doc.getNumberOfPages() <= 0) {
|
||||
throw new IOException("下载的PDF无法解析或页数为0");
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new IOException("下载的PDF无法被PDFBox加载: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
return tempFile;
|
||||
}
|
||||
@@ -126,6 +157,16 @@ public class PdfUtil {
|
||||
File outputFile = new File(wordFile.getParent(),
|
||||
FilenameUtils.getBaseName(wordFile.getName()) + ".pdf");
|
||||
|
||||
/**
|
||||
* 将 Word 文件转换为 PDF(Windows)
|
||||
* - 使用 documents4j 本地转换器进行格式转换
|
||||
* - 转换完成后进行健全性校验:文件存在、非空、可被 PDFBox 正常加载
|
||||
* - 若校验失败则抛出 IOException,避免后续流程在解析阶段失败
|
||||
*
|
||||
* @param wordFile 待转换的 Word 临时文件
|
||||
* @return 转换后的 PDF 文件对象
|
||||
* @throws IOException 当转换或校验失败时抛出
|
||||
*/
|
||||
try {
|
||||
IConverter converter = LocalConverter.builder().build();
|
||||
|
||||
@@ -134,7 +175,20 @@ public class PdfUtil {
|
||||
.to(outputFile).as(DocumentType.PDF)
|
||||
.prioritizeWith(1000) // optional
|
||||
.schedule();
|
||||
conversion.get(); // 这里会阻塞直到转换完成
|
||||
conversion.get(); // 阻塞直到转换完成
|
||||
|
||||
// 基础校验:文件存在且非空
|
||||
if (!outputFile.exists() || outputFile.length() == 0) {
|
||||
throw new IOException("PDF文件未生成或为空");
|
||||
}
|
||||
// 尝试用 PDFBox 打开以验证文件有效性
|
||||
try (PDDocument doc = Loader.loadPDF(outputFile)) {
|
||||
if (doc == null || doc.getNumberOfPages() <= 0) {
|
||||
throw new IOException("生成的PDF无法解析或页数为0");
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new IOException("生成的PDF无法被PDFBox加载: " + e.getMessage(), e);
|
||||
}
|
||||
return outputFile;
|
||||
|
||||
} catch (Exception e) {
|
||||
|
||||
Reference in New Issue
Block a user