mirror of
https://gitee.com/kekingcn/file-online-preview.git
synced 2026-03-16 06:03:53 +08:00
1.修复压缩包 二级目录无法解压问题 修改压缩包生成PDF路径
2.修复PDF 带密码缓存问题 新增PDF带密码缓存方法 userToken 3.精简OFFICE 转换代码 4.精简TIF转换代码 新增TIF转换图片缓存 修复tif错误文件不自动释放内存 等待其他修复 5.修复下载方法错 特殊符号下载错误 6.调整文件名 统一方法在FileHandlerService 7.新增判断文件名是否被URL转义
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
package cn.keking.service;
|
||||
|
||||
import cn.keking.config.ConfigConstants;
|
||||
import cn.keking.model.FileType;
|
||||
import cn.keking.utils.RarUtils;
|
||||
import cn.keking.web.filter.BaseUrlFilter;
|
||||
@@ -12,6 +13,7 @@ import net.sf.sevenzipjbinding.simple.ISimpleInArchive;
|
||||
import net.sf.sevenzipjbinding.simple.ISimpleInArchiveItem;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
@@ -25,45 +27,49 @@ import java.util.List;
|
||||
@Component
|
||||
public class CompressFileReader {
|
||||
private final FileHandlerService fileHandlerService;
|
||||
private static final String fileDir = ConfigConstants.getFileDir();
|
||||
public CompressFileReader(FileHandlerService fileHandlerService) {
|
||||
this.fileHandlerService = fileHandlerService;
|
||||
}
|
||||
public String unRar(String paths, String passWord, String fileName) throws Exception {
|
||||
public String unRar(String filePath, String filePassword, String fileName, String fileKey) throws Exception {
|
||||
List<String> imgUrls = new ArrayList<>();
|
||||
String baseUrl = BaseUrlFilter.getBaseUrl();
|
||||
String archiveFileName = fileHandlerService.getFileNameFromPath(paths);
|
||||
String folderName = filePath.replace(fileDir, ""); //修复压缩包 多重目录获取路径错误
|
||||
if (!ObjectUtils.isEmpty(fileKey)) { //压缩包文件 直接赋予路径 不予下载
|
||||
folderName = "_decompression"+folderName;
|
||||
}
|
||||
RandomAccessFile randomAccessFile = null;
|
||||
IInArchive inArchive = null;
|
||||
try {
|
||||
randomAccessFile = new RandomAccessFile(paths, "r");
|
||||
randomAccessFile = new RandomAccessFile(filePath, "r");
|
||||
inArchive = SevenZip.openInArchive(null, new RandomAccessFileInStream(randomAccessFile));
|
||||
String folderName = paths.substring(paths.lastIndexOf(File.separator) + 1);
|
||||
String extractPath = paths.substring(0, paths.lastIndexOf(folderName));
|
||||
ISimpleInArchive simpleInArchive = inArchive.getSimpleInterface();
|
||||
final String[] str = {null};
|
||||
for (final ISimpleInArchiveItem item : simpleInArchive.getArchiveItems()) {
|
||||
if (!item.isFolder()) {
|
||||
ExtractOperationResult result;
|
||||
String finalFolderName = folderName;
|
||||
result = item.extractSlow(data -> {
|
||||
try {
|
||||
str[0] = RarUtils.getUtf8String(item.getPath());
|
||||
str[0] = RarUtils.getUtf8String(item.getPath());
|
||||
if (RarUtils.isMessyCode(str[0])){
|
||||
str[0] = new String(item.getPath().getBytes(StandardCharsets.ISO_8859_1), "gbk");
|
||||
}
|
||||
str[0] = str[0].replace("\\", File.separator); //Linux 下路径错误
|
||||
String str1 = str[0].substring(0, str[0].lastIndexOf(File.separator)+ 1);
|
||||
File file = new File(extractPath, folderName + "_" + File.separator + str1);
|
||||
File file = new File(fileDir, finalFolderName + "_" + File.separator + str1);
|
||||
if (!file.exists()) {
|
||||
file.mkdirs();
|
||||
}
|
||||
OutputStream out = new FileOutputStream( extractPath+ folderName + "_" + File.separator + str[0], true);
|
||||
OutputStream out = new FileOutputStream( fileDir+ finalFolderName + "_" + File.separator + str[0], true);
|
||||
IOUtils.write(data, out);
|
||||
out.close();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return Integer.parseInt(null);
|
||||
}
|
||||
return data.length;
|
||||
}, passWord);
|
||||
}, filePassword);
|
||||
if (result == ExtractOperationResult.OK) {
|
||||
FileType type = FileType.typeFromUrl(str[0]);
|
||||
if (type.equals(FileType.PICTURE)) {
|
||||
@@ -75,7 +81,7 @@ public class CompressFileReader {
|
||||
}
|
||||
}
|
||||
}
|
||||
return archiveFileName + "_";
|
||||
return folderName + "_";
|
||||
} catch (Exception e) {
|
||||
throw new Exception(e);
|
||||
} finally {
|
||||
|
||||
@@ -7,6 +7,7 @@ import cn.keking.service.cache.CacheService;
|
||||
import cn.keking.service.cache.NotResourceCache;
|
||||
import cn.keking.utils.EncodingDetects;
|
||||
import cn.keking.utils.KkFileUtils;
|
||||
import cn.keking.utils.UrlEncoderUtils;
|
||||
import cn.keking.utils.WebUtils;
|
||||
import cn.keking.web.filter.BaseUrlFilter;
|
||||
import com.aspose.cad.*;
|
||||
@@ -36,6 +37,9 @@ import org.springframework.util.StringUtils;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.*;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLDecoder;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
@@ -195,11 +199,13 @@ public class FileHandlerService implements InitializingBean {
|
||||
* @param index 图片索引
|
||||
* @return 图片访问地址
|
||||
*/
|
||||
private String getPdf2jpgUrl(String pdfName, int index) {
|
||||
private String getPdf2jpgUrl(String pdfName, int index,String fileKey) {
|
||||
String baseUrl = BaseUrlFilter.getBaseUrl();
|
||||
if (!ObjectUtils.isEmpty(fileKey)) { // 是压缩包文件 改变PDF生成图片的路径
|
||||
pdfName = "_decompression"+ pdfName;
|
||||
}
|
||||
String pdfFolder = pdfName.substring(0, pdfName.length() - 4);
|
||||
String urlPrefix;
|
||||
|
||||
try {
|
||||
urlPrefix = baseUrl + URLEncoder.encode(pdfFolder, uriEncoding).replaceAll("\\+", "%20");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
@@ -215,14 +221,14 @@ public class FileHandlerService implements InitializingBean {
|
||||
* @param pdfName pdf文件名称
|
||||
* @return 图片访问集合
|
||||
*/
|
||||
private List<String> loadPdf2jpgCache(String pdfFilePath, String pdfName) {
|
||||
private List<String> loadPdf2jpgCache(String pdfFilePath, String pdfName, String fileKey) {
|
||||
List<String> imageUrls = new ArrayList<>();
|
||||
Integer imageCount = this.getPdf2jpgCache(pdfFilePath);
|
||||
if (Objects.isNull(imageCount)) {
|
||||
return imageUrls;
|
||||
}
|
||||
IntStream.range(0, imageCount).forEach(i -> {
|
||||
String imageUrl = this.getPdf2jpgUrl(pdfName, i);
|
||||
String imageUrl = this.getPdf2jpgUrl(pdfName, i,fileKey);
|
||||
imageUrls.add(imageUrl);
|
||||
});
|
||||
return imageUrls;
|
||||
@@ -230,26 +236,28 @@ public class FileHandlerService implements InitializingBean {
|
||||
|
||||
/**
|
||||
* pdf文件转换成jpg图片集
|
||||
*
|
||||
* @param pdfFilePath pdf文件路径
|
||||
* @param pdfName pdf文件名称
|
||||
* @return 图片访问集合
|
||||
* fileNameFilePath pdf文件路径
|
||||
* pdfFilePath pdf输出文件路径
|
||||
* pdfName pdf文件名称
|
||||
* loadPdf2jpgCache 图片访问集合
|
||||
*/
|
||||
public List<String> pdf2jpg(String pdfFilePath, String pdfName, FileAttribute fileAttribute) throws Exception {
|
||||
public List<String> pdf2jpg(String fileNameFilePath,String pdfFilePath, String pdfName, FileAttribute fileAttribute) throws Exception {
|
||||
boolean forceUpdatedCache = fileAttribute.forceUpdatedCache();
|
||||
boolean userToken = fileAttribute.getUserToken();
|
||||
String filePassword = fileAttribute.getFilePassword();
|
||||
String fileKey = fileAttribute.getFileKey();
|
||||
String pdfPassword = null;
|
||||
PDDocument doc = null;
|
||||
PdfReader pdfReader = null;
|
||||
if (!forceUpdatedCache) {
|
||||
List<String> cacheResult = this.loadPdf2jpgCache(pdfFilePath, pdfName);
|
||||
List<String> cacheResult = this.loadPdf2jpgCache(pdfFilePath, pdfName,fileKey);
|
||||
if (!CollectionUtils.isEmpty(cacheResult)) {
|
||||
return cacheResult;
|
||||
}
|
||||
}
|
||||
List<String> imageUrls = new ArrayList<>();
|
||||
try {
|
||||
File pdfFile = new File(pdfFilePath);
|
||||
File pdfFile = new File(fileNameFilePath);
|
||||
if (!pdfFile.exists()) {
|
||||
return null;
|
||||
}
|
||||
@@ -268,36 +276,39 @@ public class FileHandlerService implements InitializingBean {
|
||||
imageFilePath = folder + File.separator + pageIndex + PDF2JPG_IMAGE_FORMAT;
|
||||
BufferedImage image = pdfRenderer.renderImageWithDPI(pageIndex, ConfigConstants.getPdf2JpgDpi(), ImageType.RGB);
|
||||
ImageIOUtil.writeImage(image, imageFilePath, ConfigConstants.getPdf2JpgDpi());
|
||||
String imageUrl = this.getPdf2jpgUrl(pdfName, pageIndex);
|
||||
String imageUrl = this.getPdf2jpgUrl(pdfName, pageIndex,fileKey);
|
||||
imageUrls.add(imageUrl);
|
||||
}
|
||||
try {
|
||||
if (ObjectUtils.isEmpty(filePassword)){
|
||||
pdfReader = new PdfReader(pdfFilePath); //读取PDF文件
|
||||
}else {
|
||||
pdfReader = new PdfReader(pdfFilePath,filePassword.getBytes()); //读取PDF文件
|
||||
if (!ObjectUtils.isEmpty(filePassword)){ //获取到密码 判断是否是加密文件
|
||||
pdfReader = new PdfReader(fileNameFilePath); //读取PDF文件 通过异常获取该文件是否有密码字符
|
||||
}
|
||||
} catch (Exception e) { //获取异常方法 判断是否有加密字符串
|
||||
Throwable[] throwableArray = ExceptionUtils.getThrowables(e);
|
||||
for (Throwable throwable : throwableArray) {
|
||||
if (throwable instanceof IOException || throwable instanceof EncryptedDocumentException) {
|
||||
if (e.getMessage().toLowerCase().contains(PDF_PASSWORD_MSG)) {
|
||||
pdfPassword = PDF_PASSWORD_MSG;
|
||||
pdfPassword = PDF_PASSWORD_MSG; //查询到该文件是密码文件 输出带密码的值
|
||||
}
|
||||
}
|
||||
}
|
||||
logger.error("Convert pdf exception, pdfFilePath:{}", pdfFilePath, e);
|
||||
if (!PDF_PASSWORD_MSG.equals(pdfPassword)) { //该文件异常 错误原因非密码原因输出错误
|
||||
logger.error("Convert pdf exception, pdfFilePath:{}", pdfFilePath, e);
|
||||
}
|
||||
|
||||
} finally {
|
||||
if (pdfReader != null) { //关闭
|
||||
pdfReader.close();
|
||||
}
|
||||
}
|
||||
//判断是否加密文件 加密文件不缓存
|
||||
if (!PDF_PASSWORD_MSG.equals(pdfPassword)) {
|
||||
|
||||
if (userToken || !PDF_PASSWORD_MSG.equals(pdfPassword)) { //加密文件 判断是否启用缓存命令
|
||||
this.addPdf2jpgCache(pdfFilePath, pageCount);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
logger.error("Convert pdf to jpg exception, pdfFilePath:{}", pdfFilePath, e);
|
||||
if (!e.getMessage().contains(PDF_PASSWORD_MSG) ) {
|
||||
logger.error("Convert pdf to jpg exception, pdfFilePath:{}", pdfFilePath, e);
|
||||
}
|
||||
throw new Exception(e);
|
||||
} finally {
|
||||
if (doc != null) { //关闭
|
||||
@@ -411,8 +422,14 @@ public class FileHandlerService implements InitializingBean {
|
||||
FileAttribute attribute = new FileAttribute();
|
||||
String suffix;
|
||||
FileType type;
|
||||
String fileName;
|
||||
String fileName; //原始文件名
|
||||
String cacheName; //缓存文件名
|
||||
String cacheUnifyName; //缓存文件名统一去除文件后缀名
|
||||
String cacheListName; //缓存列表文件名称
|
||||
String outFilePath; //生成文件的路径
|
||||
String fileNameFilePath; //原始文件路径
|
||||
String fullFileName = WebUtils.getUrlParameterReg(url, "fullfilename");
|
||||
String fileKey = WebUtils.getUrlParameterReg(url, "kkCompressfileKey"); //压缩包指定特殊符号
|
||||
if (StringUtils.hasText(fullFileName)) {
|
||||
fileName = fullFileName;
|
||||
type = FileType.typeFromFileName(fullFileName);
|
||||
@@ -428,23 +445,62 @@ public class FileHandlerService implements InitializingBean {
|
||||
type = FileType.typeFromUrl(url);
|
||||
suffix = WebUtils.suffixFromUrl(url);
|
||||
}
|
||||
if (url.contains("?fileKey=")) {
|
||||
String[] strs = url.split("="); //处理解压后有反代情况下 文件的路径
|
||||
String urlStrr = getSubString(url, strs[1]);
|
||||
urlStrr = urlStrr.substring(0,urlStrr.lastIndexOf("?"));
|
||||
fileName = strs[1] + urlStrr.trim();
|
||||
attribute.setSkipDownLoad(true);
|
||||
if (!ObjectUtils.isEmpty(fileKey)) { //判断是否使用特定压缩包符号
|
||||
try {
|
||||
URL urll = new URL(url);
|
||||
fileName = urll.getPath(); //压缩包类型文件 获取解压后的绝对地址 不在执行重复下载方法
|
||||
attribute.setSkipDownLoad(true);
|
||||
} catch (MalformedURLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
url = WebUtils.encodeUrlFileName(url);
|
||||
if(UrlEncoderUtils.hasUrlEncoded(fileName) && UrlEncoderUtils.hasUrlEncoded(suffix)){ //判断文件名是否转义
|
||||
try {
|
||||
fileName = URLDecoder.decode(fileName, "UTF-8").replaceAll("\\+", "%20");
|
||||
suffix = URLDecoder.decode(suffix, "UTF-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
fileName = KkFileUtils.htmlEscape(fileName); //文件名处理
|
||||
boolean isHtml = suffix.equalsIgnoreCase("xls") || suffix.equalsIgnoreCase("xlsx") || suffix.equalsIgnoreCase("csv") || suffix.equalsIgnoreCase("xlsm") || suffix.equalsIgnoreCase("xlt") || suffix.equalsIgnoreCase("xltm") || suffix.equalsIgnoreCase("et") || suffix.equalsIgnoreCase("ett") || suffix.equalsIgnoreCase("xlam");
|
||||
cacheUnifyName = fileName.substring(0, fileName.lastIndexOf(".") ) + suffix+"."; //这里统一文件名处理 下面更具类型 各自添加后缀
|
||||
if(type.equals(FileType.OFFICE)){
|
||||
cacheName = cacheUnifyName +(isHtml ? "html" : "pdf"); //生成文件添加类型后缀 防止同名文件
|
||||
}else if(type.equals(FileType.PDF)){
|
||||
cacheName = fileName;
|
||||
}else if(type.equals(FileType.MEDIA)){
|
||||
cacheName = cacheUnifyName +"mp4" ;
|
||||
}else if(type.equals(FileType.CAD)){
|
||||
String cadPreviewType = ConfigConstants.getCadPreviewType();
|
||||
cacheName = cacheUnifyName + cadPreviewType ; //生成文件添加类型后缀 防止同名文件
|
||||
}else if(type.equals(FileType.COMPRESS)){
|
||||
cacheName = fileName;
|
||||
}else if(type.equals(FileType.TIFF)){
|
||||
cacheName = cacheUnifyName + ConfigConstants.getTifPreviewType();
|
||||
}else {
|
||||
cacheName = fileName;
|
||||
}
|
||||
if (!ObjectUtils.isEmpty(fileKey)) { //判断是否使用特定压缩包符号
|
||||
cacheName = "_decompression"+ cacheName;
|
||||
}
|
||||
outFilePath = fileDir + cacheName;
|
||||
fileNameFilePath = fileDir + fileName;
|
||||
cacheListName = cacheUnifyName+"ListName"; //文件列表缓存文件名
|
||||
attribute.setType(type);
|
||||
attribute.setName(fileName);
|
||||
attribute.setcacheName(cacheName);
|
||||
attribute.setcacheListName(cacheListName);
|
||||
attribute.setisHtml(isHtml);
|
||||
attribute.setoutFilePath(outFilePath);
|
||||
attribute.setfileNameFilePath(fileNameFilePath);
|
||||
attribute.setSuffix(suffix);
|
||||
attribute.setUrl(url);
|
||||
if (req != null) {
|
||||
String officePreviewType = req.getParameter("officePreviewType");
|
||||
String forceUpdatedCache = req.getParameter("forceUpdatedCache");
|
||||
String fileKey = WebUtils.getUrlParameterReg(url, "fileKey");
|
||||
String userToken =req.getParameter("userToken");
|
||||
if (StringUtils.hasText(officePreviewType)) {
|
||||
attribute.setOfficePreviewType(officePreviewType);
|
||||
}
|
||||
@@ -464,10 +520,8 @@ public class FileHandlerService implements InitializingBean {
|
||||
if (StringUtils.hasText(filePassword)) {
|
||||
attribute.setFilePassword(filePassword);
|
||||
}
|
||||
|
||||
String userToken = req.getParameter("userToken");
|
||||
if (StringUtils.hasText(userToken)) {
|
||||
attribute.setUserToken(userToken);
|
||||
if ("true".equalsIgnoreCase(userToken)) {
|
||||
attribute.setUserToken(true);
|
||||
}
|
||||
String kkProxyAuthorization = req.getHeader( "kk-proxy-authorization");
|
||||
attribute.setKkProxyAuthorization(kkProxyAuthorization);
|
||||
|
||||
@@ -10,6 +10,7 @@ import cn.keking.utils.KkFileUtils;
|
||||
import cn.keking.web.filter.BaseUrlFilter;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import static cn.keking.service.impl.OfficeFilePreviewImpl.getPreviewType;
|
||||
@@ -23,7 +24,6 @@ public class CadFilePreviewImpl implements FilePreview {
|
||||
|
||||
private static final String OFFICE_PREVIEW_TYPE_IMAGE = "image";
|
||||
private static final String OFFICE_PREVIEW_TYPE_ALL_IMAGES = "allImages";
|
||||
private static final String FILE_DIR = ConfigConstants.getFileDir();
|
||||
|
||||
private final FileHandlerService fileHandlerService;
|
||||
private final OtherFilePreviewImpl otherFilePreview;
|
||||
@@ -40,18 +40,17 @@ public class CadFilePreviewImpl implements FilePreview {
|
||||
String baseUrl = BaseUrlFilter.getBaseUrl();
|
||||
boolean forceUpdatedCache=fileAttribute.forceUpdatedCache();
|
||||
String fileName = fileAttribute.getName();
|
||||
String suffix = fileAttribute.getSuffix();
|
||||
String cadPreviewType = ConfigConstants.getCadPreviewType();
|
||||
String pdfName = fileName.substring(0, fileName.lastIndexOf(".")) + suffix +"." + cadPreviewType ; //生成文件添加类型后缀 防止同名文件
|
||||
String outFilePath = FILE_DIR + pdfName;
|
||||
String cacheName = fileAttribute.getcacheName();
|
||||
String outFilePath = fileAttribute.getoutFilePath();
|
||||
String fileKey = fileAttribute.getFileKey(); //判断是否压缩包
|
||||
// 判断之前是否已转换过,如果转换过,直接返回,否则执行转换
|
||||
if (forceUpdatedCache || !fileHandlerService.listConvertedFiles().containsKey(pdfName) || !ConfigConstants.isCacheEnabled()) {
|
||||
String filePath;
|
||||
ReturnResponse<String> response = DownloadUtils.downLoad(fileAttribute, null);
|
||||
if (forceUpdatedCache || !fileHandlerService.listConvertedFiles().containsKey(cacheName) || !ConfigConstants.isCacheEnabled()) {
|
||||
ReturnResponse<String> response = DownloadUtils.downLoad(fileAttribute, fileName);
|
||||
if (response.isFailure()) {
|
||||
return otherFilePreview.notSupportedFile(model, fileAttribute, response.getMsg());
|
||||
}
|
||||
filePath = response.getContent();
|
||||
String filePath = response.getContent();
|
||||
String imageUrls = null;
|
||||
if (StringUtils.hasText(outFilePath)) {
|
||||
try {
|
||||
@@ -63,26 +62,26 @@ public class CadFilePreviewImpl implements FilePreview {
|
||||
return otherFilePreview.notSupportedFile(model, fileAttribute, "office转图片异常,请联系管理员");
|
||||
}
|
||||
//是否保留CAD源文件
|
||||
if( ConfigConstants.getDeleteSourceFile()) {
|
||||
if(ObjectUtils.isEmpty(fileKey) && ConfigConstants.getDeleteSourceFile()) {
|
||||
KkFileUtils.deleteFileByPath(filePath);
|
||||
}
|
||||
if (ConfigConstants.isCacheEnabled()) {
|
||||
// 加入缓存
|
||||
fileHandlerService.addConvertedFile(pdfName, fileHandlerService.getRelativePath(outFilePath));
|
||||
fileHandlerService.addConvertedFile(cacheName, fileHandlerService.getRelativePath(outFilePath));
|
||||
}
|
||||
}
|
||||
}
|
||||
if("tif".equalsIgnoreCase(cadPreviewType)){
|
||||
model.addAttribute("currentUrl", pdfName);
|
||||
model.addAttribute("currentUrl", cacheName);
|
||||
return TIFF_FILE_PREVIEW_PAGE;
|
||||
}else if("svg".equalsIgnoreCase(cadPreviewType)){
|
||||
model.addAttribute("currentUrl", pdfName);
|
||||
model.addAttribute("currentUrl", cacheName);
|
||||
return SVG_FILE_PREVIEW_PAGE;
|
||||
}
|
||||
if (baseUrl != null && (OFFICE_PREVIEW_TYPE_IMAGE.equals(officePreviewType) || OFFICE_PREVIEW_TYPE_ALL_IMAGES.equals(officePreviewType))) {
|
||||
return getPreviewType(model, fileAttribute, officePreviewType, baseUrl, pdfName, outFilePath, fileHandlerService, OFFICE_PREVIEW_TYPE_IMAGE,otherFilePreview);
|
||||
return getPreviewType(model, fileAttribute, officePreviewType, cacheName, outFilePath, fileHandlerService, OFFICE_PREVIEW_TYPE_IMAGE,otherFilePreview);
|
||||
}
|
||||
model.addAttribute("pdfUrl", pdfName);
|
||||
model.addAttribute("pdfUrl", cacheName);
|
||||
return PDF_FILE_PREVIEW_PAGE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,6 +39,7 @@ public class CompressFilePreviewImpl implements FilePreview {
|
||||
String fileName=fileAttribute.getName();
|
||||
String filePassword = fileAttribute.getFilePassword();
|
||||
boolean forceUpdatedCache=fileAttribute.forceUpdatedCache();
|
||||
String fileKey = fileAttribute.getFileKey(); //判断是否压缩包
|
||||
String fileTree = null;
|
||||
// 判断文件名是否存在(redis缓存读取)
|
||||
if (forceUpdatedCache || !StringUtils.hasText(fileHandlerService.getConvertedFile(fileName)) || !ConfigConstants.isCacheEnabled()) {
|
||||
@@ -48,7 +49,7 @@ public class CompressFilePreviewImpl implements FilePreview {
|
||||
}
|
||||
String filePath = response.getContent();
|
||||
try {
|
||||
fileTree = compressFileReader.unRar(filePath, filePassword,fileName);
|
||||
fileTree = compressFileReader.unRar(filePath, filePassword,fileName,fileKey);
|
||||
} catch (Exception e) {
|
||||
Throwable[] throwableArray = ExceptionUtils.getThrowables(e);
|
||||
for (Throwable throwable : throwableArray) {
|
||||
@@ -62,7 +63,7 @@ public class CompressFilePreviewImpl implements FilePreview {
|
||||
}
|
||||
if (!ObjectUtils.isEmpty(fileTree)) {
|
||||
//是否保留压缩包源文件
|
||||
if (ConfigConstants.getDeleteSourceFile()) {
|
||||
if (ObjectUtils.isEmpty(fileKey) && ConfigConstants.getDeleteSourceFile()) {
|
||||
KkFileUtils.deleteFileByPath(filePath);
|
||||
}
|
||||
if (ConfigConstants.isCacheEnabled()) {
|
||||
|
||||
@@ -1,20 +1,18 @@
|
||||
package cn.keking.service.impl;
|
||||
|
||||
import cn.keking.config.ConfigConstants;
|
||||
import cn.keking.model.FileAttribute;
|
||||
import cn.keking.model.FileType;
|
||||
import cn.keking.model.ReturnResponse;
|
||||
import cn.keking.service.FilePreview;
|
||||
import cn.keking.utils.ConfigUtils;
|
||||
import cn.keking.utils.DownloadUtils;
|
||||
import cn.keking.service.FileHandlerService;
|
||||
import cn.keking.web.filter.BaseUrlFilter;
|
||||
import cn.keking.service.FilePreview;
|
||||
import cn.keking.utils.DownloadUtils;
|
||||
import org.bytedeco.ffmpeg.global.avcodec;
|
||||
import org.bytedeco.javacv.FFmpegFrameGrabber;
|
||||
import org.bytedeco.javacv.FFmpegFrameRecorder;
|
||||
import org.bytedeco.javacv.Frame;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.ui.Model;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
@@ -28,139 +26,120 @@ public class MediaFilePreviewImpl implements FilePreview {
|
||||
|
||||
private final FileHandlerService fileHandlerService;
|
||||
private final OtherFilePreviewImpl otherFilePreview;
|
||||
|
||||
private static Object LOCK=new Object();
|
||||
|
||||
private static final String mp4 = "mp4";
|
||||
public MediaFilePreviewImpl(FileHandlerService fileHandlerService, OtherFilePreviewImpl otherFilePreview) {
|
||||
this.fileHandlerService = fileHandlerService;
|
||||
this.otherFilePreview = otherFilePreview;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String filePreviewHandle(String url, Model model, FileAttribute fileAttribute) {
|
||||
// 不是http开头,浏览器不能直接访问,需下载到本地
|
||||
if (url != null && !url.toLowerCase().startsWith("http")) {
|
||||
ReturnResponse<String> response = DownloadUtils.downLoad(fileAttribute, fileAttribute.getName());
|
||||
if (response.isFailure()) {
|
||||
return otherFilePreview.notSupportedFile(model, fileAttribute, response.getMsg());
|
||||
} else {
|
||||
url=BaseUrlFilter.getBaseUrl() + fileHandlerService.getRelativePath(response.getContent());
|
||||
fileAttribute.setUrl(url);
|
||||
String fileName = fileAttribute.getName();
|
||||
String suffix = fileAttribute.getSuffix();
|
||||
String cacheName = fileAttribute.getcacheName();
|
||||
String outFilePath = fileAttribute.getoutFilePath();
|
||||
boolean forceUpdatedCache=fileAttribute.forceUpdatedCache();
|
||||
String[] mediaTypesConvert = FileType.MEDIA_TYPES_CONVERT; //获取支持的转换格式
|
||||
boolean mediaTypes = false;
|
||||
for(String temp : mediaTypesConvert){
|
||||
if (suffix.equals(temp)) {
|
||||
mediaTypes = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(checkNeedConvert(fileAttribute.getSuffix())){
|
||||
url=convertUrl(fileAttribute);
|
||||
}else{
|
||||
//正常media类型
|
||||
String[] medias = ConfigConstants.getMedia();
|
||||
for(String media:medias){
|
||||
if(media.equals(fileAttribute.getSuffix())){
|
||||
model.addAttribute("mediaUrl", url);
|
||||
return MEDIA_FILE_PREVIEW_PAGE;
|
||||
if(!url.toLowerCase().startsWith("http") || checkNeedConvert(mediaTypes)){ //不是http协议的 // 开启转换方式并是支持转换格式的
|
||||
if (forceUpdatedCache || !fileHandlerService.listConvertedFiles().containsKey(cacheName) || !ConfigConstants.isCacheEnabled()) { //查询是否开启缓存
|
||||
ReturnResponse<String> response = DownloadUtils.downLoad(fileAttribute, fileName);
|
||||
if (response.isFailure()) {
|
||||
return otherFilePreview.notSupportedFile(model, fileAttribute, response.getMsg());
|
||||
}
|
||||
String filePath = response.getContent();
|
||||
String convertedUrl = null;
|
||||
try {
|
||||
if(mediaTypes){
|
||||
convertedUrl=convertToMp4(filePath,outFilePath);
|
||||
}else {
|
||||
convertedUrl =outFilePath; //不是http协议的 但是不是转换格式的直接输出
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (convertedUrl == null ) {
|
||||
fileHandlerService.addConvertedFile(cacheName, "error"); //失败加入缓存
|
||||
return otherFilePreview.notSupportedFile(model, fileAttribute, "视频转换异常,请联系管理员");
|
||||
}
|
||||
if (ConfigConstants.isCacheEnabled()) {
|
||||
// 加入缓存
|
||||
fileHandlerService.addConvertedFile(cacheName, fileHandlerService.getRelativePath(outFilePath));
|
||||
}
|
||||
model.addAttribute("mediaUrl", fileHandlerService.getRelativePath(outFilePath));
|
||||
}else{
|
||||
model.addAttribute("mediaUrl", fileHandlerService.listConvertedFiles().get(cacheName));
|
||||
}
|
||||
return otherFilePreview.notSupportedFile(model, fileAttribute, "暂不支持");
|
||||
return MEDIA_FILE_PREVIEW_PAGE;
|
||||
}
|
||||
model.addAttribute("mediaUrl", url);
|
||||
return MEDIA_FILE_PREVIEW_PAGE;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查视频文件处理逻辑
|
||||
* 返回处理过后的url
|
||||
* @return url
|
||||
*/
|
||||
private String convertUrl(FileAttribute fileAttribute) {
|
||||
String url = fileAttribute.getUrl();
|
||||
if(fileHandlerService.listConvertedMedias().containsKey(url)){
|
||||
url= fileHandlerService.getConvertedMedias(url);
|
||||
}else{
|
||||
if(!fileHandlerService.listConvertedMedias().containsKey(url)){
|
||||
synchronized(LOCK){
|
||||
if(!fileHandlerService.listConvertedMedias().containsKey(url)){
|
||||
String convertedUrl=convertToMp4(fileAttribute);
|
||||
//加入缓存
|
||||
fileHandlerService.addConvertedMedias(url,convertedUrl);
|
||||
url=convertedUrl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查视频文件转换是否已开启,以及当前文件是否需要转换
|
||||
* @return
|
||||
*/
|
||||
private boolean checkNeedConvert(String suffix) {
|
||||
private boolean checkNeedConvert(boolean mediaTypes) {
|
||||
//1.检查开关是否开启
|
||||
if("false".equals(ConfigConstants.getMediaConvertDisable())){
|
||||
return false;
|
||||
}
|
||||
//2.检查当前文件是否需要转换
|
||||
String[] mediaTypesConvert = FileType.MEDIA_TYPES_CONVERT;
|
||||
String type = suffix;
|
||||
for(String temp : mediaTypesConvert){
|
||||
if(type.equals(temp)){
|
||||
return true;
|
||||
}
|
||||
if("true".equals(ConfigConstants.getMediaConvertDisable())){
|
||||
return mediaTypes;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将浏览器不兼容视频格式转换成MP4
|
||||
* @param fileAttribute
|
||||
* @return
|
||||
*/
|
||||
private static String convertToMp4(FileAttribute fileAttribute) {
|
||||
|
||||
//说明:这里做临时处理,取上传文件的目录
|
||||
String homePath = ConfigUtils.getHomePath();
|
||||
String filePath = homePath+File.separator+"file"+File.separator+"demo"+File.separator+fileAttribute.getName();
|
||||
String convertFileName=fileAttribute.getUrl().replace(fileAttribute.getSuffix(),"mp4");
|
||||
|
||||
File file=new File(filePath);
|
||||
FFmpegFrameGrabber frameGrabber = new FFmpegFrameGrabber(file);
|
||||
String fileName = null;
|
||||
Frame captured_frame = null;
|
||||
private static String convertToMp4(String filePath,String outFilePath)throws Exception {
|
||||
FFmpegFrameGrabber frameGrabber = FFmpegFrameGrabber.createDefault(filePath);
|
||||
Frame captured_frame;
|
||||
FFmpegFrameRecorder recorder = null;
|
||||
try {
|
||||
fileName = file.getAbsolutePath().replace(fileAttribute.getSuffix(),"mp4");
|
||||
File desFile=new File(fileName);
|
||||
//判断一下防止穿透缓存
|
||||
File desFile=new File(outFilePath);
|
||||
//判断一下防止重复转换
|
||||
if(desFile.exists()){
|
||||
return fileName;
|
||||
return outFilePath;
|
||||
}
|
||||
|
||||
frameGrabber.start();
|
||||
recorder = new FFmpegFrameRecorder(fileName, frameGrabber.getImageWidth(), frameGrabber.getImageHeight(), frameGrabber.getAudioChannels());
|
||||
recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264); //avcodec.AV_CODEC_ID_H264 //AV_CODEC_ID_MPEG4
|
||||
recorder.setFormat("mp4");
|
||||
recorder = new FFmpegFrameRecorder(outFilePath, frameGrabber.getImageWidth(), frameGrabber.getImageHeight(), frameGrabber.getAudioChannels());
|
||||
// recorder.setImageHeight(640);
|
||||
// recorder.setImageWidth(480);
|
||||
recorder.setFormat(mp4);
|
||||
recorder.setFrameRate(frameGrabber.getFrameRate());
|
||||
//recorder.setSampleFormat(frameGrabber.getSampleFormat()); //
|
||||
recorder.setSampleRate(frameGrabber.getSampleRate());
|
||||
|
||||
//视频编码属性配置 H.264 H.265 MPEG
|
||||
recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
|
||||
//设置视频比特率,单位:b
|
||||
recorder.setVideoBitrate(frameGrabber.getVideoBitrate());
|
||||
recorder.setAspectRatio(frameGrabber.getAspectRatio());
|
||||
// 设置音频通用编码格式
|
||||
recorder.setAudioCodec(avcodec.AV_CODEC_ID_AAC);
|
||||
//设置音频比特率,单位:b (比特率越高,清晰度/音质越好,当然文件也就越大 128000 = 182kb)
|
||||
recorder.setAudioBitrate(frameGrabber.getAudioBitrate());
|
||||
recorder.setAudioOptions(frameGrabber.getAudioOptions());
|
||||
recorder.setAudioChannels(frameGrabber.getAudioChannels());
|
||||
recorder.setFrameRate(frameGrabber.getFrameRate());
|
||||
recorder.start();
|
||||
while ((captured_frame = frameGrabber.grabFrame()) != null) {
|
||||
try {
|
||||
recorder.setTimestamp(frameGrabber.getTimestamp());
|
||||
recorder.record(captured_frame);
|
||||
} catch (Exception e) {
|
||||
while (true) {
|
||||
captured_frame = frameGrabber.grabFrame();
|
||||
if (captured_frame == null) {
|
||||
System.out.println("转码完成:"+filePath);
|
||||
break;
|
||||
}
|
||||
recorder.record(captured_frame);
|
||||
}
|
||||
recorder.stop();
|
||||
recorder.release();
|
||||
frameGrabber.stop();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}finally {
|
||||
if (recorder != null) { //关闭
|
||||
recorder.stop();
|
||||
recorder.close();
|
||||
}
|
||||
frameGrabber.stop();
|
||||
frameGrabber.close();
|
||||
}
|
||||
//是否删除源文件
|
||||
//file.delete();
|
||||
return convertFileName;
|
||||
return outFilePath;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -15,10 +15,10 @@ import org.apache.poi.EncryptedDocumentException;
|
||||
import org.jodconverter.core.office.OfficeException;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -30,7 +30,6 @@ public class OfficeFilePreviewImpl implements FilePreview {
|
||||
|
||||
public static final String OFFICE_PREVIEW_TYPE_IMAGE = "image";
|
||||
public static final String OFFICE_PREVIEW_TYPE_ALL_IMAGES = "allImages";
|
||||
private static final String FILE_DIR = ConfigConstants.getFileDir();
|
||||
private static final String OFFICE_PASSWORD_MSG = "password";
|
||||
|
||||
private final FileHandlerService fileHandlerService;
|
||||
@@ -47,16 +46,16 @@ public class OfficeFilePreviewImpl implements FilePreview {
|
||||
public String filePreviewHandle(String url, Model model, FileAttribute fileAttribute) {
|
||||
// 预览Type,参数传了就取参数的,没传取系统默认
|
||||
String officePreviewType = fileAttribute.getOfficePreviewType();
|
||||
boolean userToken = fileAttribute.getUserToken();
|
||||
String baseUrl = BaseUrlFilter.getBaseUrl();
|
||||
String suffix = fileAttribute.getSuffix();
|
||||
String fileName = fileAttribute.getName();
|
||||
String filePassword = fileAttribute.getFilePassword();
|
||||
boolean forceUpdatedCache=fileAttribute.forceUpdatedCache();
|
||||
String userToken = fileAttribute.getUserToken();
|
||||
boolean isHtml = suffix.equalsIgnoreCase("xls") || suffix.equalsIgnoreCase("xlsx") || suffix.equalsIgnoreCase("csv") || suffix.equalsIgnoreCase("xlsm") || suffix.equalsIgnoreCase("xlt") || suffix.equalsIgnoreCase("xltm") || suffix.equalsIgnoreCase("et") || suffix.equalsIgnoreCase("ett") || suffix.equalsIgnoreCase("xlam");
|
||||
String pdfName = fileName.substring(0, fileName.lastIndexOf(".") ) + suffix +"." +(isHtml ? "html" : "pdf"); //生成文件添加类型后缀 防止同名文件
|
||||
String cacheFileName = userToken == null ? pdfName : userToken + "_" + pdfName;
|
||||
String outFilePath = FILE_DIR + cacheFileName;
|
||||
String suffix = fileAttribute.getSuffix(); //获取文件后缀
|
||||
String fileName = fileAttribute.getName(); //获取文件原始名称
|
||||
String filePassword = fileAttribute.getFilePassword(); //获取密码
|
||||
boolean forceUpdatedCache=fileAttribute.forceUpdatedCache(); //是否启用强制更新命令
|
||||
boolean isHtml =fileAttribute.getisHtml(); //xlsx 转换成html
|
||||
String cacheName = fileAttribute.getcacheName(); //转换后的文件名
|
||||
String outFilePath = fileAttribute.getoutFilePath(); //转换后生成文件的路径
|
||||
String fileKey = fileAttribute.getFileKey(); //判断是否压缩包
|
||||
if (!officePreviewType.equalsIgnoreCase("html")) {
|
||||
if (ConfigConstants.getOfficeTypeWeb() .equalsIgnoreCase("web")) {
|
||||
if (suffix.equalsIgnoreCase("xlsx")) {
|
||||
@@ -69,40 +68,14 @@ public class OfficeFilePreviewImpl implements FilePreview {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (forceUpdatedCache|| !fileHandlerService.listConvertedFiles().containsKey(pdfName) || !ConfigConstants.isCacheEnabled()) {
|
||||
if (forceUpdatedCache|| !fileHandlerService.listConvertedFiles().containsKey(cacheName) || !ConfigConstants.isCacheEnabled()) {
|
||||
// 下载远程文件到本地,如果文件在本地已存在不会重复下载
|
||||
ReturnResponse<String> response = DownloadUtils.downLoad(fileAttribute, fileName);
|
||||
if (response.isFailure()) {
|
||||
return otherFilePreview.notSupportedFile(model, fileAttribute, response.getMsg());
|
||||
}
|
||||
String filePath = response.getContent();
|
||||
/*
|
||||
* 1. 缓存判断-如果文件已经进行转换过,就直接返回,否则执行转换
|
||||
* 2. 缓存判断-加密文件基于userToken进行缓存,如果没有就不缓存
|
||||
*/
|
||||
boolean isCached = false;
|
||||
boolean isUseCached = false;
|
||||
boolean isPwdProtectedOffice = false;
|
||||
if (ConfigConstants.isCacheEnabled()) {
|
||||
// 全局开启缓存
|
||||
isUseCached = true;
|
||||
if (!forceUpdatedCache && fileHandlerService.listConvertedFiles().containsKey(cacheFileName)) {
|
||||
// 存在缓存
|
||||
isCached = true;
|
||||
}
|
||||
if (OfficeUtils.isPwdProtected(filePath)) {
|
||||
isPwdProtectedOffice = true;
|
||||
if (!StringUtils.hasLength(userToken)) {
|
||||
// 不缓存没有userToken的加密文件
|
||||
isUseCached = false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
isPwdProtectedOffice = OfficeUtils.isPwdProtected(filePath);
|
||||
}
|
||||
|
||||
if (!isCached) {
|
||||
// 没有缓存执行转换逻辑
|
||||
String filePath = response.getContent();
|
||||
boolean isPwdProtectedOffice = OfficeUtils.isPwdProtected(filePath); // 判断是否加密文件
|
||||
if (isPwdProtectedOffice && !StringUtils.hasLength(filePassword)) {
|
||||
// 加密文件需要密码
|
||||
model.addAttribute("needFilePassword", true);
|
||||
@@ -118,40 +91,37 @@ public class OfficeFilePreviewImpl implements FilePreview {
|
||||
model.addAttribute("filePasswordError", true);
|
||||
return EXEL_FILE_PREVIEW_PAGE;
|
||||
}
|
||||
|
||||
return otherFilePreview.notSupportedFile(model, fileAttribute, "抱歉,该文件版本不兼容,文件版本错误。");
|
||||
}
|
||||
|
||||
if (isHtml) {
|
||||
// 对转换后的文件进行操作(改变编码方式)
|
||||
fileHandlerService.doActionConvertedFile(outFilePath);
|
||||
}
|
||||
//是否保留OFFICE源文件
|
||||
if (ConfigConstants.getDeleteSourceFile()) {
|
||||
if (ObjectUtils.isEmpty(fileKey) && ConfigConstants.getDeleteSourceFile()) {
|
||||
KkFileUtils.deleteFileByPath(filePath);
|
||||
}
|
||||
if (isUseCached) {
|
||||
if (userToken || !isPwdProtectedOffice) {
|
||||
// 加入缓存
|
||||
fileHandlerService.addConvertedFile(cacheFileName, fileHandlerService.getRelativePath(outFilePath));
|
||||
fileHandlerService.addConvertedFile(cacheName, fileHandlerService.getRelativePath(outFilePath));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if (!isHtml && baseUrl != null && (OFFICE_PREVIEW_TYPE_IMAGE.equals(officePreviewType) || OFFICE_PREVIEW_TYPE_ALL_IMAGES.equals(officePreviewType))) {
|
||||
return getPreviewType(model, fileAttribute, officePreviewType, baseUrl, cacheFileName, outFilePath, fileHandlerService, OFFICE_PREVIEW_TYPE_IMAGE, otherFilePreview);
|
||||
return getPreviewType(model, fileAttribute, officePreviewType, cacheName, outFilePath, fileHandlerService, OFFICE_PREVIEW_TYPE_IMAGE, otherFilePreview);
|
||||
}
|
||||
cacheFileName = URLEncoder.encode(cacheFileName).replaceAll("\\+", "%20");
|
||||
model.addAttribute("pdfUrl", cacheFileName);
|
||||
model.addAttribute("pdfUrl", cacheName);
|
||||
return isHtml ? EXEL_FILE_PREVIEW_PAGE : PDF_FILE_PREVIEW_PAGE;
|
||||
}
|
||||
|
||||
static String getPreviewType(Model model, FileAttribute fileAttribute, String officePreviewType, String baseUrl, String pdfName, String outFilePath, FileHandlerService fileHandlerService, String officePreviewTypeImage, OtherFilePreviewImpl otherFilePreview) {
|
||||
static String getPreviewType(Model model, FileAttribute fileAttribute, String officePreviewType, String pdfName, String outFilePath, FileHandlerService fileHandlerService, String officePreviewTypeImage, OtherFilePreviewImpl otherFilePreview) {
|
||||
String suffix = fileAttribute.getSuffix();
|
||||
boolean isPPT = suffix.equalsIgnoreCase("ppt") || suffix.equalsIgnoreCase("pptx");
|
||||
List<String> imageUrls = null;
|
||||
try {
|
||||
imageUrls = fileHandlerService.pdf2jpg(outFilePath, pdfName, fileAttribute);
|
||||
imageUrls = fileHandlerService.pdf2jpg(outFilePath,outFilePath, pdfName, fileAttribute);
|
||||
} catch (Exception e) {
|
||||
Throwable[] throwableArray = ExceptionUtils.getThrowables(e);
|
||||
for (Throwable throwable : throwableArray) {
|
||||
|
||||
@@ -24,37 +24,34 @@ public class PdfFilePreviewImpl implements FilePreview {
|
||||
|
||||
private final FileHandlerService fileHandlerService;
|
||||
private final OtherFilePreviewImpl otherFilePreview;
|
||||
private static final String FILE_DIR = ConfigConstants.getFileDir();
|
||||
private static final String PDF_PASSWORD_MSG = "password";
|
||||
|
||||
public PdfFilePreviewImpl(FileHandlerService fileHandlerService, OtherFilePreviewImpl otherFilePreview) {
|
||||
this.fileHandlerService = fileHandlerService;
|
||||
this.otherFilePreview = otherFilePreview;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String filePreviewHandle(String url, Model model, FileAttribute fileAttribute) {
|
||||
String fileName = fileAttribute.getName();
|
||||
String officePreviewType = fileAttribute.getOfficePreviewType();
|
||||
boolean forceUpdatedCache=fileAttribute.forceUpdatedCache();
|
||||
String pdfName = fileName.substring(0, fileName.lastIndexOf(".") + 1) + "pdf";
|
||||
String outFilePath = FILE_DIR + pdfName;
|
||||
String pdfName = fileAttribute.getName(); //获取原始文件名
|
||||
String officePreviewType = fileAttribute.getOfficePreviewType(); //转换类型
|
||||
boolean forceUpdatedCache=fileAttribute.forceUpdatedCache(); //是否启用强制更新命令
|
||||
String outFilePath = fileAttribute.getoutFilePath(); //生成的文件路径
|
||||
String fileNameFilePath = fileAttribute.getfileNameFilePath(); //原始文件路径
|
||||
if (OfficeFilePreviewImpl.OFFICE_PREVIEW_TYPE_IMAGE.equals(officePreviewType) || OfficeFilePreviewImpl.OFFICE_PREVIEW_TYPE_ALL_IMAGES.equals(officePreviewType)) {
|
||||
//当文件不存在时,就去下载
|
||||
if (forceUpdatedCache || !fileHandlerService.listConvertedFiles().containsKey(pdfName) || !ConfigConstants.isCacheEnabled()) {
|
||||
ReturnResponse<String> response = DownloadUtils.downLoad(fileAttribute, fileName);
|
||||
ReturnResponse<String> response = DownloadUtils.downLoad(fileAttribute, pdfName);
|
||||
if (response.isFailure()) {
|
||||
return otherFilePreview.notSupportedFile(model, fileAttribute, response.getMsg());
|
||||
}
|
||||
outFilePath = response.getContent();
|
||||
fileNameFilePath = response.getContent();
|
||||
if (ConfigConstants.isCacheEnabled()) {
|
||||
// 加入缓存
|
||||
fileHandlerService.addConvertedFile(pdfName, fileHandlerService.getRelativePath(outFilePath));
|
||||
fileHandlerService.addConvertedFile(pdfName, fileHandlerService.getRelativePath(fileNameFilePath));
|
||||
}
|
||||
}
|
||||
List<String> imageUrls;
|
||||
try {
|
||||
imageUrls = fileHandlerService.pdf2jpg(outFilePath, pdfName, fileAttribute);
|
||||
imageUrls = fileHandlerService.pdf2jpg(fileNameFilePath,outFilePath, pdfName, fileAttribute);
|
||||
} catch (Exception e) {
|
||||
Throwable[] throwableArray = ExceptionUtils.getThrowables(e);
|
||||
for (Throwable throwable : throwableArray) {
|
||||
@@ -91,7 +88,6 @@ public class PdfFilePreviewImpl implements FilePreview {
|
||||
fileHandlerService.addConvertedFile(pdfName, fileHandlerService.getRelativePath(outFilePath));
|
||||
}
|
||||
} else {
|
||||
pdfName = URLEncoder.encode(pdfName).replaceAll("\\+", "%20");
|
||||
model.addAttribute("pdfUrl", pdfName);
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
package cn.keking.service.impl;
|
||||
|
||||
import cn.keking.model.FileAttribute;
|
||||
import cn.keking.model.ReturnResponse;
|
||||
import cn.keking.service.FileHandlerService;
|
||||
import cn.keking.service.FilePreview;
|
||||
import cn.keking.utils.DownloadUtils;
|
||||
import cn.keking.utils.KkFileUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.ui.Model;
|
||||
@@ -21,12 +18,10 @@ import java.util.List;
|
||||
public class PictureFilePreviewImpl extends CommonPreviewImpl {
|
||||
|
||||
private final FileHandlerService fileHandlerService;
|
||||
private final OtherFilePreviewImpl otherFilePreview;
|
||||
|
||||
public PictureFilePreviewImpl(FileHandlerService fileHandlerService, OtherFilePreviewImpl otherFilePreview) {
|
||||
super(fileHandlerService, otherFilePreview);
|
||||
this.fileHandlerService = fileHandlerService;
|
||||
this.otherFilePreview = otherFilePreview;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -30,12 +30,12 @@ public class SimTextFilePreviewImpl implements FilePreview {
|
||||
this.fileHandlerService = fileHandlerService;
|
||||
this.otherFilePreview = otherFilePreview;
|
||||
}
|
||||
private static final String FILE_DIR = ConfigConstants.getFileDir();
|
||||
|
||||
@Override
|
||||
public String filePreviewHandle(String url, Model model, FileAttribute fileAttribute) {
|
||||
String fileName = fileAttribute.getName();
|
||||
boolean forceUpdatedCache=fileAttribute.forceUpdatedCache();
|
||||
String filePath = FILE_DIR + fileName;
|
||||
String filePath = fileAttribute.getfileNameFilePath();
|
||||
if (forceUpdatedCache || !fileHandlerService.listConvertedFiles().containsKey(fileName) || !ConfigConstants.isCacheEnabled()) {
|
||||
ReturnResponse<String> response = DownloadUtils.downLoad(fileAttribute, fileName);
|
||||
if (response.isFailure()) {
|
||||
|
||||
@@ -8,13 +8,11 @@ import cn.keking.service.FilePreview;
|
||||
import cn.keking.utils.ConvertPicUtil;
|
||||
import cn.keking.utils.DownloadUtils;
|
||||
import cn.keking.utils.KkFileUtils;
|
||||
import cn.keking.web.filter.BaseUrlFilter;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -32,75 +30,100 @@ public class TiffFilePreviewImpl implements FilePreview {
|
||||
this.fileHandlerService = fileHandlerService;
|
||||
this.otherFilePreview = otherFilePreview;
|
||||
}
|
||||
private final String fileDir = ConfigConstants.getFileDir();
|
||||
@Override
|
||||
public String filePreviewHandle(String url, Model model, FileAttribute fileAttribute) {
|
||||
String fileName = fileAttribute.getName();
|
||||
String baseUrl = BaseUrlFilter.getBaseUrl();
|
||||
String tifPreviewType = ConfigConstants.getTifPreviewType();
|
||||
String tifOnLinePreviewType = fileAttribute.getTifPreviewType();
|
||||
String suffix = fileAttribute.getSuffix();
|
||||
String cacheName = fileAttribute.getcacheName();
|
||||
String outFilePath = fileAttribute.getoutFilePath();
|
||||
String fileKey = fileAttribute.getFileKey(); //判断是否压缩包
|
||||
boolean forceUpdatedCache=fileAttribute.forceUpdatedCache();
|
||||
if (StringUtils.hasText(tifOnLinePreviewType)) {
|
||||
tifPreviewType = tifOnLinePreviewType;
|
||||
}
|
||||
if ("tif".equalsIgnoreCase(tifPreviewType)) {
|
||||
model.addAttribute("currentUrl", url);
|
||||
return TIFF_FILE_PREVIEW_PAGE;
|
||||
} else if ("jpg".equalsIgnoreCase(tifPreviewType) || "pdf".equalsIgnoreCase(tifPreviewType)) {
|
||||
String pdfName = fileName.substring(0, fileName.lastIndexOf(".")) + suffix +"." + "pdf" ; //生成文件添加类型后缀 防止同名文件
|
||||
String jpgName = fileName.substring(0, fileName.lastIndexOf(".")) + suffix; //生成文件添加类型后缀 防止同名文件
|
||||
String strLocalTif = fileDir + fileName;
|
||||
String outFilePath = fileDir + pdfName;
|
||||
if ("pdf".equalsIgnoreCase(tifPreviewType)) {
|
||||
//当文件不存在时,就去下载
|
||||
if (forceUpdatedCache || !fileHandlerService.listConvertedFiles().containsKey(pdfName) || !ConfigConstants.isCacheEnabled()) {
|
||||
ReturnResponse<String> response = DownloadUtils.downLoad(fileAttribute, fileName);
|
||||
if (response.isFailure()) {
|
||||
return otherFilePreview.notSupportedFile(model, fileAttribute, response.getMsg());
|
||||
}
|
||||
String filePath = response.getContent();
|
||||
if (ConvertPicUtil.convertJpg2Pdf(filePath, outFilePath)) {
|
||||
//是否保留TIFF源文件
|
||||
if (ConfigConstants.getDeleteSourceFile()) {
|
||||
KkFileUtils.deleteFileByPath(filePath);
|
||||
if ("jpg".equalsIgnoreCase(tifPreviewType) || "pdf".equalsIgnoreCase(tifPreviewType)) {
|
||||
if (forceUpdatedCache || !fileHandlerService.listConvertedFiles().containsKey(cacheName) || !ConfigConstants.isCacheEnabled()) {
|
||||
ReturnResponse<String> response = DownloadUtils.downLoad(fileAttribute, fileName);
|
||||
if (response.isFailure()) {
|
||||
return otherFilePreview.notSupportedFile(model, fileAttribute, response.getMsg());
|
||||
}
|
||||
String filePath = response.getContent();
|
||||
if ("pdf".equalsIgnoreCase(tifPreviewType)) {
|
||||
try {
|
||||
ConvertPicUtil.convertJpg2Pdf(filePath, outFilePath);
|
||||
} catch (Exception e) {
|
||||
if (e.getMessage().contains("Bad endianness tag (not 0x4949 or 0x4d4d)") ) {
|
||||
model.addAttribute("imgUrls", url);
|
||||
model.addAttribute("currentUrl", url);
|
||||
return PICTURE_FILE_PREVIEW_PAGE;
|
||||
}else {
|
||||
return otherFilePreview.notSupportedFile(model, fileAttribute, "TIF转pdf异常,请联系系统管理员!" );
|
||||
}
|
||||
if (ConfigConstants.isCacheEnabled()) {
|
||||
// 加入缓存
|
||||
fileHandlerService.addConvertedFile(pdfName, fileHandlerService.getRelativePath(outFilePath));
|
||||
}
|
||||
model.addAttribute("pdfUrl", pdfName);
|
||||
return PDF_FILE_PREVIEW_PAGE;
|
||||
} else {
|
||||
return NOT_SUPPORTED_FILE_PAGE;
|
||||
}
|
||||
} else {
|
||||
model.addAttribute("pdfUrl", pdfName);
|
||||
//是否保留TIFF源文件
|
||||
if (ObjectUtils.isEmpty(fileKey) && ConfigConstants.getDeleteSourceFile()) {
|
||||
// KkFileUtils.deleteFileByPath(filePath);
|
||||
}
|
||||
if (ConfigConstants.isCacheEnabled()) {
|
||||
// 加入缓存
|
||||
fileHandlerService.addConvertedFile(cacheName, fileHandlerService.getRelativePath(outFilePath));
|
||||
}
|
||||
model.addAttribute("pdfUrl", cacheName);
|
||||
return PDF_FILE_PREVIEW_PAGE;
|
||||
}else {
|
||||
// 将tif转换为jpg,返回转换后的文件路径、文件名的list
|
||||
List<String> listPic2Jpg;
|
||||
try {
|
||||
listPic2Jpg = ConvertPicUtil.convertTif2Jpg(filePath, outFilePath,forceUpdatedCache);
|
||||
} catch (Exception e) {
|
||||
if (e.getMessage().contains("Bad endianness tag (not 0x4949 or 0x4d4d)") ) {
|
||||
model.addAttribute("imgUrls", url);
|
||||
model.addAttribute("currentUrl", url);
|
||||
return PICTURE_FILE_PREVIEW_PAGE;
|
||||
}else {
|
||||
return otherFilePreview.notSupportedFile(model, fileAttribute, "TIF转JPG异常,请联系系统管理员!" );
|
||||
}
|
||||
}
|
||||
//是否保留源文件,转换失败保留源文件,转换成功删除源文件
|
||||
if(ObjectUtils.isEmpty(fileKey) && ConfigConstants.getDeleteSourceFile()) {
|
||||
KkFileUtils.deleteFileByPath(filePath);
|
||||
}
|
||||
if (ConfigConstants.isCacheEnabled()) {
|
||||
// 加入缓存
|
||||
fileHandlerService.putImgCache(cacheName, listPic2Jpg);
|
||||
fileHandlerService.addConvertedFile(cacheName, fileHandlerService.getRelativePath(outFilePath));
|
||||
}
|
||||
model.addAttribute("imgUrls", listPic2Jpg);
|
||||
model.addAttribute("currentUrl", listPic2Jpg.get(0));
|
||||
return PICTURE_FILE_PREVIEW_PAGE;
|
||||
}
|
||||
}
|
||||
if ("pdf".equalsIgnoreCase(tifPreviewType)) {
|
||||
model.addAttribute("pdfUrl", fileHandlerService.listConvertedFiles().get(cacheName));
|
||||
return PDF_FILE_PREVIEW_PAGE;
|
||||
}
|
||||
else if ("jpg".equalsIgnoreCase(tifPreviewType)) {
|
||||
model.addAttribute("imgUrls", fileHandlerService.getImgCache(cacheName));
|
||||
model.addAttribute("currentUrl", fileHandlerService.getImgCache(cacheName).get(0));
|
||||
return PICTURE_FILE_PREVIEW_PAGE;
|
||||
}
|
||||
}
|
||||
// 不是http开头,浏览器不能直接访问,需下载到本地
|
||||
if (url != null && !url.toLowerCase().startsWith("http")) {
|
||||
if (forceUpdatedCache || !fileHandlerService.listConvertedFiles().containsKey(fileName) || !ConfigConstants.isCacheEnabled()) {
|
||||
ReturnResponse<String> response = DownloadUtils.downLoad(fileAttribute, fileName);
|
||||
if (response.isFailure()) {
|
||||
return otherFilePreview.notSupportedFile(model, fileAttribute, response.getMsg());
|
||||
}
|
||||
model.addAttribute("currentUrl", fileHandlerService.getRelativePath(response.getContent()));
|
||||
if (ConfigConstants.isCacheEnabled()) {
|
||||
// 加入缓存
|
||||
fileHandlerService.addConvertedFile(fileName, fileHandlerService.getRelativePath(outFilePath));
|
||||
}
|
||||
} else {
|
||||
File fileTiff = new File(strLocalTif);
|
||||
// 如果本地不存在这个tif文件,则下载
|
||||
if (!fileTiff.exists()) {
|
||||
ReturnResponse<String> response = DownloadUtils.downLoad(fileAttribute, fileName);
|
||||
if (response.isFailure()) {
|
||||
return otherFilePreview.notSupportedFile(model, fileAttribute, response.getMsg());
|
||||
}
|
||||
strLocalTif = response.getContent();
|
||||
}
|
||||
// 将tif转换为jpg,返回转换后的文件路径、文件名的list
|
||||
List<String> listPic2Jpg = ConvertPicUtil.convertTif2Jpg(strLocalTif, jpgName);
|
||||
// 将返回页面的图片url的list对象
|
||||
List<String> listImageUrls = new ArrayList<>();
|
||||
// 循环,拼装url的list对象
|
||||
for (String strJpg : listPic2Jpg) {
|
||||
listImageUrls.add(baseUrl + strJpg);
|
||||
}
|
||||
model.addAttribute("imgUrls", listImageUrls);
|
||||
model.addAttribute("currentUrl", listImageUrls.get(0));
|
||||
model.addAttribute("currentUrl", fileName);
|
||||
}
|
||||
return PICTURE_FILE_PREVIEW_PAGE;
|
||||
return TIFF_FILE_PREVIEW_PAGE;
|
||||
}
|
||||
return NOT_SUPPORTED_FILE_PAGE;
|
||||
model.addAttribute("currentUrl", url);
|
||||
return TIFF_FILE_PREVIEW_PAGE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user