1.修复压缩包 二级目录无法解压问题 修改压缩包生成PDF路径

2.修复PDF 带密码缓存问题 新增PDF带密码缓存方法 userToken
3.精简OFFICE 转换代码
4.精简TIF转换代码 新增TIF转换图片缓存 修复tif错误文件不自动释放内存 等待其他修复
5.修复下载方法错 特殊符号下载错误
6.调整文件名 统一方法在FileHandlerService
7.新增判断文件名是否被URL转义
pull/248/head
gaoxiongzaq 2023-10-23 17:06:05 +08:00
parent c559efcceb
commit deb91728d4
15 changed files with 529 additions and 380 deletions

View File

@ -14,11 +14,16 @@ public class FileAttribute {
private String url; private String url;
private String fileKey; private String fileKey;
private String filePassword; private String filePassword;
private String userToken; private boolean userToken;
private String officePreviewType = ConfigConstants.getOfficePreviewType(); private String officePreviewType = ConfigConstants.getOfficePreviewType();
private String tifPreviewType; private String tifPreviewType;
private Boolean skipDownLoad = false; private Boolean skipDownLoad = false;
private Boolean forceUpdatedCache = false; private Boolean forceUpdatedCache = false;
private String cacheName;
private String outFilePath;
private String fileNameFilePath;
private String cacheListName;
private boolean isHtml;
/** /**
* *
@ -61,11 +66,11 @@ public class FileAttribute {
this.filePassword = filePassword; this.filePassword = filePassword;
} }
public String getUserToken() { public boolean getUserToken() {
return userToken; return userToken;
} }
public void setUserToken(String userToken) { public void setUserToken(boolean userToken) {
this.userToken = userToken; this.userToken = userToken;
} }
@ -96,7 +101,37 @@ public class FileAttribute {
public String getName() { public String getName() {
return name; return name;
} }
public String getcacheName() {
return cacheName;
}
public String getcacheListName() {
return cacheListName;
}
public String getoutFilePath() {
return outFilePath;
}
public String getfileNameFilePath() {
return fileNameFilePath;
}
public boolean getisHtml() {
return isHtml;
}
public void setcacheName(String cacheName) {
this.cacheName = cacheName;
}
public void setcacheListName(String cacheListName) {
this.cacheListName = cacheListName;
}
public void setoutFilePath(String outFilePath) {
this.outFilePath = outFilePath;
}
public void setfileNameFilePath(String fileNameFilePath) {
this.fileNameFilePath = fileNameFilePath;
}
public void setisHtml(boolean isHtml) {
this.isHtml = isHtml;
}
public void setName(String name) { public void setName(String name) {
this.name = name; this.name = name;
} }

View File

@ -1,5 +1,6 @@
package cn.keking.service; package cn.keking.service;
import cn.keking.config.ConfigConstants;
import cn.keking.model.FileType; import cn.keking.model.FileType;
import cn.keking.utils.RarUtils; import cn.keking.utils.RarUtils;
import cn.keking.web.filter.BaseUrlFilter; import cn.keking.web.filter.BaseUrlFilter;
@ -12,6 +13,7 @@ import net.sf.sevenzipjbinding.simple.ISimpleInArchive;
import net.sf.sevenzipjbinding.simple.ISimpleInArchiveItem; import net.sf.sevenzipjbinding.simple.ISimpleInArchiveItem;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import java.io.*; import java.io.*;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
@ -25,45 +27,49 @@ import java.util.List;
@Component @Component
public class CompressFileReader { public class CompressFileReader {
private final FileHandlerService fileHandlerService; private final FileHandlerService fileHandlerService;
private static final String fileDir = ConfigConstants.getFileDir();
public CompressFileReader(FileHandlerService fileHandlerService) { public CompressFileReader(FileHandlerService fileHandlerService) {
this.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<>(); List<String> imgUrls = new ArrayList<>();
String baseUrl = BaseUrlFilter.getBaseUrl(); String baseUrl = BaseUrlFilter.getBaseUrl();
String archiveFileName = fileHandlerService.getFileNameFromPath(paths); String folderName = filePath.replace(fileDir, ""); //修复压缩包 多重目录获取路径错误
if (!ObjectUtils.isEmpty(fileKey)) { //压缩包文件 直接赋予路径 不予下载
folderName = "_decompression"+folderName;
}
RandomAccessFile randomAccessFile = null; RandomAccessFile randomAccessFile = null;
IInArchive inArchive = null; IInArchive inArchive = null;
try { try {
randomAccessFile = new RandomAccessFile(paths, "r"); randomAccessFile = new RandomAccessFile(filePath, "r");
inArchive = SevenZip.openInArchive(null, new RandomAccessFileInStream(randomAccessFile)); 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(); ISimpleInArchive simpleInArchive = inArchive.getSimpleInterface();
final String[] str = {null}; final String[] str = {null};
for (final ISimpleInArchiveItem item : simpleInArchive.getArchiveItems()) { for (final ISimpleInArchiveItem item : simpleInArchive.getArchiveItems()) {
if (!item.isFolder()) { if (!item.isFolder()) {
ExtractOperationResult result; ExtractOperationResult result;
String finalFolderName = folderName;
result = item.extractSlow(data -> { result = item.extractSlow(data -> {
try { try {
str[0] = RarUtils.getUtf8String(item.getPath()); str[0] = RarUtils.getUtf8String(item.getPath());
if (RarUtils.isMessyCode(str[0])){ if (RarUtils.isMessyCode(str[0])){
str[0] = new String(item.getPath().getBytes(StandardCharsets.ISO_8859_1), "gbk"); str[0] = new String(item.getPath().getBytes(StandardCharsets.ISO_8859_1), "gbk");
} }
str[0] = str[0].replace("\\", File.separator); //Linux 下路径错误 str[0] = str[0].replace("\\", File.separator); //Linux 下路径错误
String str1 = str[0].substring(0, str[0].lastIndexOf(File.separator)+ 1); 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()) { if (!file.exists()) {
file.mkdirs(); 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); IOUtils.write(data, out);
out.close(); out.close();
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
return Integer.parseInt(null);
} }
return data.length; return data.length;
}, passWord); }, filePassword);
if (result == ExtractOperationResult.OK) { if (result == ExtractOperationResult.OK) {
FileType type = FileType.typeFromUrl(str[0]); FileType type = FileType.typeFromUrl(str[0]);
if (type.equals(FileType.PICTURE)) { if (type.equals(FileType.PICTURE)) {
@ -75,7 +81,7 @@ public class CompressFileReader {
} }
} }
} }
return archiveFileName + "_"; return folderName + "_";
} catch (Exception e) { } catch (Exception e) {
throw new Exception(e); throw new Exception(e);
} finally { } finally {

View File

@ -7,6 +7,7 @@ import cn.keking.service.cache.CacheService;
import cn.keking.service.cache.NotResourceCache; import cn.keking.service.cache.NotResourceCache;
import cn.keking.utils.EncodingDetects; import cn.keking.utils.EncodingDetects;
import cn.keking.utils.KkFileUtils; import cn.keking.utils.KkFileUtils;
import cn.keking.utils.UrlEncoderUtils;
import cn.keking.utils.WebUtils; import cn.keking.utils.WebUtils;
import cn.keking.web.filter.BaseUrlFilter; import cn.keking.web.filter.BaseUrlFilter;
import com.aspose.cad.*; import com.aspose.cad.*;
@ -36,6 +37,9 @@ import org.springframework.util.StringUtils;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.*; import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLDecoder;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.ArrayList; import java.util.ArrayList;
@ -195,11 +199,13 @@ public class FileHandlerService implements InitializingBean {
* @param index * @param index
* @return 访 * @return 访
*/ */
private String getPdf2jpgUrl(String pdfName, int index) { private String getPdf2jpgUrl(String pdfName, int index,String fileKey) {
String baseUrl = BaseUrlFilter.getBaseUrl(); String baseUrl = BaseUrlFilter.getBaseUrl();
if (!ObjectUtils.isEmpty(fileKey)) { // 是压缩包文件 改变PDF生成图片的路径
pdfName = "_decompression"+ pdfName;
}
String pdfFolder = pdfName.substring(0, pdfName.length() - 4); String pdfFolder = pdfName.substring(0, pdfName.length() - 4);
String urlPrefix; String urlPrefix;
try { try {
urlPrefix = baseUrl + URLEncoder.encode(pdfFolder, uriEncoding).replaceAll("\\+", "%20"); urlPrefix = baseUrl + URLEncoder.encode(pdfFolder, uriEncoding).replaceAll("\\+", "%20");
} catch (UnsupportedEncodingException e) { } catch (UnsupportedEncodingException e) {
@ -215,14 +221,14 @@ public class FileHandlerService implements InitializingBean {
* @param pdfName pdf * @param pdfName pdf
* @return 访 * @return 访
*/ */
private List<String> loadPdf2jpgCache(String pdfFilePath, String pdfName) { private List<String> loadPdf2jpgCache(String pdfFilePath, String pdfName, String fileKey) {
List<String> imageUrls = new ArrayList<>(); List<String> imageUrls = new ArrayList<>();
Integer imageCount = this.getPdf2jpgCache(pdfFilePath); Integer imageCount = this.getPdf2jpgCache(pdfFilePath);
if (Objects.isNull(imageCount)) { if (Objects.isNull(imageCount)) {
return imageUrls; return imageUrls;
} }
IntStream.range(0, imageCount).forEach(i -> { IntStream.range(0, imageCount).forEach(i -> {
String imageUrl = this.getPdf2jpgUrl(pdfName, i); String imageUrl = this.getPdf2jpgUrl(pdfName, i,fileKey);
imageUrls.add(imageUrl); imageUrls.add(imageUrl);
}); });
return imageUrls; return imageUrls;
@ -230,26 +236,28 @@ public class FileHandlerService implements InitializingBean {
/** /**
* pdfjpg * pdfjpg
* * fileNameFilePath pdf
* @param pdfFilePath pdf * pdfFilePath pdf
* @param pdfName pdf * pdfName pdf
* @return 访 * 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 forceUpdatedCache = fileAttribute.forceUpdatedCache();
boolean userToken = fileAttribute.getUserToken();
String filePassword = fileAttribute.getFilePassword(); String filePassword = fileAttribute.getFilePassword();
String fileKey = fileAttribute.getFileKey();
String pdfPassword = null; String pdfPassword = null;
PDDocument doc = null; PDDocument doc = null;
PdfReader pdfReader = null; PdfReader pdfReader = null;
if (!forceUpdatedCache) { if (!forceUpdatedCache) {
List<String> cacheResult = this.loadPdf2jpgCache(pdfFilePath, pdfName); List<String> cacheResult = this.loadPdf2jpgCache(pdfFilePath, pdfName,fileKey);
if (!CollectionUtils.isEmpty(cacheResult)) { if (!CollectionUtils.isEmpty(cacheResult)) {
return cacheResult; return cacheResult;
} }
} }
List<String> imageUrls = new ArrayList<>(); List<String> imageUrls = new ArrayList<>();
try { try {
File pdfFile = new File(pdfFilePath); File pdfFile = new File(fileNameFilePath);
if (!pdfFile.exists()) { if (!pdfFile.exists()) {
return null; return null;
} }
@ -268,36 +276,39 @@ public class FileHandlerService implements InitializingBean {
imageFilePath = folder + File.separator + pageIndex + PDF2JPG_IMAGE_FORMAT; imageFilePath = folder + File.separator + pageIndex + PDF2JPG_IMAGE_FORMAT;
BufferedImage image = pdfRenderer.renderImageWithDPI(pageIndex, ConfigConstants.getPdf2JpgDpi(), ImageType.RGB); BufferedImage image = pdfRenderer.renderImageWithDPI(pageIndex, ConfigConstants.getPdf2JpgDpi(), ImageType.RGB);
ImageIOUtil.writeImage(image, imageFilePath, ConfigConstants.getPdf2JpgDpi()); ImageIOUtil.writeImage(image, imageFilePath, ConfigConstants.getPdf2JpgDpi());
String imageUrl = this.getPdf2jpgUrl(pdfName, pageIndex); String imageUrl = this.getPdf2jpgUrl(pdfName, pageIndex,fileKey);
imageUrls.add(imageUrl); imageUrls.add(imageUrl);
} }
try { try {
if (ObjectUtils.isEmpty(filePassword)){ if (!ObjectUtils.isEmpty(filePassword)){ //获取到密码 判断是否是加密文件
pdfReader = new PdfReader(pdfFilePath); //读取PDF文件 pdfReader = new PdfReader(fileNameFilePath); //读取PDF文件 通过异常获取该文件是否有密码字符
}else {
pdfReader = new PdfReader(pdfFilePath,filePassword.getBytes()); //读取PDF文件
} }
} catch (Exception e) { //获取异常方法 判断是否有加密字符串 } catch (Exception e) { //获取异常方法 判断是否有加密字符串
Throwable[] throwableArray = ExceptionUtils.getThrowables(e); Throwable[] throwableArray = ExceptionUtils.getThrowables(e);
for (Throwable throwable : throwableArray) { for (Throwable throwable : throwableArray) {
if (throwable instanceof IOException || throwable instanceof EncryptedDocumentException) { if (throwable instanceof IOException || throwable instanceof EncryptedDocumentException) {
if (e.getMessage().toLowerCase().contains(PDF_PASSWORD_MSG)) { 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 { } finally {
if (pdfReader != null) { //关闭 if (pdfReader != null) { //关闭
pdfReader.close(); pdfReader.close();
} }
} }
//判断是否加密文件 加密文件不缓存
if (!PDF_PASSWORD_MSG.equals(pdfPassword)) { if (userToken || !PDF_PASSWORD_MSG.equals(pdfPassword)) { //加密文件 判断是否启用缓存命令
this.addPdf2jpgCache(pdfFilePath, pageCount); this.addPdf2jpgCache(pdfFilePath, pageCount);
} }
} catch (IOException e) { } 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); throw new Exception(e);
} finally { } finally {
if (doc != null) { //关闭 if (doc != null) { //关闭
@ -411,8 +422,14 @@ public class FileHandlerService implements InitializingBean {
FileAttribute attribute = new FileAttribute(); FileAttribute attribute = new FileAttribute();
String suffix; String suffix;
FileType type; FileType type;
String fileName; String fileName; //原始文件名
String cacheName; //缓存文件名
String cacheUnifyName; //缓存文件名统一去除文件后缀名
String cacheListName; //缓存列表文件名称
String outFilePath; //生成文件的路径
String fileNameFilePath; //原始文件路径
String fullFileName = WebUtils.getUrlParameterReg(url, "fullfilename"); String fullFileName = WebUtils.getUrlParameterReg(url, "fullfilename");
String fileKey = WebUtils.getUrlParameterReg(url, "kkCompressfileKey"); //压缩包指定特殊符号
if (StringUtils.hasText(fullFileName)) { if (StringUtils.hasText(fullFileName)) {
fileName = fullFileName; fileName = fullFileName;
type = FileType.typeFromFileName(fullFileName); type = FileType.typeFromFileName(fullFileName);
@ -428,23 +445,62 @@ public class FileHandlerService implements InitializingBean {
type = FileType.typeFromUrl(url); type = FileType.typeFromUrl(url);
suffix = WebUtils.suffixFromUrl(url); suffix = WebUtils.suffixFromUrl(url);
} }
if (url.contains("?fileKey=")) { if (!ObjectUtils.isEmpty(fileKey)) { //判断是否使用特定压缩包符号
String[] strs = url.split("="); //处理解压后有反代情况下 文件的路径 try {
String urlStrr = getSubString(url, strs[1]); URL urll = new URL(url);
urlStrr = urlStrr.substring(0,urlStrr.lastIndexOf("?")); fileName = urll.getPath(); //压缩包类型文件 获取解压后的绝对地址 不在执行重复下载方法
fileName = strs[1] + urlStrr.trim(); attribute.setSkipDownLoad(true);
attribute.setSkipDownLoad(true); } catch (MalformedURLException e) {
e.printStackTrace();
}
} }
url = WebUtils.encodeUrlFileName(url); 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); //文件名处理 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.setType(type);
attribute.setName(fileName); attribute.setName(fileName);
attribute.setcacheName(cacheName);
attribute.setcacheListName(cacheListName);
attribute.setisHtml(isHtml);
attribute.setoutFilePath(outFilePath);
attribute.setfileNameFilePath(fileNameFilePath);
attribute.setSuffix(suffix); attribute.setSuffix(suffix);
attribute.setUrl(url); attribute.setUrl(url);
if (req != null) { if (req != null) {
String officePreviewType = req.getParameter("officePreviewType"); String officePreviewType = req.getParameter("officePreviewType");
String forceUpdatedCache = req.getParameter("forceUpdatedCache"); String forceUpdatedCache = req.getParameter("forceUpdatedCache");
String fileKey = WebUtils.getUrlParameterReg(url, "fileKey"); String userToken =req.getParameter("userToken");
if (StringUtils.hasText(officePreviewType)) { if (StringUtils.hasText(officePreviewType)) {
attribute.setOfficePreviewType(officePreviewType); attribute.setOfficePreviewType(officePreviewType);
} }
@ -464,10 +520,8 @@ public class FileHandlerService implements InitializingBean {
if (StringUtils.hasText(filePassword)) { if (StringUtils.hasText(filePassword)) {
attribute.setFilePassword(filePassword); attribute.setFilePassword(filePassword);
} }
if ("true".equalsIgnoreCase(userToken)) {
String userToken = req.getParameter("userToken"); attribute.setUserToken(true);
if (StringUtils.hasText(userToken)) {
attribute.setUserToken(userToken);
} }
String kkProxyAuthorization = req.getHeader( "kk-proxy-authorization"); String kkProxyAuthorization = req.getHeader( "kk-proxy-authorization");
attribute.setKkProxyAuthorization(kkProxyAuthorization); attribute.setKkProxyAuthorization(kkProxyAuthorization);

View File

@ -10,6 +10,7 @@ import cn.keking.utils.KkFileUtils;
import cn.keking.web.filter.BaseUrlFilter; import cn.keking.web.filter.BaseUrlFilter;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.ui.Model; import org.springframework.ui.Model;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import static cn.keking.service.impl.OfficeFilePreviewImpl.getPreviewType; 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_IMAGE = "image";
private static final String OFFICE_PREVIEW_TYPE_ALL_IMAGES = "allImages"; private static final String OFFICE_PREVIEW_TYPE_ALL_IMAGES = "allImages";
private static final String FILE_DIR = ConfigConstants.getFileDir();
private final FileHandlerService fileHandlerService; private final FileHandlerService fileHandlerService;
private final OtherFilePreviewImpl otherFilePreview; private final OtherFilePreviewImpl otherFilePreview;
@ -40,18 +40,17 @@ public class CadFilePreviewImpl implements FilePreview {
String baseUrl = BaseUrlFilter.getBaseUrl(); String baseUrl = BaseUrlFilter.getBaseUrl();
boolean forceUpdatedCache=fileAttribute.forceUpdatedCache(); boolean forceUpdatedCache=fileAttribute.forceUpdatedCache();
String fileName = fileAttribute.getName(); String fileName = fileAttribute.getName();
String suffix = fileAttribute.getSuffix();
String cadPreviewType = ConfigConstants.getCadPreviewType(); String cadPreviewType = ConfigConstants.getCadPreviewType();
String pdfName = fileName.substring(0, fileName.lastIndexOf(".")) + suffix +"." + cadPreviewType ; //生成文件添加类型后缀 防止同名文件 String cacheName = fileAttribute.getcacheName();
String outFilePath = FILE_DIR + pdfName; String outFilePath = fileAttribute.getoutFilePath();
String fileKey = fileAttribute.getFileKey(); //判断是否压缩包
// 判断之前是否已转换过,如果转换过,直接返回,否则执行转换 // 判断之前是否已转换过,如果转换过,直接返回,否则执行转换
if (forceUpdatedCache || !fileHandlerService.listConvertedFiles().containsKey(pdfName) || !ConfigConstants.isCacheEnabled()) { if (forceUpdatedCache || !fileHandlerService.listConvertedFiles().containsKey(cacheName) || !ConfigConstants.isCacheEnabled()) {
String filePath; ReturnResponse<String> response = DownloadUtils.downLoad(fileAttribute, fileName);
ReturnResponse<String> response = DownloadUtils.downLoad(fileAttribute, null);
if (response.isFailure()) { if (response.isFailure()) {
return otherFilePreview.notSupportedFile(model, fileAttribute, response.getMsg()); return otherFilePreview.notSupportedFile(model, fileAttribute, response.getMsg());
} }
filePath = response.getContent(); String filePath = response.getContent();
String imageUrls = null; String imageUrls = null;
if (StringUtils.hasText(outFilePath)) { if (StringUtils.hasText(outFilePath)) {
try { try {
@ -63,26 +62,26 @@ public class CadFilePreviewImpl implements FilePreview {
return otherFilePreview.notSupportedFile(model, fileAttribute, "office转图片异常请联系管理员"); return otherFilePreview.notSupportedFile(model, fileAttribute, "office转图片异常请联系管理员");
} }
//是否保留CAD源文件 //是否保留CAD源文件
if( ConfigConstants.getDeleteSourceFile()) { if(ObjectUtils.isEmpty(fileKey) && ConfigConstants.getDeleteSourceFile()) {
KkFileUtils.deleteFileByPath(filePath); KkFileUtils.deleteFileByPath(filePath);
} }
if (ConfigConstants.isCacheEnabled()) { if (ConfigConstants.isCacheEnabled()) {
// 加入缓存 // 加入缓存
fileHandlerService.addConvertedFile(pdfName, fileHandlerService.getRelativePath(outFilePath)); fileHandlerService.addConvertedFile(cacheName, fileHandlerService.getRelativePath(outFilePath));
} }
} }
} }
if("tif".equalsIgnoreCase(cadPreviewType)){ if("tif".equalsIgnoreCase(cadPreviewType)){
model.addAttribute("currentUrl", pdfName); model.addAttribute("currentUrl", cacheName);
return TIFF_FILE_PREVIEW_PAGE; return TIFF_FILE_PREVIEW_PAGE;
}else if("svg".equalsIgnoreCase(cadPreviewType)){ }else if("svg".equalsIgnoreCase(cadPreviewType)){
model.addAttribute("currentUrl", pdfName); model.addAttribute("currentUrl", cacheName);
return SVG_FILE_PREVIEW_PAGE; return SVG_FILE_PREVIEW_PAGE;
} }
if (baseUrl != null && (OFFICE_PREVIEW_TYPE_IMAGE.equals(officePreviewType) || OFFICE_PREVIEW_TYPE_ALL_IMAGES.equals(officePreviewType))) { 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; return PDF_FILE_PREVIEW_PAGE;
} }
} }

View File

@ -39,6 +39,7 @@ public class CompressFilePreviewImpl implements FilePreview {
String fileName=fileAttribute.getName(); String fileName=fileAttribute.getName();
String filePassword = fileAttribute.getFilePassword(); String filePassword = fileAttribute.getFilePassword();
boolean forceUpdatedCache=fileAttribute.forceUpdatedCache(); boolean forceUpdatedCache=fileAttribute.forceUpdatedCache();
String fileKey = fileAttribute.getFileKey(); //判断是否压缩包
String fileTree = null; String fileTree = null;
// 判断文件名是否存在(redis缓存读取) // 判断文件名是否存在(redis缓存读取)
if (forceUpdatedCache || !StringUtils.hasText(fileHandlerService.getConvertedFile(fileName)) || !ConfigConstants.isCacheEnabled()) { if (forceUpdatedCache || !StringUtils.hasText(fileHandlerService.getConvertedFile(fileName)) || !ConfigConstants.isCacheEnabled()) {
@ -48,7 +49,7 @@ public class CompressFilePreviewImpl implements FilePreview {
} }
String filePath = response.getContent(); String filePath = response.getContent();
try { try {
fileTree = compressFileReader.unRar(filePath, filePassword,fileName); fileTree = compressFileReader.unRar(filePath, filePassword,fileName,fileKey);
} catch (Exception e) { } catch (Exception e) {
Throwable[] throwableArray = ExceptionUtils.getThrowables(e); Throwable[] throwableArray = ExceptionUtils.getThrowables(e);
for (Throwable throwable : throwableArray) { for (Throwable throwable : throwableArray) {
@ -62,7 +63,7 @@ public class CompressFilePreviewImpl implements FilePreview {
} }
if (!ObjectUtils.isEmpty(fileTree)) { if (!ObjectUtils.isEmpty(fileTree)) {
//是否保留压缩包源文件 //是否保留压缩包源文件
if (ConfigConstants.getDeleteSourceFile()) { if (ObjectUtils.isEmpty(fileKey) && ConfigConstants.getDeleteSourceFile()) {
KkFileUtils.deleteFileByPath(filePath); KkFileUtils.deleteFileByPath(filePath);
} }
if (ConfigConstants.isCacheEnabled()) { if (ConfigConstants.isCacheEnabled()) {

View File

@ -1,20 +1,18 @@
package cn.keking.service.impl; package cn.keking.service.impl;
import cn.keking.config.ConfigConstants; import cn.keking.config.ConfigConstants;
import cn.keking.model.FileAttribute; import cn.keking.model.FileAttribute;
import cn.keking.model.FileType; import cn.keking.model.FileType;
import cn.keking.model.ReturnResponse; 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.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.ffmpeg.global.avcodec;
import org.bytedeco.javacv.FFmpegFrameGrabber; import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.FFmpegFrameRecorder; import org.bytedeco.javacv.FFmpegFrameRecorder;
import org.bytedeco.javacv.Frame; import org.bytedeco.javacv.Frame;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.ui.Model; import org.springframework.ui.Model;
import java.io.File; import java.io.File;
/** /**
@ -28,139 +26,120 @@ public class MediaFilePreviewImpl implements FilePreview {
private final FileHandlerService fileHandlerService; private final FileHandlerService fileHandlerService;
private final OtherFilePreviewImpl otherFilePreview; private final OtherFilePreviewImpl otherFilePreview;
private static final String mp4 = "mp4";
private static Object LOCK=new Object();
public MediaFilePreviewImpl(FileHandlerService fileHandlerService, OtherFilePreviewImpl otherFilePreview) { public MediaFilePreviewImpl(FileHandlerService fileHandlerService, OtherFilePreviewImpl otherFilePreview) {
this.fileHandlerService = fileHandlerService; this.fileHandlerService = fileHandlerService;
this.otherFilePreview = otherFilePreview; this.otherFilePreview = otherFilePreview;
} }
@Override @Override
public String filePreviewHandle(String url, Model model, FileAttribute fileAttribute) { public String filePreviewHandle(String url, Model model, FileAttribute fileAttribute) {
// 不是http开头浏览器不能直接访问需下载到本地 String fileName = fileAttribute.getName();
if (url != null && !url.toLowerCase().startsWith("http")) { String suffix = fileAttribute.getSuffix();
ReturnResponse<String> response = DownloadUtils.downLoad(fileAttribute, fileAttribute.getName()); String cacheName = fileAttribute.getcacheName();
if (response.isFailure()) { String outFilePath = fileAttribute.getoutFilePath();
return otherFilePreview.notSupportedFile(model, fileAttribute, response.getMsg()); boolean forceUpdatedCache=fileAttribute.forceUpdatedCache();
} else { String[] mediaTypesConvert = FileType.MEDIA_TYPES_CONVERT; //获取支持的转换格式
url=BaseUrlFilter.getBaseUrl() + fileHandlerService.getRelativePath(response.getContent()); boolean mediaTypes = false;
fileAttribute.setUrl(url); for(String temp : mediaTypesConvert){
if (suffix.equals(temp)) {
mediaTypes = true;
break;
} }
} }
if(!url.toLowerCase().startsWith("http") || checkNeedConvert(mediaTypes)){ //不是http协议的 // 开启转换方式并是支持转换格式的
if(checkNeedConvert(fileAttribute.getSuffix())){ if (forceUpdatedCache || !fileHandlerService.listConvertedFiles().containsKey(cacheName) || !ConfigConstants.isCacheEnabled()) { //查询是否开启缓存
url=convertUrl(fileAttribute); ReturnResponse<String> response = DownloadUtils.downLoad(fileAttribute, fileName);
}else{ if (response.isFailure()) {
//正常media类型 return otherFilePreview.notSupportedFile(model, fileAttribute, response.getMsg());
String[] medias = ConfigConstants.getMedia();
for(String media:medias){
if(media.equals(fileAttribute.getSuffix())){
model.addAttribute("mediaUrl", url);
return MEDIA_FILE_PREVIEW_PAGE;
} }
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); model.addAttribute("mediaUrl", url);
return MEDIA_FILE_PREVIEW_PAGE; 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 * @return
*/ */
private boolean checkNeedConvert(String suffix) { private boolean checkNeedConvert(boolean mediaTypes) {
//1.检查开关是否开启 //1.检查开关是否开启
if("false".equals(ConfigConstants.getMediaConvertDisable())){ if("true".equals(ConfigConstants.getMediaConvertDisable())){
return false; return mediaTypes;
}
//2.检查当前文件是否需要转换
String[] mediaTypesConvert = FileType.MEDIA_TYPES_CONVERT;
String type = suffix;
for(String temp : mediaTypesConvert){
if(type.equals(temp)){
return true;
}
} }
return false; return false;
} }
private static String convertToMp4(String filePath,String outFilePath)throws Exception {
/** FFmpegFrameGrabber frameGrabber = FFmpegFrameGrabber.createDefault(filePath);
* MP4 Frame captured_frame;
* @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;
FFmpegFrameRecorder recorder = null; FFmpegFrameRecorder recorder = null;
try { try {
fileName = file.getAbsolutePath().replace(fileAttribute.getSuffix(),"mp4"); File desFile=new File(outFilePath);
File desFile=new File(fileName); //判断一下防止重复转换
//判断一下防止穿透缓存
if(desFile.exists()){ if(desFile.exists()){
return fileName; return outFilePath;
} }
frameGrabber.start(); frameGrabber.start();
recorder = new FFmpegFrameRecorder(fileName, frameGrabber.getImageWidth(), frameGrabber.getImageHeight(), frameGrabber.getAudioChannels()); recorder = new FFmpegFrameRecorder(outFilePath, frameGrabber.getImageWidth(), frameGrabber.getImageHeight(), frameGrabber.getAudioChannels());
recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264); //avcodec.AV_CODEC_ID_H264  //AV_CODEC_ID_MPEG4 // recorder.setImageHeight(640);
recorder.setFormat("mp4"); // recorder.setImageWidth(480);
recorder.setFormat(mp4);
recorder.setFrameRate(frameGrabber.getFrameRate()); recorder.setFrameRate(frameGrabber.getFrameRate());
//recorder.setSampleFormat(frameGrabber.getSampleFormat()); //
recorder.setSampleRate(frameGrabber.getSampleRate()); 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.setAudioChannels(frameGrabber.getAudioChannels());
recorder.setFrameRate(frameGrabber.getFrameRate());
recorder.start(); recorder.start();
while ((captured_frame = frameGrabber.grabFrame()) != null) { while (true) {
try { captured_frame = frameGrabber.grabFrame();
recorder.setTimestamp(frameGrabber.getTimestamp()); if (captured_frame == null) {
recorder.record(captured_frame); System.out.println("转码完成:"+filePath);
} catch (Exception e) { break;
} }
recorder.record(captured_frame);
} }
recorder.stop();
recorder.release();
frameGrabber.stop();
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
return null;
}finally {
if (recorder != null) { //关闭
recorder.stop();
recorder.close();
}
frameGrabber.stop();
frameGrabber.close();
} }
//是否删除源文件 return outFilePath;
//file.delete();
return convertFileName;
} }
} }

View File

@ -15,10 +15,10 @@ import org.apache.poi.EncryptedDocumentException;
import org.jodconverter.core.office.OfficeException; import org.jodconverter.core.office.OfficeException;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.ui.Model; import org.springframework.ui.Model;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import java.io.IOException; import java.io.IOException;
import java.net.URLEncoder;
import java.util.List; 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_IMAGE = "image";
public static final String OFFICE_PREVIEW_TYPE_ALL_IMAGES = "allImages"; 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 static final String OFFICE_PASSWORD_MSG = "password";
private final FileHandlerService fileHandlerService; private final FileHandlerService fileHandlerService;
@ -47,16 +46,16 @@ public class OfficeFilePreviewImpl implements FilePreview {
public String filePreviewHandle(String url, Model model, FileAttribute fileAttribute) { public String filePreviewHandle(String url, Model model, FileAttribute fileAttribute) {
// 预览Type参数传了就取参数的没传取系统默认 // 预览Type参数传了就取参数的没传取系统默认
String officePreviewType = fileAttribute.getOfficePreviewType(); String officePreviewType = fileAttribute.getOfficePreviewType();
boolean userToken = fileAttribute.getUserToken();
String baseUrl = BaseUrlFilter.getBaseUrl(); String baseUrl = BaseUrlFilter.getBaseUrl();
String suffix = fileAttribute.getSuffix(); String suffix = fileAttribute.getSuffix(); //获取文件后缀
String fileName = fileAttribute.getName(); String fileName = fileAttribute.getName(); //获取文件原始名称
String filePassword = fileAttribute.getFilePassword(); String filePassword = fileAttribute.getFilePassword(); //获取密码
boolean forceUpdatedCache=fileAttribute.forceUpdatedCache(); boolean forceUpdatedCache=fileAttribute.forceUpdatedCache(); //是否启用强制更新命令
String userToken = fileAttribute.getUserToken(); boolean isHtml =fileAttribute.getisHtml(); //xlsx 转换成html
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 cacheName = fileAttribute.getcacheName(); //转换后的文件名
String pdfName = fileName.substring(0, fileName.lastIndexOf(".") ) + suffix +"." +(isHtml ? "html" : "pdf"); //生成文件添加类型后缀 防止同名文件 String outFilePath = fileAttribute.getoutFilePath(); //转换后生成文件的路径
String cacheFileName = userToken == null ? pdfName : userToken + "_" + pdfName; String fileKey = fileAttribute.getFileKey(); //判断是否压缩包
String outFilePath = FILE_DIR + cacheFileName;
if (!officePreviewType.equalsIgnoreCase("html")) { if (!officePreviewType.equalsIgnoreCase("html")) {
if (ConfigConstants.getOfficeTypeWeb() .equalsIgnoreCase("web")) { if (ConfigConstants.getOfficeTypeWeb() .equalsIgnoreCase("web")) {
if (suffix.equalsIgnoreCase("xlsx")) { 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); ReturnResponse<String> response = DownloadUtils.downLoad(fileAttribute, fileName);
if (response.isFailure()) { if (response.isFailure()) {
return otherFilePreview.notSupportedFile(model, fileAttribute, response.getMsg()); return otherFilePreview.notSupportedFile(model, fileAttribute, response.getMsg());
} }
String filePath = response.getContent(); String filePath = response.getContent();
/* boolean isPwdProtectedOffice = OfficeUtils.isPwdProtected(filePath); // 判断是否加密文件
* 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) {
// 没有缓存执行转换逻辑
if (isPwdProtectedOffice && !StringUtils.hasLength(filePassword)) { if (isPwdProtectedOffice && !StringUtils.hasLength(filePassword)) {
// 加密文件需要密码 // 加密文件需要密码
model.addAttribute("needFilePassword", true); model.addAttribute("needFilePassword", true);
@ -118,40 +91,37 @@ public class OfficeFilePreviewImpl implements FilePreview {
model.addAttribute("filePasswordError", true); model.addAttribute("filePasswordError", true);
return EXEL_FILE_PREVIEW_PAGE; return EXEL_FILE_PREVIEW_PAGE;
} }
return otherFilePreview.notSupportedFile(model, fileAttribute, "抱歉,该文件版本不兼容,文件版本错误。"); return otherFilePreview.notSupportedFile(model, fileAttribute, "抱歉,该文件版本不兼容,文件版本错误。");
} }
if (isHtml) { if (isHtml) {
// 对转换后的文件进行操作(改变编码方式) // 对转换后的文件进行操作(改变编码方式)
fileHandlerService.doActionConvertedFile(outFilePath); fileHandlerService.doActionConvertedFile(outFilePath);
} }
//是否保留OFFICE源文件 //是否保留OFFICE源文件
if (ConfigConstants.getDeleteSourceFile()) { if (ObjectUtils.isEmpty(fileKey) && ConfigConstants.getDeleteSourceFile()) {
KkFileUtils.deleteFileByPath(filePath); 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))) { 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", cacheName);
model.addAttribute("pdfUrl", cacheFileName);
return isHtml ? EXEL_FILE_PREVIEW_PAGE : PDF_FILE_PREVIEW_PAGE; 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(); String suffix = fileAttribute.getSuffix();
boolean isPPT = suffix.equalsIgnoreCase("ppt") || suffix.equalsIgnoreCase("pptx"); boolean isPPT = suffix.equalsIgnoreCase("ppt") || suffix.equalsIgnoreCase("pptx");
List<String> imageUrls = null; List<String> imageUrls = null;
try { try {
imageUrls = fileHandlerService.pdf2jpg(outFilePath, pdfName, fileAttribute); imageUrls = fileHandlerService.pdf2jpg(outFilePath,outFilePath, pdfName, fileAttribute);
} catch (Exception e) { } catch (Exception e) {
Throwable[] throwableArray = ExceptionUtils.getThrowables(e); Throwable[] throwableArray = ExceptionUtils.getThrowables(e);
for (Throwable throwable : throwableArray) { for (Throwable throwable : throwableArray) {

View File

@ -24,37 +24,34 @@ public class PdfFilePreviewImpl implements FilePreview {
private final FileHandlerService fileHandlerService; private final FileHandlerService fileHandlerService;
private final OtherFilePreviewImpl otherFilePreview; private final OtherFilePreviewImpl otherFilePreview;
private static final String FILE_DIR = ConfigConstants.getFileDir();
private static final String PDF_PASSWORD_MSG = "password"; private static final String PDF_PASSWORD_MSG = "password";
public PdfFilePreviewImpl(FileHandlerService fileHandlerService, OtherFilePreviewImpl otherFilePreview) { public PdfFilePreviewImpl(FileHandlerService fileHandlerService, OtherFilePreviewImpl otherFilePreview) {
this.fileHandlerService = fileHandlerService; this.fileHandlerService = fileHandlerService;
this.otherFilePreview = otherFilePreview; this.otherFilePreview = otherFilePreview;
} }
@Override @Override
public String filePreviewHandle(String url, Model model, FileAttribute fileAttribute) { public String filePreviewHandle(String url, Model model, FileAttribute fileAttribute) {
String fileName = fileAttribute.getName(); String pdfName = fileAttribute.getName(); //获取原始文件名
String officePreviewType = fileAttribute.getOfficePreviewType(); String officePreviewType = fileAttribute.getOfficePreviewType(); //转换类型
boolean forceUpdatedCache=fileAttribute.forceUpdatedCache(); boolean forceUpdatedCache=fileAttribute.forceUpdatedCache(); //是否启用强制更新命令
String pdfName = fileName.substring(0, fileName.lastIndexOf(".") + 1) + "pdf"; String outFilePath = fileAttribute.getoutFilePath(); //生成的文件路径
String outFilePath = FILE_DIR + pdfName; String fileNameFilePath = fileAttribute.getfileNameFilePath(); //原始文件路径
if (OfficeFilePreviewImpl.OFFICE_PREVIEW_TYPE_IMAGE.equals(officePreviewType) || OfficeFilePreviewImpl.OFFICE_PREVIEW_TYPE_ALL_IMAGES.equals(officePreviewType)) { if (OfficeFilePreviewImpl.OFFICE_PREVIEW_TYPE_IMAGE.equals(officePreviewType) || OfficeFilePreviewImpl.OFFICE_PREVIEW_TYPE_ALL_IMAGES.equals(officePreviewType)) {
//当文件不存在时,就去下载 //当文件不存在时,就去下载
if (forceUpdatedCache || !fileHandlerService.listConvertedFiles().containsKey(pdfName) || !ConfigConstants.isCacheEnabled()) { 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()) { if (response.isFailure()) {
return otherFilePreview.notSupportedFile(model, fileAttribute, response.getMsg()); return otherFilePreview.notSupportedFile(model, fileAttribute, response.getMsg());
} }
outFilePath = response.getContent(); fileNameFilePath = response.getContent();
if (ConfigConstants.isCacheEnabled()) { if (ConfigConstants.isCacheEnabled()) {
// 加入缓存 // 加入缓存
fileHandlerService.addConvertedFile(pdfName, fileHandlerService.getRelativePath(outFilePath)); fileHandlerService.addConvertedFile(pdfName, fileHandlerService.getRelativePath(fileNameFilePath));
} }
} }
List<String> imageUrls; List<String> imageUrls;
try { try {
imageUrls = fileHandlerService.pdf2jpg(outFilePath, pdfName, fileAttribute); imageUrls = fileHandlerService.pdf2jpg(fileNameFilePath,outFilePath, pdfName, fileAttribute);
} catch (Exception e) { } catch (Exception e) {
Throwable[] throwableArray = ExceptionUtils.getThrowables(e); Throwable[] throwableArray = ExceptionUtils.getThrowables(e);
for (Throwable throwable : throwableArray) { for (Throwable throwable : throwableArray) {
@ -91,7 +88,6 @@ public class PdfFilePreviewImpl implements FilePreview {
fileHandlerService.addConvertedFile(pdfName, fileHandlerService.getRelativePath(outFilePath)); fileHandlerService.addConvertedFile(pdfName, fileHandlerService.getRelativePath(outFilePath));
} }
} else { } else {
pdfName = URLEncoder.encode(pdfName).replaceAll("\\+", "%20");
model.addAttribute("pdfUrl", pdfName); model.addAttribute("pdfUrl", pdfName);
} }
} else { } else {

View File

@ -1,10 +1,7 @@
package cn.keking.service.impl; package cn.keking.service.impl;
import cn.keking.model.FileAttribute; import cn.keking.model.FileAttribute;
import cn.keking.model.ReturnResponse;
import cn.keking.service.FileHandlerService; import cn.keking.service.FileHandlerService;
import cn.keking.service.FilePreview;
import cn.keking.utils.DownloadUtils;
import cn.keking.utils.KkFileUtils; import cn.keking.utils.KkFileUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.ui.Model; import org.springframework.ui.Model;
@ -21,12 +18,10 @@ import java.util.List;
public class PictureFilePreviewImpl extends CommonPreviewImpl { public class PictureFilePreviewImpl extends CommonPreviewImpl {
private final FileHandlerService fileHandlerService; private final FileHandlerService fileHandlerService;
private final OtherFilePreviewImpl otherFilePreview;
public PictureFilePreviewImpl(FileHandlerService fileHandlerService, OtherFilePreviewImpl otherFilePreview) { public PictureFilePreviewImpl(FileHandlerService fileHandlerService, OtherFilePreviewImpl otherFilePreview) {
super(fileHandlerService, otherFilePreview); super(fileHandlerService, otherFilePreview);
this.fileHandlerService = fileHandlerService; this.fileHandlerService = fileHandlerService;
this.otherFilePreview = otherFilePreview;
} }
@Override @Override

View File

@ -30,12 +30,12 @@ public class SimTextFilePreviewImpl implements FilePreview {
this.fileHandlerService = fileHandlerService; this.fileHandlerService = fileHandlerService;
this.otherFilePreview = otherFilePreview; this.otherFilePreview = otherFilePreview;
} }
private static final String FILE_DIR = ConfigConstants.getFileDir();
@Override @Override
public String filePreviewHandle(String url, Model model, FileAttribute fileAttribute) { public String filePreviewHandle(String url, Model model, FileAttribute fileAttribute) {
String fileName = fileAttribute.getName(); String fileName = fileAttribute.getName();
boolean forceUpdatedCache=fileAttribute.forceUpdatedCache(); boolean forceUpdatedCache=fileAttribute.forceUpdatedCache();
String filePath = FILE_DIR + fileName; String filePath = fileAttribute.getfileNameFilePath();
if (forceUpdatedCache || !fileHandlerService.listConvertedFiles().containsKey(fileName) || !ConfigConstants.isCacheEnabled()) { if (forceUpdatedCache || !fileHandlerService.listConvertedFiles().containsKey(fileName) || !ConfigConstants.isCacheEnabled()) {
ReturnResponse<String> response = DownloadUtils.downLoad(fileAttribute, fileName); ReturnResponse<String> response = DownloadUtils.downLoad(fileAttribute, fileName);
if (response.isFailure()) { if (response.isFailure()) {

View File

@ -8,13 +8,11 @@ import cn.keking.service.FilePreview;
import cn.keking.utils.ConvertPicUtil; import cn.keking.utils.ConvertPicUtil;
import cn.keking.utils.DownloadUtils; import cn.keking.utils.DownloadUtils;
import cn.keking.utils.KkFileUtils; import cn.keking.utils.KkFileUtils;
import cn.keking.web.filter.BaseUrlFilter;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.ui.Model; import org.springframework.ui.Model;
import org.springframework.util.StringUtils; import org.springframework.util.ObjectUtils;
import java.io.File; import java.io.IOException;
import java.util.ArrayList;
import java.util.List; import java.util.List;
/** /**
@ -32,75 +30,100 @@ public class TiffFilePreviewImpl implements FilePreview {
this.fileHandlerService = fileHandlerService; this.fileHandlerService = fileHandlerService;
this.otherFilePreview = otherFilePreview; this.otherFilePreview = otherFilePreview;
} }
private final String fileDir = ConfigConstants.getFileDir();
@Override @Override
public String filePreviewHandle(String url, Model model, FileAttribute fileAttribute) { public String filePreviewHandle(String url, Model model, FileAttribute fileAttribute) {
String fileName = fileAttribute.getName(); String fileName = fileAttribute.getName();
String baseUrl = BaseUrlFilter.getBaseUrl();
String tifPreviewType = ConfigConstants.getTifPreviewType(); String tifPreviewType = ConfigConstants.getTifPreviewType();
String tifOnLinePreviewType = fileAttribute.getTifPreviewType(); String cacheName = fileAttribute.getcacheName();
String suffix = fileAttribute.getSuffix(); String outFilePath = fileAttribute.getoutFilePath();
String fileKey = fileAttribute.getFileKey(); //判断是否压缩包
boolean forceUpdatedCache=fileAttribute.forceUpdatedCache(); boolean forceUpdatedCache=fileAttribute.forceUpdatedCache();
if (StringUtils.hasText(tifOnLinePreviewType)) { if ("jpg".equalsIgnoreCase(tifPreviewType) || "pdf".equalsIgnoreCase(tifPreviewType)) {
tifPreviewType = tifOnLinePreviewType; if (forceUpdatedCache || !fileHandlerService.listConvertedFiles().containsKey(cacheName) || !ConfigConstants.isCacheEnabled()) {
} ReturnResponse<String> response = DownloadUtils.downLoad(fileAttribute, fileName);
if ("tif".equalsIgnoreCase(tifPreviewType)) { if (response.isFailure()) {
model.addAttribute("currentUrl", url); return otherFilePreview.notSupportedFile(model, fileAttribute, response.getMsg());
return TIFF_FILE_PREVIEW_PAGE; }
} else if ("jpg".equalsIgnoreCase(tifPreviewType) || "pdf".equalsIgnoreCase(tifPreviewType)) { String filePath = response.getContent();
String pdfName = fileName.substring(0, fileName.lastIndexOf(".")) + suffix +"." + "pdf" ; //生成文件添加类型后缀 防止同名文件 if ("pdf".equalsIgnoreCase(tifPreviewType)) {
String jpgName = fileName.substring(0, fileName.lastIndexOf(".")) + suffix; //生成文件添加类型后缀 防止同名文件 try {
String strLocalTif = fileDir + fileName; ConvertPicUtil.convertJpg2Pdf(filePath, outFilePath);
String outFilePath = fileDir + pdfName; } catch (Exception e) {
if ("pdf".equalsIgnoreCase(tifPreviewType)) { if (e.getMessage().contains("Bad endianness tag (not 0x4949 or 0x4d4d)") ) {
//当文件不存在时,就去下载 model.addAttribute("imgUrls", url);
if (forceUpdatedCache || !fileHandlerService.listConvertedFiles().containsKey(pdfName) || !ConfigConstants.isCacheEnabled()) { model.addAttribute("currentUrl", url);
ReturnResponse<String> response = DownloadUtils.downLoad(fileAttribute, fileName); return PICTURE_FILE_PREVIEW_PAGE;
if (response.isFailure()) { }else {
return otherFilePreview.notSupportedFile(model, fileAttribute, response.getMsg()); return otherFilePreview.notSupportedFile(model, fileAttribute, "TIF转pdf异常请联系系统管理员!" );
}
String filePath = response.getContent();
if (ConvertPicUtil.convertJpg2Pdf(filePath, outFilePath)) {
//是否保留TIFF源文件
if (ConfigConstants.getDeleteSourceFile()) {
KkFileUtils.deleteFileByPath(filePath);
} }
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 { //是否保留TIFF源文件
model.addAttribute("pdfUrl", pdfName); 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; 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 { } else {
File fileTiff = new File(strLocalTif); model.addAttribute("currentUrl", fileName);
// 如果本地不存在这个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));
} }
return PICTURE_FILE_PREVIEW_PAGE; return TIFF_FILE_PREVIEW_PAGE;
} }
return NOT_SUPPORTED_FILE_PAGE; model.addAttribute("currentUrl", url);
return TIFF_FILE_PREVIEW_PAGE;
} }
} }

View File

@ -1,26 +1,26 @@
package cn.keking.utils; package cn.keking.utils;
import cn.keking.config.ConfigConstants; import cn.keking.config.ConfigConstants;
import cn.keking.web.filter.BaseUrlFilter;
import com.sun.media.jai.codec.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.itextpdf.text.Document; import com.itextpdf.text.Document;
import com.itextpdf.text.Image; import com.itextpdf.text.Image;
import com.itextpdf.text.io.FileChannelRandomAccessSource; import com.itextpdf.text.io.FileChannelRandomAccessSource;
import com.itextpdf.text.pdf.PdfWriter; import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.text.pdf.RandomAccessFileOrArray; import com.itextpdf.text.pdf.RandomAccessFileOrArray;
import com.itextpdf.text.pdf.codec.TiffImage; import com.itextpdf.text.pdf.codec.TiffImage;
import com.sun.media.jai.codec.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.media.jai.JAI; import javax.media.jai.JAI;
import javax.media.jai.RenderedOp; import javax.media.jai.RenderedOp;
import java.awt.image.RenderedImage; import java.awt.image.RenderedImage;
import java.awt.image.renderable.ParameterBlock; import java.awt.image.renderable.ParameterBlock;
import java.io.File; import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.RandomAccessFile; import java.io.RandomAccessFile;
import java.nio.file.Files; import java.nio.channels.FileChannel;
import java.nio.file.Paths;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -28,7 +28,6 @@ public class ConvertPicUtil {
private static final int FIT_WIDTH = 500; private static final int FIT_WIDTH = 500;
private static final int FIT_HEIGHT = 900; private static final int FIT_HEIGHT = 900;
private final static Logger logger = LoggerFactory.getLogger(ConvertPicUtil.class); private final static Logger logger = LoggerFactory.getLogger(ConvertPicUtil.class);
private final static String fileDir = ConfigConstants.getFileDir(); private final static String fileDir = ConfigConstants.getFileDir();
/** /**
@ -38,17 +37,14 @@ public class ConvertPicUtil {
* @param strOutputFile * @param strOutputFile
* @return boolean * @return boolean
*/ */
public static List<String> convertTif2Jpg(String strInputFile, String strOutputFile) { public static List<String> convertTif2Jpg(String strInputFile, String strOutputFile, boolean forceUpdatedCache) throws Exception {
List<String> listImageFiles = new ArrayList<>(); List<String> listImageFiles = new ArrayList<>();
String baseUrl = BaseUrlFilter.getBaseUrl();
if (strInputFile == null || "".equals(strInputFile.trim())) {
return null;
}
if (!new File(strInputFile).exists()) { if (!new File(strInputFile).exists()) {
logger.info("找不到文件【" + strInputFile + "】"); logger.info("找不到文件【" + strInputFile + "】");
return null; return null;
} }
strInputFile = strInputFile.replaceAll("\\\\", "/"); strOutputFile = strOutputFile.replaceAll(".jpg", "");
FileSeekableStream fileSeekStream = null; FileSeekableStream fileSeekStream = null;
try { try {
JPEGEncodeParam jpegEncodeParam = new JPEGEncodeParam(); JPEGEncodeParam jpegEncodeParam = new JPEGEncodeParam();
@ -58,20 +54,18 @@ public class ConvertPicUtil {
fileSeekStream = new FileSeekableStream(strInputFile); fileSeekStream = new FileSeekableStream(strInputFile);
ImageDecoder imageDecoder = ImageCodec.createImageDecoder("TIFF", fileSeekStream, null); ImageDecoder imageDecoder = ImageCodec.createImageDecoder("TIFF", fileSeekStream, null);
int intTifCount = imageDecoder.getNumPages(); int intTifCount = imageDecoder.getNumPages();
logger.info("该tif文件共有【" + intTifCount + "】页"); // logger.info("该tif文件共有【" + intTifCount + "】页");
String strJpgPath = fileDir+strOutputFile;
// 处理目标文件夹,如果不存在则自动创建 // 处理目标文件夹,如果不存在则自动创建
File fileJpgPath = new File(strJpgPath); File fileJpgPath = new File(strOutputFile);
if (!fileJpgPath.exists() && !fileJpgPath.mkdirs()) { if (!fileJpgPath.exists() && !fileJpgPath.mkdirs()) {
logger.error("{} 创建失败", strJpgPath); logger.error("{} 创建失败", strOutputFile);
} }
// 循环处理每页tif文件转换为jpg // 循环处理每页tif文件转换为jpg
for (int i = 0; i < intTifCount; i++) { for (int i = 0; i < intTifCount; i++) {
String strJpg= strJpgPath + "/" + i + ".jpg"; String strJpg= strOutputFile + "/" + i + ".jpg";
String strJpgUrl = strOutputFile + "/" + i + ".jpg";
File fileJpg = new File(strJpg); File fileJpg = new File(strJpg);
// 如果文件不存在,则生成 // 如果文件不存在,则生成
if (!fileJpg.exists()) { if (forceUpdatedCache|| !fileJpg.exists()) {
RenderedImage renderedImage = imageDecoder.decodeAsRenderedImage(i); RenderedImage renderedImage = imageDecoder.decodeAsRenderedImage(i);
ParameterBlock pb = new ParameterBlock(); ParameterBlock pb = new ParameterBlock();
pb.addSource(renderedImage); pb.addSource(renderedImage);
@ -80,24 +74,22 @@ public class ConvertPicUtil {
pb.add(jpegEncodeParam); pb.add(jpegEncodeParam);
RenderedOp renderedOp = JAI.create("filestore", pb); RenderedOp renderedOp = JAI.create("filestore", pb);
renderedOp.dispose(); renderedOp.dispose();
logger.info("每页分别保存至: " + fileJpg.getCanonicalPath()); // logger.info("每页分别保存至: " + fileJpg.getCanonicalPath());
} }
listImageFiles.add(strJpgUrl); strJpg = baseUrl+strJpg.replace(fileDir, "");
listImageFiles.add(strJpg);
} }
return listImageFiles;
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); if (!e.getMessage().contains("Bad endianness tag (not 0x4949 or 0x4d4d)") ) {
return null; logger.error("TIF转JPG异常文件路径" + strInputFile, e);
}
throw new Exception(e);
} finally { } finally {
if (fileSeekStream != null) { if (fileSeekStream != null) {
try { fileSeekStream.close();
fileSeekStream.close();
} catch (IOException e) {
logger.error(e.getMessage(), e);
}
} }
} }
return listImageFiles;
} }
/** /**
@ -106,44 +98,41 @@ public class ConvertPicUtil {
* @param strJpgFile jpg * @param strJpgFile jpg
* @param strPdfFile pdf * @param strPdfFile pdf
*/ */
public static boolean convertJpg2Pdf(String strJpgFile, String strPdfFile) { public static String convertJpg2Pdf(String strJpgFile, String strPdfFile) throws Exception {
Document document = null; Document document = new Document();
RandomAccessFileOrArray rafa = null; RandomAccessFileOrArray rafa = null;
FileOutputStream outputStream = null;
try { try {
document = new Document(); RandomAccessFile aFile = new RandomAccessFile(strJpgFile, "r");
PdfWriter.getInstance(document, Files.newOutputStream(Paths.get(strPdfFile))); FileChannel inChannel = aFile.getChannel();
document.open(); FileChannelRandomAccessSource fcra = new FileChannelRandomAccessSource(inChannel);
rafa = new RandomAccessFileOrArray(new FileChannelRandomAccessSource(new RandomAccessFile(strJpgFile, "r").getChannel())); rafa = new RandomAccessFileOrArray(fcra);
int pages = TiffImage.getNumberOfPages(rafa); int pages = TiffImage.getNumberOfPages(rafa);
outputStream = new FileOutputStream(strPdfFile);
PdfWriter.getInstance(document, outputStream);
document.open();
Image image; Image image;
for (int i = 1; i <= pages; i++) { for (int i = 1; i <= pages; i++) {
try { image = TiffImage.getTiffImage(rafa, i);
image = TiffImage.getTiffImage(rafa, i); image.scaleToFit(FIT_WIDTH, FIT_HEIGHT);
image.scaleToFit(FIT_WIDTH, FIT_HEIGHT); document.add(image);
document.add(image);
} catch (Exception e) {
document.close();
rafa.close();
e.printStackTrace();
}
} }
document.close(); } catch (IOException e) {
rafa.close(); if (!e.getMessage().contains("Bad endianness tag (not 0x4949 or 0x4d4d)") ) {
return true; logger.error("TIF转JPG异常文件路径" + strPdfFile, e);
} catch (Exception e) { }
logger.error("图片转PDF异常图片文件路径" + strJpgFile, e); throw new Exception(e);
} finally { } finally {
try { if (document != null) {
if (document != null && document.isOpen()) { document.close();
document.close(); }
} if (rafa != null) {
if (rafa != null) { rafa.close();
rafa.close(); }
} if (outputStream != null) {
} catch (IOException e) { outputStream.close();
e.printStackTrace();
} }
} }
return false; return strPdfFile;
} }
} }

View File

@ -8,24 +8,27 @@ import io.mola.galimatias.GalimatiasParseException;
import org.apache.commons.io.FileUtils; import org.apache.commons.io.FileUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RequestCallback;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;
import java.io.File; import java.io.File;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.net.URI;
import java.net.URL; import java.net.URL;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.Arrays; import java.util.Arrays;
import java.util.Map; import java.util.Map;
import java.util.UUID; import java.util.UUID;
import static cn.keking.utils.KkFileUtils.isFtpUrl; import static cn.keking.utils.KkFileUtils.isFtpUrl;
import static cn.keking.utils.KkFileUtils.isHttpUrl; import static cn.keking.utils.KkFileUtils.isHttpUrl;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RequestCallback;
import org.springframework.web.client.RestTemplate;
/** /**
* @author yudian-it * @author yudian-it
*/ */
@ -46,6 +49,7 @@ public class DownloadUtils {
* @return * @return
*/ */
public static ReturnResponse<String> downLoad(FileAttribute fileAttribute, String fileName) { public static ReturnResponse<String> downLoad(FileAttribute fileAttribute, String fileName) {
String fileKey = fileAttribute.getFileKey();
// 忽略ssl证书 // 忽略ssl证书
String urlStr = null; String urlStr = null;
try { try {
@ -70,8 +74,7 @@ public class DownloadUtils {
response.setMsg("下载失败:不支持的类型!" + urlStr); response.setMsg("下载失败:不支持的类型!" + urlStr);
return response; return response;
} }
assert urlStr != null; if (!ObjectUtils.isEmpty(fileKey)) { //压缩包文件 直接赋予路径 不予下载
if (urlStr.contains("?fileKey=")) {
response.setContent(fileDir + fileName); response.setContent(fileDir + fileName);
response.setMsg(fileName); response.setMsg(fileName);
return response; return response;
@ -87,20 +90,37 @@ public class DownloadUtils {
if (!fileAttribute.getSkipDownLoad()) { if (!fileAttribute.getSkipDownLoad()) {
if (isHttpUrl(url)) { if (isHttpUrl(url)) {
File realFile = new File(realPath); File realFile = new File(realPath);
SimpleClientHttpRequestFactory httpFactory = new SimpleClientHttpRequestFactory();
//连接超时10秒默认无限制单位毫秒
httpFactory.setConnectTimeout(60 * 1000);
//读取超时5秒,默认无限限制,单位:毫秒
httpFactory.setReadTimeout(60 * 1000);
restTemplate.setRequestFactory(httpFactory);
RequestCallback requestCallback = request -> { RequestCallback requestCallback = request -> {
request.getHeaders() request.getHeaders().setAccept(Arrays.asList(MediaType.APPLICATION_OCTET_STREAM, MediaType.ALL));
.setAccept(Arrays.asList(MediaType.APPLICATION_OCTET_STREAM, MediaType.ALL)); String proxyAuthorization = fileAttribute.getKkProxyAuthorization();
String proxyAuthorization = fileAttribute.getKkProxyAuthorization();
if(StringUtils.hasText(proxyAuthorization)){ if(StringUtils.hasText(proxyAuthorization)){
Map<String,String> proxyAuthorizationMap = mapper.readValue(proxyAuthorization, Map.class); Map<String,String> proxyAuthorizationMap = mapper.readValue(proxyAuthorization, Map.class);
proxyAuthorizationMap.entrySet().forEach(entry-> request.getHeaders().set(entry.getKey(), entry.getValue())); proxyAuthorizationMap.forEach((key, value) -> request.getHeaders().set(key, value));
} }
}; };
urlStr = URLDecoder.decode(urlStr, StandardCharsets.UTF_8.name()); try {
restTemplate.execute(urlStr, HttpMethod.GET, requestCallback, fileResponse -> { URI uri = URI.create(urlStr);
FileUtils.copyToFile(fileResponse.getBody(), realFile); restTemplate.execute(uri, HttpMethod.GET, requestCallback, fileResponse -> {
return null; FileUtils.copyToFile(fileResponse.getBody(), realFile);
}); return null;
});
} catch (RestClientException e) {
if (e.getMessage().contains("404 Not Found") || e.getMessage().contains("403 Not Found") || e.getMessage().contains("500 Not Found") ){
response.setCode(1);
response.setContent(null);
response.setMsg("下载失败:" + e);
return response;
}else {
e.printStackTrace();
}
}
} else if (isFtpUrl(url)) { } else if (isFtpUrl(url)) {
String ftpUsername = WebUtils.getUrlParameterReg(fileAttribute.getUrl(), URL_PARAM_FTP_USERNAME); String ftpUsername = WebUtils.getUrlParameterReg(fileAttribute.getUrl(), URL_PARAM_FTP_USERNAME);
String ftpPassword = WebUtils.getUrlParameterReg(fileAttribute.getUrl(), URL_PARAM_FTP_PASSWORD); String ftpPassword = WebUtils.getUrlParameterReg(fileAttribute.getUrl(), URL_PARAM_FTP_PASSWORD);

View File

@ -0,0 +1,82 @@
package cn.keking.utils;
import java.util.BitSet;
public class UrlEncoderUtils {
private static BitSet dontNeedEncoding;
static {
dontNeedEncoding = new BitSet(256);
int i;
for (i = 'a'; i <= 'z'; i++) {
dontNeedEncoding.set(i);
}
for (i = 'A'; i <= 'Z'; i++) {
dontNeedEncoding.set(i);
}
for (i = '0'; i <= '9'; i++) {
dontNeedEncoding.set(i);
}
dontNeedEncoding.set('+');
/**
* , 123+456,123+456123 456urlEncode<br>
* 123%2B456,使123+456 urlEncode <br>
* urlEncodeurlEncode<br>
* stringurlEncode<br>
*/
dontNeedEncoding.set('-');
dontNeedEncoding.set('_');
dontNeedEncoding.set('.');
dontNeedEncoding.set('*');
}
/**
* strurlEncoder.encode<br>
* URL,encode.<Br>
* encodeencode<Br>
*
* @param str
* @return
*/
public static boolean hasUrlEncoded(String str) {
/**
* JAVAURLEncoder.encodestring : ' ''+' <br>
* 0-9a-zA-Z <br>
* '-''_''.''*' <br>
* %XXX16[0-9A-F]
*/
boolean needEncode = false;
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
if (dontNeedEncoding.get((int) c)) {
continue;
}
if (c == '%' && (i + 2) < str.length()) {
// 判断是否符合urlEncode规范
char c1 = str.charAt(++i);
char c2 = str.charAt(++i);
if (isDigit16Char(c1) && isDigit16Char(c2)) {
continue;
}
}
// 其他字符肯定需要urlEncode
needEncode = true;
break;
}
return !needEncode;
}
/**
* c16
*
* @param c
* @return
*/
private static boolean isDigit16Char(char c) {
return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F');
}
}

View File

@ -52,7 +52,7 @@
function chooseNode(event, treeId, treeNode) { function chooseNode(event, treeId, treeNode) {
if (!treeNode.isParent) { if (!treeNode.isParent) {
var path = '${baseUrl}' + treeNode.id + "?fileKey=" + '${fileName}'; var path = '${baseUrl}' + treeNode.id + "?kkCompressfileKey=" + '${fileName}';
location.href = "${baseUrl}onlinePreview?url=" + encodeURIComponent(Base64.encode(path)); location.href = "${baseUrl}onlinePreview?url=" + encodeURIComponent(Base64.encode(path));
} }
} }