This commit is contained in:
2025-10-27 09:28:10 +08:00
parent 17bd458302
commit 8e5774955d
5 changed files with 417 additions and 104 deletions

123
pom.xml
View File

@@ -187,11 +187,11 @@
<artifactId>lombok</artifactId> <artifactId>lombok</artifactId>
<version>1.18.16</version> <version>1.18.16</version>
</dependency> </dependency>
<!-- <dependency>--> <!-- <dependency>-->
<!-- <groupId>dm</groupId>--> <!-- <groupId>dm</groupId>-->
<!-- <artifactId>dm.jdbc.driver</artifactId>--> <!-- <artifactId>dm.jdbc.driver</artifactId>-->
<!-- <version>1.6</version>--> <!-- <version>1.6</version>-->
<!-- </dependency>--> <!-- </dependency>-->
<!-- CXF webservice --> <!-- CXF webservice -->
<dependency> <dependency>
@@ -240,7 +240,7 @@
<dependency> <dependency>
<groupId>org.apache.pdfbox</groupId> <groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId> <artifactId>pdfbox</artifactId>
<version>2.0.3</version> <version>2.0.27</version>
</dependency> </dependency>
<dependency> <dependency>
@@ -275,13 +275,13 @@
<systemPath>${basedir}/src/main/lib/twain4java-0.3.3-all.jar</systemPath> <systemPath>${basedir}/src/main/lib/twain4java-0.3.3-all.jar</systemPath>
</dependency> </dependency>
<!-- <dependency>--> <!-- <dependency>-->
<!-- <groupId>rt</groupId>--> <!-- <groupId>rt</groupId>-->
<!-- <artifactId>rt</artifactId>--> <!-- <artifactId>rt</artifactId>-->
<!-- <version>0.0.1</version>--> <!-- <version>0.0.1</version>-->
<!-- <scope>system</scope>--> <!-- <scope>system</scope>-->
<!-- <systemPath>${basedir}/src/main/lib/rt-0.0.1.jar</systemPath>--> <!-- <systemPath>${basedir}/src/main/lib/rt-0.0.1.jar</systemPath>-->
<!-- </dependency>--> <!-- </dependency>-->
<dependency> <dependency>
<groupId>jce</groupId> <groupId>jce</groupId>
@@ -345,7 +345,6 @@
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.aspose</groupId> <groupId>com.aspose</groupId>
<artifactId>aspose-words</artifactId> <artifactId>aspose-words</artifactId>
@@ -363,11 +362,11 @@
</dependency> </dependency>
<!-- excel转pdf --> <!-- excel转pdf -->
<!-- <dependency>--> <!-- <dependency>-->
<!-- <groupId>com.aspose</groupId>--> <!-- <groupId>com.aspose</groupId>-->
<!-- <artifactId>aspose-cells</artifactId>--> <!-- <artifactId>aspose-cells</artifactId>-->
<!-- <version>24.7</version>--> <!-- <version>24.7</version>-->
<!-- </dependency>--> <!-- </dependency>-->
<!-- 图片转pdf 判断方向 --> <!-- 图片转pdf 判断方向 -->
<dependency> <dependency>
@@ -397,14 +396,13 @@
</dependency> </dependency>
<!-- &lt;!&ndash; 单点登录&ndash;&gt;--> <!-- &lt;!&ndash; 单点登录&ndash;&gt;-->
<!-- <dependency>--> <!-- <dependency>-->
<!-- <groupId>org.keycloak</groupId>--> <!-- <groupId>org.keycloak</groupId>-->
<!-- <artifactId>keycloak-spring-boot-starter</artifactId>--> <!-- <artifactId>keycloak-spring-boot-starter</artifactId>-->
<!-- <version>10.0.2</version>--> <!-- <version>10.0.2</version>-->
<!-- <scope>provided</scope>--> <!-- <scope>provided</scope>-->
<!-- </dependency>--> <!-- </dependency>-->
<dependency> <dependency>
<groupId>org.springframework</groupId> <groupId>org.springframework</groupId>
@@ -412,12 +410,12 @@
<version>4.3.6.RELEASE</version> <version>4.3.6.RELEASE</version>
</dependency> </dependency>
<!-- sqlServer 驱动 --> <!-- sqlServer 驱动 -->
<!-- <dependency>--> <!-- <dependency>-->
<!-- <groupId>com.microsoft.sqlserver</groupId>--> <!-- <groupId>com.microsoft.sqlserver</groupId>-->
<!-- <artifactId>sqljdbc4</artifactId>--> <!-- <artifactId>sqljdbc4</artifactId>-->
<!-- <version>4.0</version>--> <!-- <version>4.0</version>-->
<!-- </dependency>--> <!-- </dependency>-->
<!--aop--> <!--aop-->
<dependency> <dependency>
@@ -432,13 +430,13 @@
<!-- 人大金仓 JDBC 驱动 --> <!-- 人大金仓 JDBC 驱动 -->
<!-- <dependency>--> <!-- <dependency>-->
<!-- <groupId>com.kingbase8</groupId>--> <!-- <groupId>com.kingbase8</groupId>-->
<!-- <artifactId>kingbase8</artifactId>--> <!-- <artifactId>kingbase8</artifactId>-->
<!-- <version>8.6.0</version>--> <!-- <version>8.6.0</version>-->
<!-- <scope>system</scope>--> <!-- <scope>system</scope>-->
<!-- <systemPath>${basedir}/src/main/lib/kingbase8-8.6.0.jar</systemPath>--> <!-- <systemPath>${basedir}/src/main/lib/kingbase8-8.6.0.jar</systemPath>-->
<!-- </dependency>--> <!-- </dependency>-->
<dependency> <dependency>
<groupId>com.highgo</groupId> <groupId>com.highgo</groupId>
@@ -505,11 +503,11 @@
<version>2.16.0</version> <version>2.16.0</version>
</dependency> </dependency>
<!-- <dependency>--> <!-- <dependency>-->
<!-- <groupId>org.apache.logging.log4j</groupId>--> <!-- <groupId>org.apache.logging.log4j</groupId>-->
<!-- <artifactId>log4j-slf4j-impl</artifactId>--> <!-- <artifactId>log4j-slf4j-impl</artifactId>-->
<!-- <version>2.16.0</version>--> <!-- <version>2.16.0</version>-->
<!-- </dependency>--> <!-- </dependency>-->
<dependency> <dependency>
<groupId>org.apache.logging.log4j</groupId> <groupId>org.apache.logging.log4j</groupId>
@@ -539,6 +537,13 @@
<version>1.68</version> <version>1.68</version>
</dependency> </dependency>
<dependency>
<groupId>org.ofdrw</groupId>
<artifactId>ofdrw-full</artifactId>
<version>2.3.7</version>
</dependency>
</dependencies> </dependencies>
<build> <build>
@@ -572,21 +577,21 @@
<verbose>true</verbose> <verbose>true</verbose>
<overwrite>true</overwrite> <overwrite>true</overwrite>
</configuration> </configuration>
<!-- <executions> <!-- <executions>
<execution> <execution>
<id>Generate MyBatis Artifacts</id> <id>Generate MyBatis Artifacts</id>
<goals> <goals>
<goal>generate</goal> <goal>generate</goal>
</goals> </goals>
</execution> </execution>
</executions> </executions>
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>org.mybatis.generator</groupId> <groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId> <artifactId>mybatis-generator-core</artifactId>
<version>1.3.2</version> <version>1.3.2</version>
</dependency> </dependency>
</dependencies> --> </dependencies> -->
</plugin> </plugin>
</plugins> </plugins>

View File

@@ -10,6 +10,7 @@ import java.io.*;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.UUID; import java.util.UUID;
import java.util.zip.ZipEntry; import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream; import java.util.zip.ZipOutputStream;
@@ -103,6 +104,47 @@ public class DownloadZip {
return null; return null;
} }
/**
* 普通java文件下载方法适用于所有框架
* @param request
* @param response
* @param filesMap 需要打包下载的文件路径和文件名集合 key:绝对路径 value:压缩包内文件名
* @param zipBasePath 下载文件压缩包之前,必须创建一个空的文件压缩包(下载完成之后删除压缩文件包)zipBasePath 是此文件压缩包所在的文件目录
* @param zipName 下载压缩包的名称
* @return
* @throws IOException
*/
public static String downloadFilesZip(HttpServletRequest request, HttpServletResponse response, Map<String, String> filesMap, String zipBasePath, String zipName) throws Exception {
//将附件中多个文件进行压缩,批量打包下载文件
String zipFilePath = zipBasePath+ File.separator+zipName;
//IO流实现下载的功能
response.setContentType("text/html; charset=UTF-8"); //设置编码字符
response.setContentType("application/octet-stream"); //设置内容类型为下载类型
response.setHeader("Content-disposition", "attachment;filename="+new String(zipName.getBytes(),"iso-8859-1"));//设置下载的文件名称
OutputStream out = response.getOutputStream(); //创建页面返回方式为输出流,会自动弹出下载框
//压缩文件
File zip = new File(zipFilePath);
if (!zip.exists()){
zip.createNewFile();
}
//创建zip文件输出流
ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zip));
zipFile(zipBasePath,zipName, zipFilePath,filesMap,zos);
zos.close();
response.setHeader("Content-disposition", "attachment;filename="+new String(zipName.getBytes(),"iso-8859-1"));//设置下载的压缩文件名称
//将打包后的文件写到客户端,输出的方法同上,使用缓冲流输出
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(zipFilePath));
byte[] buff = new byte[bis.available()];
bis.read(buff);
bis.close();
out.write(buff);//输出数据文件
out.flush();//释放缓存
out.close();//关闭输出流
return null;
}
/** /**
* 压缩文件 * 压缩文件
* @param zipBasePath 临时压缩文件基础路径 * @param zipBasePath 临时压缩文件基础路径
@@ -151,6 +193,47 @@ public class DownloadZip {
return null; return null;
} }
/**
* 压缩文件
* @param zipBasePath 临时压缩文件基础路径
* @param zipName 临时压缩文件名称
* @param zipFilePath 临时压缩文件完整路径
* @param filesMap 需要压缩的文件路径和文件名集合 key:绝对路径 value:压缩包内文件名
* @throws IOException
*/
public static String zipFile(String zipBasePath, String zipName, String zipFilePath, Map<String, String> filesMap, ZipOutputStream zos) throws IOException {
//循环读取文件路径集合,获取每一个文件的路径
for(Map.Entry<String, String> entry : filesMap.entrySet()){
String filePath = entry.getKey();
String fileNameInZip = entry.getValue();
File inputFile = new File(filePath); //根据文件路径创建文件
if(inputFile.exists()) { //判断文件是否存在
if (inputFile.isFile()) { //判断是否属于文件,还是文件夹
//创建输入流读取文件
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(inputFile));
//将文件写入zip内即将文件进行打包
zos.putNextEntry(new ZipEntry(fileNameInZip));
//写入文件的方法,同上
int size = 0;
byte[] buffer = new byte[1024*1024]; //设置读取数据缓存大小
while ((size = bis.read(buffer)) > 0) {
zos.write(buffer, 0, size);
}
//关闭输入输出流
zos.closeEntry();
bis.close();
} else { //如果是文件夹则使用穷举的方法获取文件写入zip
// not handling directories for now
}
}
}
return null;
}
/** /**
* 压缩文件 * 压缩文件
* @param zipBasePath 临时压缩文件基础路径 * @param zipBasePath 临时压缩文件基础路径

View File

@@ -2,36 +2,48 @@ package com.point.strategy.common;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.io.*; import java.io.*;
import java.net.URLEncoder;
import java.nio.channels.FileChannel; import java.nio.channels.FileChannel;
public class FileUtil { public class FileUtil {
public static HttpServletResponse download(String path, HttpServletResponse response) { public static HttpServletResponse download(String path, HttpServletResponse response) {
InputStream fis = null;
OutputStream toClient = null;
try { try {
// path是指欲下载的文件的路径。 // path是指欲下载的文件的路径。
File file = new File(path); File file = new File(path);
// 取得文件名。 // 取得文件名。
String filename = file.getName(); String filename = file.getName();
// 取得文件的后缀名。
String ext = filename.substring(filename.lastIndexOf(".") + 1).toUpperCase();
// 以流的形式下载文件。 // 以流的形式下载文件。
InputStream fis = new BufferedInputStream(new FileInputStream(path)); fis = new BufferedInputStream(new FileInputStream(path));
byte[] buffer = new byte[fis.available()];
fis.read(buffer);
fis.close();
// 清空response // 清空response
response.reset(); response.reset();
// 设置response的Header // 设置response的Header
response.addHeader("Content-Disposition", "attachment;filename=" + new String(filename.getBytes())); response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));
response.addHeader("Content-Length", "" + file.length()); response.addHeader("Content-Length", "" + file.length());
OutputStream toClient = new BufferedOutputStream(response.getOutputStream()); toClient = new BufferedOutputStream(response.getOutputStream());
response.setContentType("application/octet-stream"); response.setContentType("application/octet-stream");
toClient.write(buffer); byte[] buffer = new byte[1024];
toClient.flush(); int bytesRead;
toClient.close(); while ((bytesRead = fis.read(buffer)) != -1) {
toClient.write(buffer, 0, bytesRead);
}
} catch (IOException ex) { } catch (IOException ex) {
ex.printStackTrace(); ex.printStackTrace();
} finally {
try {
if (fis != null) {
fis.close();
}
if (toClient != null) {
toClient.flush();
toClient.close();
}
} catch (IOException e) {
e.printStackTrace();
}
} }
return response; return response;
} }

View File

@@ -0,0 +1,29 @@
package com.point.strategy.common;
import org.ofdrw.converter.export.PDFExporterPDFBox;
import java.nio.file.Paths;
/**
* OFD转PDF工具类
*/
public class OfdToPdfUtil {
/**
* ofd转pdf
* @param resourceFilePath OFD源文件地址
* @param targetFilePath 需要输出PDF的目标地址
*/
public static void ofdToPdf(String resourceFilePath, String targetFilePath){
try {
// 按照OFD导出器的标准模式使用
PDFExporterPDFBox exporter = new PDFExporterPDFBox(
Paths.get(resourceFilePath),
Paths.get(targetFilePath)
);
exporter.export();
exporter.close();
} catch (Exception e) {
throw new RuntimeException("OFD转PDF失败: " + e.getMessage(), e);
}
}
}

View File

@@ -11,7 +11,6 @@ import com.point.strategy.bean.receive.编码;
import com.point.strategy.classTree.bean.ClassTree; import com.point.strategy.classTree.bean.ClassTree;
import com.point.strategy.classTree.mapper.ClassTreeMapper; import com.point.strategy.classTree.mapper.ClassTreeMapper;
import com.point.strategy.common.*; import com.point.strategy.common.*;
import com.point.strategy.dao.TentityStructDescriptionMapper;
import com.point.strategy.dao.TtableDescriptionMapper; import com.point.strategy.dao.TtableDescriptionMapper;
import com.point.strategy.dao.TtableStructDescriptionMapper; import com.point.strategy.dao.TtableStructDescriptionMapper;
import com.point.strategy.docTraditionArrange.docVolume.mapper.DanganguanliMapper; import com.point.strategy.docTraditionArrange.docVolume.mapper.DanganguanliMapper;
@@ -35,6 +34,7 @@ import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.dom4j.Document; import org.dom4j.Document;
import org.dom4j.Element; import org.dom4j.Element;
import org.dom4j.io.SAXReader; import org.dom4j.io.SAXReader;
import org.ofdrw.tool.merge.OFDMerger;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@@ -44,14 +44,14 @@ import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes; import org.springframework.web.context.request.ServletRequestAttributes;
import sun.management.resources.agent;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.awt.*; import java.awt.*;
import java.io.ByteArrayOutputStream; import java.io.*;
import java.io.File; import java.net.URLEncoder;
import java.io.FileOutputStream; import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.List; import java.util.List;
import java.util.*; import java.util.*;
@@ -186,7 +186,7 @@ public class FileManageService {
try { try {
String zipBasePath = tempPath + "\\temp2\\bb\\"; String zipBasePath = tempPath + "\\temp2\\bb\\";
FileUtil.makedir(zipBasePath); FileUtil.makedir(zipBasePath);
List<String> filePaths = new ArrayList<String>(); Map<String, String> filePaths = new HashMap<>();
String zipName = "批量下载" + DateUtil.date2String(new Date(), 3) + ".zip"; String zipName = "批量下载" + DateUtil.date2String(new Date(), 3) + ".zip";
//得到temp_file表数据列表 //得到temp_file表数据列表
String myTableName = ""; String myTableName = "";
@@ -201,6 +201,7 @@ public class FileManageService {
List<Map<String, Object>> dataList2 = danganguanliMapper.selectObject(parasMap2); List<Map<String, Object>> dataList2 = danganguanliMapper.selectObject(parasMap2);
for (Map<String, Object> tempFile_map : dataList2) { for (Map<String, Object> tempFile_map : dataList2) {
String file_name_server = StringUtil.formatMap(tempFile_map, "file_name_server"); String file_name_server = StringUtil.formatMap(tempFile_map, "file_name_server");
String file_name = StringUtil.formatMap(tempFile_map, "file_name");
String file_path = StringUtil.formatMap(tempFile_map, "file_path"); String file_path = StringUtil.formatMap(tempFile_map, "file_path");
String file_des = StringUtil.formatMap(tempFile_map, "file_des"); String file_des = StringUtil.formatMap(tempFile_map, "file_des");
//如果file_des后面有/就不加/没有就加一个 //如果file_des后面有/就不加/没有就加一个
@@ -209,7 +210,7 @@ public class FileManageService {
} }
//String dir = imgUpload + File.separator + file_path + File.separator + file_name_server; //String dir = imgUpload + File.separator + file_path + File.separator + file_name_server;
String dir = file_des + file_name_server; String dir = file_des + file_name_server;
filePaths.add(dir); filePaths.put(dir, file_name);
} }
//打包成zip文件 并下载 //打包成zip文件 并下载
DownloadZip.downloadFilesZip(request, response, filePaths, zipBasePath, zipName); DownloadZip.downloadFilesZip(request, response, filePaths, zipBasePath, zipName);
@@ -245,7 +246,7 @@ public class FileManageService {
//批量下载档案复制 //批量下载档案复制
String zipBasePath = tempPath + "\\temp2\\bb\\"; String zipBasePath = tempPath + "\\temp2\\bb\\";
FileUtil.makedir(zipBasePath); FileUtil.makedir(zipBasePath);
List<String> filePaths = new ArrayList<String>(); Map<String, String> filesMap = new HashMap<>();
String zipName = "批量下载" + DateUtil.date2String(new Date(), 3) + ".zip"; String zipName = "批量下载" + DateUtil.date2String(new Date(), 3) + ".zip";
//得到temp_file表数据列表 //得到temp_file表数据列表
String myTableName = tableName + "_file"; String myTableName = tableName + "_file";
@@ -255,14 +256,16 @@ public class FileManageService {
List<Map<String, Object>> dataList2 = danganguanliMapper.selectObject(parasMap2); List<Map<String, Object>> dataList2 = danganguanliMapper.selectObject(parasMap2);
for (Map<String, Object> tempFile_map : dataList2) { for (Map<String, Object> tempFile_map : dataList2) {
String file_name_server = StringUtil.formatMap(tempFile_map, "file_name_server"); String file_name_server = StringUtil.formatMap(tempFile_map, "file_name_server");
String file_name = StringUtil.formatMap(tempFile_map, "file_name");
String file_path = StringUtil.formatMap(tempFile_map, "file_path"); String file_path = StringUtil.formatMap(tempFile_map, "file_path");
String file_des = StringUtil.formatMap(tempFile_map, "file_des"); String file_des = StringUtil.formatMap(tempFile_map, "file_des");
//String dir = imgUpload + File.separator + file_path + File.separator + file_name_server; //String dir = imgUpload + File.separator + file_path + File.separator + file_name_server;
String dir = file_des + File.separator + file_name_server; String dir = file_des + File.separator + file_name_server;
filePaths.add(dir + file_name_server); String fileNameInZip = StringUtils.isNotEmpty(file_name) ? file_name : file_name_server;
filesMap.put(dir, fileNameInZip);
} }
//打包成zip文件 并下载 //打包成zip文件 并下载
DownloadZip.downloadFilesZip(request, response, filePaths, zipBasePath, zipName); DownloadZip.downloadFilesZip(request, response, filesMap, zipBasePath, zipName);
//删除临时文件夹目录 //删除临时文件夹目录
FileUtil.delAllFile(zipBasePath); FileUtil.delAllFile(zipBasePath);
} catch (Exception e) { } catch (Exception e) {
@@ -1269,6 +1272,8 @@ public class FileManageService {
HttpServletRequest request, HttpServletRequest request,
HttpServletResponse response, HttpServletResponse response,
Integer type) { Integer type) {
logger.info("开始合并下载流程文件ID: {}, 表名: {}", fileIds, tableName);
List<File> tempFilesForCleanup = new ArrayList<>();
try { try {
String relative_path = "uploadFile/" + tableName + "_temp_file/" + fondscode + "/" + id; String relative_path = "uploadFile/" + tableName + "_temp_file/" + fondscode + "/" + id;
String dir = imgUpload + File.separator + relative_path; String dir = imgUpload + File.separator + relative_path;
@@ -1281,48 +1286,227 @@ public class FileManageService {
} }
parasMap2.put("conditionSql", " id in (" + fileIds + " )"); parasMap2.put("conditionSql", " id in (" + fileIds + " )");
List<Map<String, Object>> dataList2 = danganguanliMapper.selectObject(parasMap2); List<Map<String, Object>> dataList2 = danganguanliMapper.selectObject(parasMap2);
if (CollectionUtils.isEmpty(dataList2)) {
logger.warn("合并下载找不到任何文件文件ID: " + fileIds);
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
return;
}
logger.info("找到 {} 个待处理文件。", dataList2.size());
String temp_pdf = tempPath + "/temp_company_img/"; String temp_pdf = tempPath + "/temp_company_img/";
FileUtil.makedir(temp_pdf); FileUtil.makedir(temp_pdf);
String[] fileArray = new String[dataList2.size()]; List<String> fileList = new ArrayList<>();
UserRole userRole = userService.getUserRole(request); UserRole userRole = userService.getUserRole(request);
String userChnName = userRole.getUser().getUserChnName(); String userChnName = userRole.getUser().getUserChnName();
int i = 0;
for (Map<String, Object> tempFile_map : dataList2) { for (Map<String, Object> tempFile_map : dataList2) {
String file_name_server = StringUtil.formatMap(tempFile_map, "file_name_server"); String file_name_server = StringUtil.formatMap(tempFile_map, "file_name_server");
String file_des = StringUtil.formatMap(tempFile_map, "file_des"); String file_des = StringUtil.formatMap(tempFile_map, "file_des");
String srcImg = file_des + File.separator + file_name_server; String srcPath = file_des + File.separator + file_name_server;
logger.info("正在处理文件: {}", srcPath);
String srcpdfPath = destFilePdf(srcImg, userChnName); String extension = "";
int dotIndex = file_name_server.lastIndexOf('.');
if (dotIndex >= 0) {
extension = file_name_server.substring(dotIndex).toLowerCase();
}
fileArray[i] = srcpdfPath; if (extension.equals(".jpg") || extension.equals(".png") || extension.equals(".jpeg")) {
i++; String srcpdfPath = destFilePdf(srcPath, userChnName);
if (srcpdfPath != null) {
logger.info("成功将图片 {} 转换为PDF: {}", srcPath, srcpdfPath);
fileList.add(srcpdfPath);
tempFilesForCleanup.add(new File(srcpdfPath));
tempFilesForCleanup.add(new File(srcpdfPath.replace(".pdf", ".jpg")));
} else {
logger.error("处理并转换图片文件失败: {}", srcPath);
}
} else if (extension.equals(".pdf")) {
logger.info("文件已经是PDF格式将直接合并: {}", srcPath);
fileList.add(srcPath);
} else if (extension.equals(".ofd")) {
logger.info("文件是OFD格式将直接合并: {}", srcPath);
fileList.add(srcPath);
} else {
logger.warn("不支持合并的文件类型: {}. 已跳过此文件。", srcPath);
}
} }
String tarFile = temp_pdf + StringUtil.generaterUUID() + ".pdf";
PdfFileHelper.mergePdf(fileArray, tarFile);
String srcFile2 = tarFile; if (fileList.isEmpty()) {
String tarFile2 = temp_pdf + "setWaterMark-" + DateUtil.date2String(new Date(), 3) + ".pdf"; logger.error("没有文件被成功处理。正在中止合并下载。");
FileUtil.download(srcFile2, response); response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
return;
}
logger.info("待合并的文件列表: {}", StringUtils.join(fileList, ", "));
boolean hasOfd = fileList.stream().anyMatch(f -> f.toLowerCase().endsWith(".ofd"));
if (hasOfd) {
if (youhongIntegrate) {
logger.info("检测到OFD文件将转换为PDF后合并。");
List<String> pdfFileList = new ArrayList<>();
for (String filePath : fileList) {
if (filePath.toLowerCase().endsWith(".pdf")) {
// 已经是PDF直接添加
pdfFileList.add(filePath);
} else if (filePath.toLowerCase().endsWith(".ofd")) {
// OFD文件转换为PDF
String pdfPath = temp_pdf + StringUtil.generaterUUID() + ".pdf";
try {
OfdToPdfUtil.ofdToPdf(filePath, pdfPath);
pdfFileList.add(pdfPath);
tempFilesForCleanup.add(new File(pdfPath));
logger.info("成功将OFD {} 转换为PDF: {}", filePath, pdfPath);
} catch (Exception e) {
logger.error("OFD转PDF失败: {}", filePath, e);
continue;
}
}
}
if (pdfFileList.isEmpty()) {
logger.error("没有PDF文件可供合并。");
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
return;
}
// 统一使用PDF合并逻辑
String tarFile = temp_pdf + StringUtil.generaterUUID() + ".pdf";
tempFilesForCleanup.add(new File(tarFile));
logger.info("正在将 {} 个PDF文件合并到 {}", pdfFileList.size(), tarFile);
PdfFileHelper.mergePdf(pdfFileList.toArray(new String[0]), tarFile);
File mergedFile = new File(tarFile);
if (!mergedFile.exists() || mergedFile.length() == 0) {
logger.error("合并后的PDF文件不存在或是空的. 路径: {}", tarFile);
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
return;
}
logger.info("PDF合并完成。合并后文件大小: {} 字节。开始下载: {}", mergedFile.length(), tarFile);
FileUtil.download(tarFile, response);
} else {
logger.error("检测到OFD文件但OFD服务集成未启用无法合并。");
response.setStatus(HttpServletResponse.SC_NOT_IMPLEMENTED);
}
} else {
String tarFile = temp_pdf + StringUtil.generaterUUID() + ".pdf";
tempFilesForCleanup.add(new File(tarFile));
logger.info("正在将 {} 个PDF文件合并到 {}", fileList.size(), tarFile);
PdfFileHelper.mergePdf(fileList.toArray(new String[0]), tarFile);
File mergedFile = new File(tarFile);
if (!mergedFile.exists() || mergedFile.length() == 0) {
logger.error("合并后的文件不存在或是空的. 路径: {}", tarFile);
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
return;
}
logger.info("合并完成。合并后文件大小: {} 字节。开始下载: {}", mergedFile.length(), tarFile);
FileUtil.download(tarFile, response);
}
} catch (Exception e) { } catch (Exception e) {
logger.error("合并下载过程中发生错误", e);
e.printStackTrace(); e.printStackTrace();
} finally {
logger.info("开始清理 {} 个临时文件。", tempFilesForCleanup.size());
for (File tempFile : tempFilesForCleanup) {
if (tempFile != null && tempFile.exists()) {
logger.info("正在删除临时文件: {}", tempFile.getAbsolutePath());
if (!tempFile.delete()) {
logger.warn("删除临时文件失败: {}", tempFile.getAbsolutePath());
}
}
}
}
}
private void downloadOfdFile(String path, HttpServletResponse response) {
InputStream fis = null;
OutputStream toClient = null;
try {
File file = new File(path);
String filename = file.getName();
fis = new BufferedInputStream(new FileInputStream(path));
response.reset();
response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));
response.addHeader("Content-Length", "" + file.length());
toClient = new BufferedOutputStream(response.getOutputStream());
// 设置OFD文件的Content-Type
response.setContentType("application/ofd");
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = fis.read(buffer)) != -1) {
toClient.write(buffer, 0, bytesRead);
}
} catch (IOException ex) {
logger.error("下载OFD文件失败", ex);
} finally {
try {
if (fis != null) {
fis.close();
}
if (toClient != null) {
toClient.flush();
toClient.close();
}
} catch (IOException e) {
logger.error("关闭流失败", e);
}
} }
} }
private String destFilePdf(String srcImg, String userChnName) { private String destFilePdf(String srcImg, String userChnName) {
String destImg = srcImg.replaceAll(".jpg", "_waterMark.jpg"); File srcFile = new File(srcImg);
ImgUtil.pressText( if (!srcFile.exists() || srcFile.length() == 0) {
cn.hutool.core.io.FileUtil.file(srcImg), //源图片 logger.error("源图片文件不存在或是空的: {}", srcImg);
cn.hutool.core.io.FileUtil.file(destImg), //目标图片 return null;
userChnName + "(内部资料)", //水印文字 }
Color.red, //水印文字颜色 logger.info("源图片文件 {} 的大小: {} 字节", srcImg, srcFile.length());
new Font("黑体", Font.BOLD, 100), //字体
0, //x坐标修正值。 默认在中间,偏移量相对于中间偏移 int lastDotIndex = srcImg.lastIndexOf('.');
0, //y坐标修正值。 默认在中间,偏移量相对于中间偏移 if (lastDotIndex == -1) {
0.3f//透明度alpha 必须是范围 [0.0, 1.0] 之内(包含边界值)的一个浮点数字 logger.error("无法处理没有扩展名的文件: " + srcImg);
); return null;
}
String baseName = srcImg.substring(0, lastDotIndex);
String destImg = baseName + "_waterMark.jpg";
logger.info("正在添加水印: {} -> {}", srcImg, destImg);
try {
ImgUtil.pressText(
cn.hutool.core.io.FileUtil.file(srcImg), //源图片
cn.hutool.core.io.FileUtil.file(destImg), //目标图片
userChnName + "(内部资料)", //水印文字
Color.red, //水印文字颜色
new Font("黑体", Font.BOLD, 100), //字体
0, //x坐标修正值。 默认在中间,偏移量相对于中间偏移
0, //y坐标修正值。 默认在中间,偏移量相对于中间偏移
0.3f//透明度alpha 必须是范围 [0.0, 1.0] 之内(包含边界值)的一个浮点数字
);
} catch (Exception e) {
logger.error("给图片添加水印失败: {}", srcImg, e);
return null;
}
File watermarkedFile = new File(destImg);
if (!watermarkedFile.exists() || watermarkedFile.length() == 0) {
logger.error("带水印的图片未生成或是空的: {}", destImg);
return null;
}
logger.info("带水印的图片文件 {} 的大小: {} 字节", destImg, watermarkedFile.length());
String fromPath = destImg; String fromPath = destImg;
String toSource = destImg.replaceAll(".jpg", ".pdf"); String toSource = baseName + "_waterMark.pdf";
logger.info("正在将带水印的图片转换为PDF: {} -> {}", fromPath, toSource);
Img2pdf.jpg2pdfSortedByFilename(fromPath, toSource); Img2pdf.jpg2pdfSortedByFilename(fromPath, toSource);
File pdfFile = new File(toSource);
if (!pdfFile.exists() || pdfFile.length() == 0) {
logger.error("转换后的PDF文件未生成或是空的: {}", toSource);
return null;
}
logger.info("转换后的PDF文件 {} 的大小: {} 字节", toSource, pdfFile.length());
return toSource; return toSource;
} }