Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7715b18415 | |||
| edb0fce4c7 | |||
| 10160e8104 | |||
| 5e5488ceec | |||
| 602e80ee9e | |||
| 9c83860e1b | |||
| 1f1970232b |
@ -28,5 +28,5 @@ ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
|
||||
ENV PATH $PATH:$JAVA_HOME/bin
|
||||
ENV LANG zh_CN.UTF-8
|
||||
ENV LC_ALL zh_CN.UTF-8
|
||||
ENV KKFILEVIEW_BIN_FOLDER /opt/kkFileView-2.2.1/bin
|
||||
ENTRYPOINT ["java","-Dfile.encoding=UTF-8","-Dsun.java2d.cmm=sun.java2d.cmm.kcms.KcmsServiceProvider","-Dspring.config.location=/opt/kkFileView-2.2.1/config/application.properties","-jar","/opt/kkFileView-2.2.1/bin/kkFileView-2.2.1.jar"]
|
||||
ENV KKFILEVIEW_BIN_FOLDER /opt/kkFileView-3.3.0/bin
|
||||
ENTRYPOINT ["java","-Dfile.encoding=UTF-8","-Dsun.java2d.cmm=sun.java2d.cmm.kcms.KcmsServiceProvider","-Dspring.config.location=/opt/kkFileView-3.3.0/config/application.properties","-jar","/opt/kkFileView-3.3.0/bin/kkFileView-3.3.0.jar"]
|
||||
20
README.md
20
README.md
@ -109,6 +109,26 @@ pdf预览模式预览效果如下
|
||||
|
||||
### 历史更新记录
|
||||
|
||||
> 2020年12月27日 :
|
||||
|
||||
2020年年终大版本更新,架构全面设计,代码全面重构,代码质量全面提升,二次开发更便捷,欢迎拉源码品鉴,提issue、pr共同建设
|
||||
|
||||
1. 架构模块调整,大量的代码重构,代码质量提升N个等级,欢迎品鉴
|
||||
2. 增强XML文件预览效果,新增XML文档数结构预览
|
||||
3. 新增markdown文件预览支持,预览支持md渲染和源文本切换支持
|
||||
4. 切换底层web server为jetty,解决这个issue:https://github.com/kekingcn/kkFileView/issues/168
|
||||
5. 引入cpdetector,解决文件编码识别问题
|
||||
6. url采用base64+urlencode双编码,彻底解决各种奇葩文件名预览问题
|
||||
7. 新增配置项office.preview.switch.disabled,控制offic文件预览切换开关
|
||||
8. 优化文本类型文件预览逻辑,采用Base64传输内容,避免预览时再次请求文件内容
|
||||
9. office预览图片模式禁用图片放大效果,达到图片和pdf预览效果一致的体验
|
||||
10. 直接代码静态设置pdfbox兼容低版本jdk,在IDEA中运行也不会有警告提示
|
||||
11. 移除guava、hutool等非必须的工具包,减少代码体积
|
||||
12. Office组件加载异步化,提速应用启动速度最快到5秒内
|
||||
13. 合理设置预览消费队列的线程数
|
||||
14. 修复压缩包里文件再次预览失败的bug
|
||||
15. 修复图片预览的bug
|
||||
|
||||
> 2020年05月20日 :
|
||||
1. 新增支持全局水印,并支持通过参数动态改变水印内容
|
||||
2. 新增支持CAD文件预览
|
||||
|
||||
2
pom.xml
2
pom.xml
@ -5,7 +5,7 @@
|
||||
|
||||
<groupId>cn.keking</groupId>
|
||||
<artifactId>filepreview</artifactId>
|
||||
<version>2.2.1</version>
|
||||
<version>3.3.0</version>
|
||||
<modules>
|
||||
<module>office-plugin</module>
|
||||
<module>server</module>
|
||||
|
||||
@ -12,7 +12,7 @@
|
||||
|
||||
<groupId>cn.keking</groupId>
|
||||
<artifactId>kkFileView</artifactId>
|
||||
<version>2.2.1</version>
|
||||
<version>3.3.0</version>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
|
||||
@ -6,4 +6,4 @@ echo Starting kkFileView...
|
||||
echo Please check log file in ../log/kkFileView.log for more information
|
||||
echo You can get help in our official homesite: https://kkFileView.keking.cn
|
||||
echo If this project is helpful to you, please star it on https://gitee.com/kekingcn/file-online-preview/stargazers
|
||||
java -Dsun.java2d.cmm=sun.java2d.cmm.kcms.KcmsServiceProvider -Dspring.config.location=..\config\application.properties -jar kkFileView-2.2.1.jar -> ..\log\kkFileView.log
|
||||
java -Dsun.java2d.cmm=sun.java2d.cmm.kcms.KcmsServiceProvider -Dspring.config.location=..\config\application.properties -jar kkFileView-3.3.0.jar -> ..\log\kkFileView.log
|
||||
@ -29,4 +29,4 @@ echo "Starting kkFileView..."
|
||||
echo "Please execute ./showlog.sh to check log for more information"
|
||||
echo "You can get help in our official homesite: https://kkFileView.keking.cn"
|
||||
echo "If this project is helpful to you, please star it on https://gitee.com/kekingcn/file-online-preview/stargazers"
|
||||
nohup java -Dfile.encoding=UTF-8 -Dsun.java2d.cmm=sun.java2d.cmm.kcms.KcmsServiceProvider -Dspring.config.location=../config/application.properties -jar kkFileView-2.2.1.jar > ../log/kkFileView.log 2>&1 &
|
||||
nohup java -Dfile.encoding=UTF-8 -Dsun.java2d.cmm=sun.java2d.cmm.kcms.KcmsServiceProvider -Dspring.config.location=../config/application.properties -jar kkFileView-3.3.0.jar > ../log/kkFileView.log 2>&1 &
|
||||
|
||||
@ -1,7 +1,5 @@
|
||||
package cn.keking.service;
|
||||
package cn.keking.config;
|
||||
|
||||
import cn.keking.config.ConfigConstants;
|
||||
import cn.keking.config.WatermarkConfigConstants;
|
||||
import org.artofsolving.jodconverter.office.OfficeUtils;
|
||||
import org.artofsolving.jodconverter.util.ConfigUtils;
|
||||
import org.slf4j.Logger;
|
||||
@ -13,6 +11,7 @@ import java.io.BufferedReader;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* @auther: chenjh
|
||||
@ -81,7 +80,7 @@ public class ConfigRefreshComponent {
|
||||
setWatermarkConfig(properties);
|
||||
bufferedReader.close();
|
||||
fileReader.close();
|
||||
Thread.sleep(1000L);
|
||||
TimeUnit.SECONDS.sleep(1);
|
||||
}
|
||||
} catch (IOException | InterruptedException e) {
|
||||
LOGGER.error("读取配置文件异常", e);
|
||||
@ -1,7 +1,7 @@
|
||||
package cn.keking.utils;
|
||||
package cn.keking.config;
|
||||
|
||||
import cn.keking.config.ConfigConstants;
|
||||
import cn.keking.service.cache.CacheService;
|
||||
import cn.keking.utils.FileUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
|
||||
@ -14,13 +14,13 @@ import org.springframework.stereotype.Component;
|
||||
*/
|
||||
@Component
|
||||
@ConditionalOnExpression("'${cache.clean.enabled:false}'.equals('true')")
|
||||
public class ShedulerClean {
|
||||
public class SchedulerCleanConfig {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(ShedulerClean.class);
|
||||
private final Logger logger = LoggerFactory.getLogger(SchedulerCleanConfig.class);
|
||||
|
||||
private final CacheService cacheService;
|
||||
|
||||
public ShedulerClean(CacheService cacheService) {
|
||||
public SchedulerCleanConfig(CacheService cacheService) {
|
||||
this.cacheService = cacheService;
|
||||
}
|
||||
|
||||
@ -10,6 +10,7 @@ import java.util.Map;
|
||||
* Content :文件类型,文本,office,压缩包等等
|
||||
*/
|
||||
public enum FileType {
|
||||
|
||||
picture("pictureFilePreviewImpl"),
|
||||
compress("compressFilePreviewImpl"),
|
||||
office("officeFilePreviewImpl"),
|
||||
@ -19,12 +20,13 @@ public enum FileType {
|
||||
media("mediaFilePreviewImpl"),
|
||||
markdown("markdownFilePreviewImpl"),
|
||||
xml("xmlFilePreviewImpl"),
|
||||
flv("flvFilePreviewImpl"),
|
||||
cad("cadFilePreviewImpl");
|
||||
|
||||
private static final String[] OFFICE_TYPES = {"docx", "doc", "xls", "xlsx", "ppt", "pptx"};
|
||||
private static final String[] PICTURE_TYPES = {"jpg", "jpeg", "png", "gif", "bmp", "ico", "RAW"};
|
||||
private static final String[] ARCHIVE_TYPES = {"rar", "zip", "jar", "7-zip", "tar", "gzip", "7z"};
|
||||
private static final String[] SIMTEXT_TYPES = ConfigConstants.getSimText();
|
||||
private static final String[] SSIM_TEXT_TYPES = ConfigConstants.getSimText();
|
||||
private static final String[] MEDIA_TYPES = ConfigConstants.getMedia();
|
||||
private static final Map<String, FileType> FILE_TYPE_MAPPER = new HashMap<>();
|
||||
|
||||
@ -38,7 +40,7 @@ public enum FileType {
|
||||
for (String archive : ARCHIVE_TYPES) {
|
||||
FILE_TYPE_MAPPER.put(archive, FileType.compress);
|
||||
}
|
||||
for (String text : SIMTEXT_TYPES) {
|
||||
for (String text : SSIM_TEXT_TYPES) {
|
||||
FILE_TYPE_MAPPER.put(text, FileType.simText);
|
||||
}
|
||||
for (String media : MEDIA_TYPES) {
|
||||
@ -48,11 +50,29 @@ public enum FileType {
|
||||
FILE_TYPE_MAPPER.put("xml", FileType.xml);
|
||||
FILE_TYPE_MAPPER.put("pdf", FileType.pdf);
|
||||
FILE_TYPE_MAPPER.put("dwg", FileType.cad);
|
||||
FILE_TYPE_MAPPER.put("flv", FileType.flv);
|
||||
|
||||
}
|
||||
|
||||
public static FileType to(String fileType){
|
||||
private static FileType to(String fileType){
|
||||
return FILE_TYPE_MAPPER.getOrDefault(fileType,other);
|
||||
}
|
||||
/**
|
||||
* 查看文件类型(防止参数中存在.点号或者其他特殊字符,所以先抽取文件名,然后再获取文件类型)
|
||||
*
|
||||
* @param url url
|
||||
* @return 文件类型
|
||||
*/
|
||||
public static FileType typeFromUrl(String url) {
|
||||
String nonPramStr = url.substring(0, url.contains("?") ? url.indexOf("?") : url.length());
|
||||
String fileName = nonPramStr.substring(nonPramStr.lastIndexOf("/") + 1);
|
||||
return typeFromFileName(fileName);
|
||||
}
|
||||
|
||||
public static FileType typeFromFileName(String fileName) {
|
||||
String fileType = fileName.substring(fileName.lastIndexOf(".") + 1);
|
||||
return FileType.to(fileType);
|
||||
}
|
||||
|
||||
private final String instanceName;
|
||||
|
||||
|
||||
@ -4,11 +4,18 @@ import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 接口返回值结构
|
||||
*
|
||||
* @author yudian-it
|
||||
* @date 2017/11/17
|
||||
*/
|
||||
public class ReturnResponse<T> implements Serializable{
|
||||
public class ReturnResponse<T> implements Serializable {
|
||||
private static final long serialVersionUID = 313975329998789878L;
|
||||
|
||||
public static final int SUCCESS_CODE = 0;
|
||||
public static final int FAILURE_CODE = 1;
|
||||
public static final String SUCCESS_MSG = "SUCCESS";
|
||||
public static final String FAILURE_MSG = "FAILURE";
|
||||
|
||||
/**
|
||||
* 返回状态
|
||||
* 0. 成功
|
||||
@ -31,6 +38,30 @@ public class ReturnResponse<T> implements Serializable{
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
public static ReturnResponse<Object> failure(String errMsg) {
|
||||
return new ReturnResponse<>(FAILURE_CODE, errMsg, null);
|
||||
}
|
||||
|
||||
public static ReturnResponse<Object> failure() {
|
||||
return failure(FAILURE_MSG);
|
||||
}
|
||||
|
||||
public static ReturnResponse<Object> success(){
|
||||
return success(null);
|
||||
}
|
||||
|
||||
public static ReturnResponse<Object> success(Object content) {
|
||||
return new ReturnResponse<>(SUCCESS_CODE, SUCCESS_MSG, content);
|
||||
}
|
||||
|
||||
public boolean isSuccess(){
|
||||
return SUCCESS_CODE == code;
|
||||
}
|
||||
|
||||
public boolean isFailure(){
|
||||
return !isSuccess();
|
||||
}
|
||||
|
||||
public int getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
@ -67,7 +67,7 @@ public class CompressFileReader {
|
||||
}
|
||||
String parentName = getLast2FileName(fullName, archiveSeparator, archiveFileName);
|
||||
parentName = (level - 1) + "_" + parentName;
|
||||
FileType type = fileHandlerService.typeFromUrl(childName);
|
||||
FileType type = FileType.typeFromUrl(childName);
|
||||
if (type.equals(FileType.picture)) {//添加图片文件到图片列表
|
||||
imgUrls.add(baseUrl + childName);
|
||||
}
|
||||
@ -120,7 +120,7 @@ public class CompressFileReader {
|
||||
headersToBeExtracted.add(Collections.singletonMap(childName, header));
|
||||
}
|
||||
String parentName = getLast2FileName(fullName, "\\", archiveFileName);
|
||||
FileType type = fileHandlerService.typeFromUrl(childName);
|
||||
FileType type = FileType.typeFromUrl(childName);
|
||||
if (type.equals(FileType.picture)) {//添加图片文件到图片列表
|
||||
imgUrls.add(baseUrl + childName);
|
||||
}
|
||||
@ -163,7 +163,7 @@ public class CompressFileReader {
|
||||
}
|
||||
String parentName = getLast2FileName(fullName, archiveSeparator, archiveFileName);
|
||||
parentName = (level - 1) + "_" + parentName;
|
||||
FileType type = fileHandlerService.typeFromUrl(childName);
|
||||
FileType type = FileType.typeFromUrl(childName);
|
||||
if (type.equals(FileType.picture)) {//添加图片文件到图片列表
|
||||
imgUrls.add(baseUrl + childName);
|
||||
}
|
||||
|
||||
@ -10,6 +10,7 @@ import org.springframework.ui.ExtendedModelMap;
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Created by kl on 2018/1/19.
|
||||
@ -70,7 +71,7 @@ public class FileConvertQueueTask {
|
||||
}
|
||||
} catch (Exception e) {
|
||||
try {
|
||||
Thread.sleep(1000*10);
|
||||
TimeUnit.SECONDS.sleep(10);
|
||||
} catch (Exception ex){
|
||||
ex.printStackTrace();
|
||||
}
|
||||
|
||||
@ -4,13 +4,28 @@ import cn.keking.config.ConfigConstants;
|
||||
import cn.keking.model.FileAttribute;
|
||||
import cn.keking.model.FileType;
|
||||
import cn.keking.service.cache.CacheService;
|
||||
import cn.keking.utils.FileUtils;
|
||||
import cn.keking.utils.WebUtils;
|
||||
import com.aspose.cad.Color;
|
||||
import com.aspose.cad.fileformats.cad.CadDrawTypeMode;
|
||||
import com.aspose.cad.imageoptions.CadRasterizationOptions;
|
||||
import com.aspose.cad.imageoptions.PdfOptions;
|
||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
import org.apache.pdfbox.rendering.ImageType;
|
||||
import org.apache.pdfbox.rendering.PDFRenderer;
|
||||
import org.apache.pdfbox.tools.imageio.ImageIOUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.*;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@ -21,10 +36,15 @@ import java.util.Map;
|
||||
@Component
|
||||
public class FileHandlerService {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(FileHandlerService.class);
|
||||
|
||||
private static final String DEFAULT_CONVERTER_CHARSET = System.getProperty("sun.jnu.encoding");
|
||||
private final String fileDir = ConfigConstants.getFileDir();
|
||||
private final CacheService cacheService;
|
||||
|
||||
@Value("${server.tomcat.uri-encoding:UTF-8}")
|
||||
private String uriEncoding;
|
||||
|
||||
public FileHandlerService(CacheService cacheService) {
|
||||
this.cacheService = cacheService;
|
||||
}
|
||||
@ -51,35 +71,6 @@ public class FileHandlerService {
|
||||
return cacheService.getPdfImageCache(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查看文件类型(防止参数中存在.点号或者其他特殊字符,所以先抽取文件名,然后再获取文件类型)
|
||||
*
|
||||
* @param url url
|
||||
* @return 文件类型
|
||||
*/
|
||||
public FileType typeFromUrl(String url) {
|
||||
String nonPramStr = url.substring(0, url.contains("?") ? url.indexOf("?") : url.length());
|
||||
String fileName = nonPramStr.substring(nonPramStr.lastIndexOf("/") + 1);
|
||||
return this.typeFromFileName(fileName);
|
||||
}
|
||||
|
||||
private FileType typeFromFileName(String fileName) {
|
||||
String fileType = fileName.substring(fileName.lastIndexOf(".") + 1);
|
||||
return FileType.to(fileType);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从url中剥离出文件名
|
||||
*
|
||||
* @param url 格式如:http://www.com.cn/20171113164107_月度绩效表模板(新).xls?UCloudPublicKey=ucloudtangshd@weifenf.com14355492830001993909323&Expires=&Signature=I D1NOFtAJSPT16E6imv6JWuq0k=
|
||||
* @return 文件名
|
||||
*/
|
||||
public String getFileNameFromURL(String url) {
|
||||
// 因为url的参数中可能会存在/的情况,所以直接url.lastIndexOf("/")会有问题
|
||||
// 所以先从?处将url截断,然后运用url.lastIndexOf("/")获取文件名
|
||||
String noQueryUrl = url.substring(0, url.contains("?") ? url.indexOf("?") : url.length());
|
||||
return noQueryUrl.substring(noQueryUrl.lastIndexOf("/") + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从路径中获取文件负
|
||||
@ -174,19 +165,87 @@ public class FileHandlerService {
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件后缀
|
||||
*
|
||||
* @param url url
|
||||
* @return 文件后缀
|
||||
* pdf文件转换成jpg图片集
|
||||
* @param pdfFilePath pdf文件路径
|
||||
* @param pdfName pdf文件名称
|
||||
* @param baseUrl 基础访问地址
|
||||
* @return 图片访问集合
|
||||
*/
|
||||
private String suffixFromUrl(String url) {
|
||||
String nonPramStr = url.substring(0, url.contains("?") ? url.indexOf("?") : url.length());
|
||||
String fileName = nonPramStr.substring(nonPramStr.lastIndexOf("/") + 1);
|
||||
return suffixFromFileName(fileName);
|
||||
public List<String> pdf2jpg(String pdfFilePath, String pdfName, String baseUrl) {
|
||||
List<String> imageUrls = new ArrayList<>();
|
||||
Integer imageCount = this.getConvertedPdfImage(pdfFilePath);
|
||||
String imageFileSuffix = ".jpg";
|
||||
String pdfFolder = pdfName.substring(0, pdfName.length() - 4);
|
||||
String urlPrefix;
|
||||
try {
|
||||
urlPrefix = baseUrl + URLEncoder.encode(URLEncoder.encode(pdfFolder, uriEncoding).replaceAll("\\+", "%20"), uriEncoding);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
logger.error("UnsupportedEncodingException", e);
|
||||
urlPrefix = baseUrl + pdfFolder;
|
||||
}
|
||||
if (imageCount != null && imageCount > 0) {
|
||||
for (int i = 0; i < imageCount; i++)
|
||||
imageUrls.add(urlPrefix + "/" + i + imageFileSuffix);
|
||||
return imageUrls;
|
||||
}
|
||||
try {
|
||||
File pdfFile = new File(pdfFilePath);
|
||||
PDDocument doc = PDDocument.load(pdfFile);
|
||||
int pageCount = doc.getNumberOfPages();
|
||||
PDFRenderer pdfRenderer = new PDFRenderer(doc);
|
||||
|
||||
int index = pdfFilePath.lastIndexOf(".");
|
||||
String folder = pdfFilePath.substring(0, index);
|
||||
|
||||
File path = new File(folder);
|
||||
if (!path.exists() && !path.mkdirs()) {
|
||||
logger.error("创建转换文件【{}】目录失败,请检查目录权限!", folder);
|
||||
}
|
||||
String imageFilePath;
|
||||
for (int pageIndex = 0; pageIndex < pageCount; pageIndex++) {
|
||||
imageFilePath = folder + File.separator + pageIndex + imageFileSuffix;
|
||||
BufferedImage image = pdfRenderer.renderImageWithDPI(pageIndex, 105, ImageType.RGB);
|
||||
ImageIOUtil.writeImage(image, imageFilePath, 105);
|
||||
imageUrls.add(urlPrefix + "/" + pageIndex + imageFileSuffix);
|
||||
}
|
||||
doc.close();
|
||||
this.addConvertedPdfImage(pdfFilePath, pageCount);
|
||||
} catch (IOException e) {
|
||||
logger.error("Convert pdf to jpg exception, pdfFilePath:{}", pdfFilePath, e);
|
||||
}
|
||||
return imageUrls;
|
||||
}
|
||||
|
||||
private String suffixFromFileName(String fileName) {
|
||||
return fileName.substring(fileName.lastIndexOf(".") + 1);
|
||||
/**
|
||||
* cad文件转pdf
|
||||
* @param inputFilePath cad文件路径
|
||||
* @param outputFilePath pdf输出文件路径
|
||||
* @return 转换是否成功
|
||||
*/
|
||||
public boolean cadToPdf(String inputFilePath, String outputFilePath) {
|
||||
com.aspose.cad.Image cadImage = com.aspose.cad.Image.load(inputFilePath);
|
||||
CadRasterizationOptions cadRasterizationOptions = new CadRasterizationOptions();
|
||||
cadRasterizationOptions.setLayouts(new String[]{"Model"});
|
||||
cadRasterizationOptions.setNoScaling(true);
|
||||
cadRasterizationOptions.setBackgroundColor(Color.getWhite());
|
||||
cadRasterizationOptions.setPageWidth(cadImage.getWidth());
|
||||
cadRasterizationOptions.setPageHeight(cadImage.getHeight());
|
||||
cadRasterizationOptions.setPdfProductLocation("center");
|
||||
cadRasterizationOptions.setAutomaticLayoutsScaling(true);
|
||||
cadRasterizationOptions.setDrawType(CadDrawTypeMode.UseObjectColor);
|
||||
PdfOptions pdfOptions = new PdfOptions();
|
||||
pdfOptions.setVectorRasterizationOptions(cadRasterizationOptions);
|
||||
File outputFile = new File(outputFilePath);
|
||||
OutputStream stream;
|
||||
try {
|
||||
stream = new FileOutputStream(outputFile);
|
||||
cadImage.save(stream, pdfOptions);
|
||||
cadImage.close();
|
||||
return true;
|
||||
} catch (FileNotFoundException e) {
|
||||
logger.error("PDFFileNotFoundException,inputFilePath:{}", inputFilePath, e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -203,12 +262,12 @@ public class FileHandlerService {
|
||||
String fullFileName = WebUtils.getUrlParameterReg(url, "fullfilename");
|
||||
if (StringUtils.hasText(fullFileName)) {
|
||||
fileName = fullFileName;
|
||||
type = this.typeFromFileName(fullFileName);
|
||||
suffix = suffixFromFileName(fullFileName);
|
||||
type = FileType.typeFromFileName(fullFileName);
|
||||
suffix = FileUtils.suffixFromFileName(fullFileName);
|
||||
} else {
|
||||
fileName = getFileNameFromURL(url);
|
||||
type = typeFromUrl(url);
|
||||
suffix = suffixFromUrl(url);
|
||||
fileName = WebUtils.getFileNameFromURL(url);
|
||||
type = FileType.typeFromUrl(url);
|
||||
suffix = WebUtils.suffixFromUrl(url);
|
||||
}
|
||||
attribute.setType(type);
|
||||
attribute.setName(fileName);
|
||||
|
||||
@ -8,5 +8,16 @@ import org.springframework.ui.Model;
|
||||
* Content :
|
||||
*/
|
||||
public interface FilePreview {
|
||||
|
||||
String FLV_FILE_PREVIEW_PAGE = "flv";
|
||||
String PDF_FILE_PREVIEW_PAGE = "pdf";
|
||||
String COMPRESS_FILE_PREVIEW_PAGE = "compress";
|
||||
String MEDIA_FILE_PREVIEW_PAGE = "media";
|
||||
String PICTURE_FILE_PREVIEW_PAGE = "picture";
|
||||
String OFFICE_PICTURE_FILE_PREVIEW_PAGE = "officePicture";
|
||||
String TXT_FILE_PREVIEW_PAGE = "txt";
|
||||
String EXEL_FILE_PREVIEW_PAGE = "html";
|
||||
String NOT_SUPPORTED_FILE_PAGE = "fileNotSupported";
|
||||
|
||||
String filePreviewHandle(String url, Model model, FileAttribute fileAttribute);
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
package cn.keking.extend;
|
||||
package cn.keking.service;
|
||||
|
||||
import org.artofsolving.jodconverter.document.DocumentFamily;
|
||||
import org.artofsolving.jodconverter.document.DocumentFormat;
|
||||
@ -13,9 +13,9 @@ import java.util.Map;
|
||||
* @author yudian-it
|
||||
* @date 2017/12/5
|
||||
*/
|
||||
public class ControlDocumentFormatRegistry extends SimpleDocumentFormatRegistry {
|
||||
public class OfficePluginExtendFormatRegistry extends SimpleDocumentFormatRegistry {
|
||||
|
||||
public ControlDocumentFormatRegistry() {
|
||||
public OfficePluginExtendFormatRegistry() {
|
||||
DocumentFormat pdf = new DocumentFormat("Portable Document Format", "pdf", "application/pdf");
|
||||
pdf.setStoreProperties(DocumentFamily.TEXT, Collections.singletonMap("FilterName", "writer_pdf_Export"));
|
||||
pdf.setStoreProperties(DocumentFamily.SPREADSHEET, Collections.singletonMap("FilterName", "calc_pdf_Export"));
|
||||
@ -1,7 +1,6 @@
|
||||
package cn.keking.service;
|
||||
|
||||
import com.sun.star.document.UpdateDocMode;
|
||||
import cn.keking.extend.ControlDocumentFormatRegistry;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.artofsolving.jodconverter.OfficeDocumentConverter;
|
||||
import org.artofsolving.jodconverter.office.DefaultOfficeManagerConfiguration;
|
||||
@ -72,7 +71,7 @@ public class OfficePluginManager {
|
||||
}
|
||||
|
||||
public OfficeDocumentConverter getDocumentConverter() {
|
||||
OfficeDocumentConverter converter = new OfficeDocumentConverter(officeManager, new ControlDocumentFormatRegistry());
|
||||
OfficeDocumentConverter converter = new OfficeDocumentConverter(officeManager, new OfficePluginExtendFormatRegistry());
|
||||
converter.setDefaultLoadProperties(getLoadProperties());
|
||||
return converter;
|
||||
}
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
package cn.keking.service;
|
||||
|
||||
import org.artofsolving.jodconverter.OfficeDocumentConverter;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.File;
|
||||
@ -10,6 +12,8 @@ import java.io.File;
|
||||
*/
|
||||
@Component
|
||||
public class OfficeToPdfService {
|
||||
|
||||
private final static Logger logger = LoggerFactory.getLogger(OfficeToPdfService.class);
|
||||
private final OfficePluginManager officePluginManager;
|
||||
|
||||
public OfficeToPdfService(OfficePluginManager officePluginManager) {
|
||||
@ -21,12 +25,11 @@ public class OfficeToPdfService {
|
||||
}
|
||||
|
||||
|
||||
public static void converterFile(File inputFile, String outputFilePath_end,
|
||||
OfficeDocumentConverter converter) {
|
||||
public static void converterFile(File inputFile, String outputFilePath_end, OfficeDocumentConverter converter) {
|
||||
File outputFile = new File(outputFilePath_end);
|
||||
// 假如目标路径不存在,则新建该路径
|
||||
if (!outputFile.getParentFile().exists()) {
|
||||
outputFile.getParentFile().mkdirs();
|
||||
if (!outputFile.getParentFile().exists() && !outputFile.getParentFile().mkdirs()) {
|
||||
logger.error("创建目录【{}】失败,请检查目录权限!",outputFilePath_end);
|
||||
}
|
||||
converter.convert(inputFile, outputFile);
|
||||
}
|
||||
|
||||
@ -28,19 +28,11 @@ public class CacheServiceRedisImpl implements CacheService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initPDFCachePool(Integer capacity) {
|
||||
|
||||
}
|
||||
|
||||
public void initPDFCachePool(Integer capacity) { }
|
||||
@Override
|
||||
public void initIMGCachePool(Integer capacity) {
|
||||
|
||||
}
|
||||
|
||||
public void initIMGCachePool(Integer capacity) { }
|
||||
@Override
|
||||
public void initPdfImagesCachePool(Integer capacity) {
|
||||
|
||||
}
|
||||
public void initPdfImagesCachePool(Integer capacity) { }
|
||||
|
||||
@Override
|
||||
public void putPDFCache(String key, String value) {
|
||||
|
||||
@ -31,11 +31,8 @@ public class CacheServiceRocksDBImpl implements CacheService {
|
||||
}
|
||||
|
||||
private static final String DB_PATH = ConfigUtils.getHomePath() + File.separator + "cache";
|
||||
|
||||
private static final int QUEUE_SIZE = 500000;
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(CacheServiceRocksDBImpl.class);
|
||||
|
||||
private final BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<>(QUEUE_SIZE);
|
||||
|
||||
private RocksDB db;
|
||||
|
||||
@ -4,10 +4,8 @@ import cn.keking.config.ConfigConstants;
|
||||
import cn.keking.model.FileAttribute;
|
||||
import cn.keking.model.ReturnResponse;
|
||||
import cn.keking.service.FilePreview;
|
||||
import cn.keking.utils.CadUtils;
|
||||
import cn.keking.utils.DownloadUtils;
|
||||
import cn.keking.service.FileHandlerService;
|
||||
import cn.keking.utils.PdfUtils;
|
||||
import cn.keking.web.filter.BaseUrlFilter;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.ui.Model;
|
||||
@ -22,47 +20,38 @@ import static cn.keking.service.impl.OfficeFilePreviewImpl.getPreviewType;
|
||||
@Service
|
||||
public class CadFilePreviewImpl implements FilePreview {
|
||||
|
||||
private final FileHandlerService fileHandlerService;
|
||||
private final CadUtils cadUtils;
|
||||
private final PdfUtils pdfUtils;
|
||||
|
||||
public CadFilePreviewImpl(FileHandlerService fileHandlerService, CadUtils cadUtils, PdfUtils pdfUtils) {
|
||||
this.fileHandlerService = fileHandlerService;
|
||||
this.cadUtils = cadUtils;
|
||||
this.pdfUtils = pdfUtils;
|
||||
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
public CadFilePreviewImpl(FileHandlerService fileHandlerService, OtherFilePreviewImpl otherFilePreview) {
|
||||
this.fileHandlerService = fileHandlerService;
|
||||
this.otherFilePreview = otherFilePreview;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String filePreviewHandle(String url, Model model, FileAttribute fileAttribute) {
|
||||
// 预览Type,参数传了就取参数的,没传取系统默认
|
||||
String officePreviewType = model.asMap().get("officePreviewType") == null ? ConfigConstants.getOfficePreviewType() : model.asMap().get("officePreviewType").toString();
|
||||
String baseUrl = BaseUrlFilter.getBaseUrl();
|
||||
String suffix=fileAttribute.getSuffix();
|
||||
String fileName=fileAttribute.getName();
|
||||
String fileName = fileAttribute.getName();
|
||||
String pdfName = fileName.substring(0, fileName.lastIndexOf(".") + 1) + "pdf";
|
||||
String outFilePath = FILE_DIR + pdfName;
|
||||
// 判断之前是否已转换过,如果转换过,直接返回,否则执行转换
|
||||
if (!fileHandlerService.listConvertedFiles().containsKey(pdfName) || !ConfigConstants.isCacheEnabled()) {
|
||||
String filePath;
|
||||
ReturnResponse<String> response = DownloadUtils.downLoad(fileAttribute, null);
|
||||
if (0 != response.getCode()) {
|
||||
model.addAttribute("fileType", suffix);
|
||||
model.addAttribute("msg", response.getMsg());
|
||||
return "fileNotSupported";
|
||||
if (response.isFailure()) {
|
||||
return otherFilePreview.notSupportedFile(model, fileAttribute, response.getMsg());
|
||||
}
|
||||
filePath = response.getContent();
|
||||
if (StringUtils.hasText(outFilePath)) {
|
||||
boolean convertResult = cadUtils.cadToPdf(filePath, outFilePath);
|
||||
boolean convertResult = fileHandlerService.cadToPdf(filePath, outFilePath);
|
||||
if (!convertResult) {
|
||||
model.addAttribute("fileType", suffix);
|
||||
model.addAttribute("msg", "cad文件转换异常,请联系管理员");
|
||||
return "fileNotSupported";
|
||||
return otherFilePreview.notSupportedFile(model, fileAttribute, "cad文件转换异常,请联系管理员");
|
||||
}
|
||||
if (ConfigConstants.isCacheEnabled()) {
|
||||
// 加入缓存
|
||||
@ -71,10 +60,10 @@ public class CadFilePreviewImpl implements FilePreview {
|
||||
}
|
||||
}
|
||||
if (baseUrl != null && (OFFICE_PREVIEW_TYPE_IMAGE.equals(officePreviewType) || OFFICE_PREVIEW_TYPE_ALL_IMAGES.equals(officePreviewType))) {
|
||||
return getPreviewType(model, fileAttribute, officePreviewType, baseUrl, pdfName, outFilePath, pdfUtils, OFFICE_PREVIEW_TYPE_IMAGE);
|
||||
return getPreviewType(model, fileAttribute, officePreviewType, baseUrl, pdfName, outFilePath, fileHandlerService, OFFICE_PREVIEW_TYPE_IMAGE,otherFilePreview);
|
||||
}
|
||||
model.addAttribute("pdfUrl", pdfName);
|
||||
return "pdf";
|
||||
return PDF_FILE_PREVIEW_PAGE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -20,10 +20,12 @@ public class CompressFilePreviewImpl implements FilePreview {
|
||||
|
||||
private final FileHandlerService fileHandlerService;
|
||||
private final CompressFileReader compressFileReader;
|
||||
private final OtherFilePreviewImpl otherFilePreview;
|
||||
|
||||
public CompressFilePreviewImpl(FileHandlerService fileHandlerService, CompressFileReader compressFileReader) {
|
||||
public CompressFilePreviewImpl(FileHandlerService fileHandlerService, CompressFileReader compressFileReader, OtherFilePreviewImpl otherFilePreview) {
|
||||
this.fileHandlerService = fileHandlerService;
|
||||
this.compressFileReader = compressFileReader;
|
||||
this.otherFilePreview = otherFilePreview;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -34,10 +36,8 @@ public class CompressFilePreviewImpl implements FilePreview {
|
||||
// 判断文件名是否存在(redis缓存读取)
|
||||
if (!StringUtils.hasText(fileHandlerService.getConvertedFile(fileName)) || !ConfigConstants.isCacheEnabled()) {
|
||||
ReturnResponse<String> response = DownloadUtils.downLoad(fileAttribute, fileName);
|
||||
if (0 != response.getCode()) {
|
||||
model.addAttribute("fileType", suffix);
|
||||
model.addAttribute("msg", response.getMsg());
|
||||
return "fileNotSupported";
|
||||
if (response.isFailure()) {
|
||||
return otherFilePreview.notSupportedFile(model, fileAttribute, response.getMsg());
|
||||
}
|
||||
String filePath = response.getContent();
|
||||
if ("zip".equalsIgnoreCase(suffix) || "jar".equalsIgnoreCase(suffix) || "gzip".equalsIgnoreCase(suffix)) {
|
||||
@ -55,11 +55,9 @@ public class CompressFilePreviewImpl implements FilePreview {
|
||||
}
|
||||
if (fileTree != null && !"null".equals(fileTree)) {
|
||||
model.addAttribute("fileTree", fileTree);
|
||||
return "compress";
|
||||
return COMPRESS_FILE_PREVIEW_PAGE;
|
||||
} else {
|
||||
model.addAttribute("fileType", suffix);
|
||||
model.addAttribute("msg", "压缩文件类型不受支持,尝试在压缩的时候选择RAR4格式");
|
||||
return "fileNotSupported";
|
||||
return otherFilePreview.notSupportedFile(model, fileAttribute, "压缩文件类型不受支持,尝试在压缩的时候选择RAR4格式");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,27 @@
|
||||
package cn.keking.service.impl;
|
||||
|
||||
import cn.keking.model.FileAttribute;
|
||||
import cn.keking.service.FilePreview;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.ui.Model;
|
||||
|
||||
/**
|
||||
* @author : kl
|
||||
* create : 2020-12-27 2:50 下午
|
||||
* flv文件预览处理实现
|
||||
**/
|
||||
@Service
|
||||
public class FlvFilePreviewImpl implements FilePreview {
|
||||
|
||||
private final MediaFilePreviewImpl mediaFilePreview;
|
||||
|
||||
public FlvFilePreviewImpl(MediaFilePreviewImpl mediaFilePreview) {
|
||||
this.mediaFilePreview = mediaFilePreview;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String filePreviewHandle(String url, Model model, FileAttribute fileAttribute) {
|
||||
mediaFilePreview.filePreviewHandle(url,model,fileAttribute);
|
||||
return FLV_FILE_PREVIEW_PAGE;
|
||||
}
|
||||
}
|
||||
@ -8,6 +8,7 @@ import cn.keking.service.FileHandlerService;
|
||||
import cn.keking.web.filter.BaseUrlFilter;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.ui.Model;
|
||||
|
||||
/**
|
||||
* @author : kl
|
||||
* @authorboke : kailing.pub
|
||||
@ -18,9 +19,11 @@ import org.springframework.ui.Model;
|
||||
public class MediaFilePreviewImpl implements FilePreview {
|
||||
|
||||
private final FileHandlerService fileHandlerService;
|
||||
private final OtherFilePreviewImpl otherFilePreview;
|
||||
|
||||
public MediaFilePreviewImpl(FileHandlerService fileHandlerService) {
|
||||
public MediaFilePreviewImpl(FileHandlerService fileHandlerService, OtherFilePreviewImpl otherFilePreview) {
|
||||
this.fileHandlerService = fileHandlerService;
|
||||
this.otherFilePreview = otherFilePreview;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -28,10 +31,8 @@ public class MediaFilePreviewImpl implements FilePreview {
|
||||
// 不是http开头,浏览器不能直接访问,需下载到本地
|
||||
if (url != null && !url.toLowerCase().startsWith("http")) {
|
||||
ReturnResponse<String> response = DownloadUtils.downLoad(fileAttribute, fileAttribute.getName());
|
||||
if (0 != response.getCode()) {
|
||||
model.addAttribute("fileType", fileAttribute.getSuffix());
|
||||
model.addAttribute("msg", response.getMsg());
|
||||
return "fileNotSupported";
|
||||
if (response.isFailure()) {
|
||||
return otherFilePreview.notSupportedFile(model, fileAttribute, response.getMsg());
|
||||
} else {
|
||||
model.addAttribute("mediaUrl", BaseUrlFilter.getBaseUrl() + fileHandlerService.getRelativePath(response.getContent()));
|
||||
}
|
||||
@ -39,11 +40,7 @@ public class MediaFilePreviewImpl implements FilePreview {
|
||||
model.addAttribute("mediaUrl", url);
|
||||
}
|
||||
model.addAttribute("mediaUrl", url);
|
||||
String suffix=fileAttribute.getSuffix();
|
||||
if ("flv".equalsIgnoreCase(suffix)) {
|
||||
return "flv";
|
||||
}
|
||||
return "media";
|
||||
return MEDIA_FILE_PREVIEW_PAGE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -7,7 +7,6 @@ import cn.keking.service.FilePreview;
|
||||
import cn.keking.utils.DownloadUtils;
|
||||
import cn.keking.service.FileHandlerService;
|
||||
import cn.keking.service.OfficeToPdfService;
|
||||
import cn.keking.utils.PdfUtils;
|
||||
import cn.keking.web.filter.BaseUrlFilter;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.ui.Model;
|
||||
@ -22,27 +21,27 @@ import java.util.List;
|
||||
@Service
|
||||
public class OfficeFilePreviewImpl implements FilePreview {
|
||||
|
||||
private final FileHandlerService fileHandlerService;
|
||||
private final PdfUtils pdfUtils;
|
||||
private final OfficeToPdfService officeToPdfService;
|
||||
|
||||
public OfficeFilePreviewImpl(FileHandlerService fileHandlerService, PdfUtils pdfUtils, OfficeToPdfService officeToPdfService) {
|
||||
this.fileHandlerService = fileHandlerService;
|
||||
this.pdfUtils = pdfUtils;
|
||||
this.officeToPdfService = officeToPdfService;
|
||||
}
|
||||
|
||||
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 final FileHandlerService fileHandlerService;
|
||||
private final OfficeToPdfService officeToPdfService;
|
||||
private final OtherFilePreviewImpl otherFilePreview;
|
||||
|
||||
public OfficeFilePreviewImpl(FileHandlerService fileHandlerService, OfficeToPdfService officeToPdfService, OtherFilePreviewImpl otherFilePreview) {
|
||||
this.fileHandlerService = fileHandlerService;
|
||||
this.officeToPdfService = officeToPdfService;
|
||||
this.otherFilePreview = otherFilePreview;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String filePreviewHandle(String url, Model model, FileAttribute fileAttribute) {
|
||||
// 预览Type,参数传了就取参数的,没传取系统默认
|
||||
String officePreviewType = fileAttribute.getOfficePreviewType();
|
||||
String baseUrl = BaseUrlFilter.getBaseUrl();
|
||||
String suffix=fileAttribute.getSuffix();
|
||||
String fileName=fileAttribute.getName();
|
||||
String suffix = fileAttribute.getSuffix();
|
||||
String fileName = fileAttribute.getName();
|
||||
boolean isHtml = suffix.equalsIgnoreCase("xls") || suffix.equalsIgnoreCase("xlsx");
|
||||
String pdfName = fileName.substring(0, fileName.lastIndexOf(".") + 1) + (isHtml ? "html" : "pdf");
|
||||
String outFilePath = FILE_DIR + pdfName;
|
||||
@ -50,10 +49,8 @@ public class OfficeFilePreviewImpl implements FilePreview {
|
||||
if (!fileHandlerService.listConvertedFiles().containsKey(pdfName) || !ConfigConstants.isCacheEnabled()) {
|
||||
String filePath;
|
||||
ReturnResponse<String> response = DownloadUtils.downLoad(fileAttribute, null);
|
||||
if (0 != response.getCode()) {
|
||||
model.addAttribute("fileType", suffix);
|
||||
model.addAttribute("msg", response.getMsg());
|
||||
return "fileNotSupported";
|
||||
if (response.isFailure()) {
|
||||
return otherFilePreview.notSupportedFile(model, fileAttribute, response.getMsg());
|
||||
}
|
||||
filePath = response.getContent();
|
||||
if (StringUtils.hasText(outFilePath)) {
|
||||
@ -69,25 +66,23 @@ public class OfficeFilePreviewImpl implements FilePreview {
|
||||
}
|
||||
}
|
||||
if (!isHtml && baseUrl != null && (OFFICE_PREVIEW_TYPE_IMAGE.equals(officePreviewType) || OFFICE_PREVIEW_TYPE_ALL_IMAGES.equals(officePreviewType))) {
|
||||
return getPreviewType(model, fileAttribute, officePreviewType, baseUrl, pdfName, outFilePath, pdfUtils, OFFICE_PREVIEW_TYPE_IMAGE);
|
||||
return getPreviewType(model, fileAttribute, officePreviewType, baseUrl, pdfName, outFilePath, fileHandlerService, OFFICE_PREVIEW_TYPE_IMAGE, otherFilePreview);
|
||||
}
|
||||
model.addAttribute("pdfUrl", pdfName);
|
||||
return isHtml ? "html" : "pdf";
|
||||
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, PdfUtils pdfUtils, String officePreviewTypeImage) {
|
||||
List<String> imageUrls = pdfUtils.pdf2jpg(outFilePath, pdfName, baseUrl);
|
||||
static String getPreviewType(Model model, FileAttribute fileAttribute, String officePreviewType, String baseUrl, String pdfName, String outFilePath, FileHandlerService fileHandlerService, String officePreviewTypeImage, OtherFilePreviewImpl otherFilePreview) {
|
||||
List<String> imageUrls = fileHandlerService.pdf2jpg(outFilePath, pdfName, baseUrl);
|
||||
if (imageUrls == null || imageUrls.size() < 1) {
|
||||
model.addAttribute("msg", "office转图片异常,请联系管理员");
|
||||
model.addAttribute("fileType",fileAttribute.getSuffix());
|
||||
return "fileNotSupported";
|
||||
return otherFilePreview.notSupportedFile(model, fileAttribute, "office转图片异常,请联系管理员");
|
||||
}
|
||||
model.addAttribute("imgurls", imageUrls);
|
||||
model.addAttribute("currentUrl", imageUrls.get(0));
|
||||
if (officePreviewTypeImage.equals(officePreviewType)) {
|
||||
return "officePicture";
|
||||
return OFFICE_PICTURE_FILE_PREVIEW_PAGE;
|
||||
} else {
|
||||
return "picture";
|
||||
return PICTURE_FILE_PREVIEW_PAGE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -11,10 +11,21 @@ import org.springframework.ui.Model;
|
||||
*/
|
||||
@Service
|
||||
public class OtherFilePreviewImpl implements FilePreview {
|
||||
|
||||
|
||||
@Override
|
||||
public String filePreviewHandle(String url, Model model, FileAttribute fileAttribute) {
|
||||
model.addAttribute("fileType",fileAttribute.getSuffix());
|
||||
model.addAttribute("msg", "系统还不支持该格式文件的在线预览");
|
||||
return "fileNotSupported";
|
||||
return this.notSupportedFile(model,fileAttribute,"系统还不支持该格式文件的在线预览");
|
||||
}
|
||||
|
||||
/**
|
||||
* 通用的预览失败,导向到不支持的文件响应页面
|
||||
*
|
||||
* @return 页面
|
||||
*/
|
||||
public String notSupportedFile(Model model, FileAttribute fileAttribute, String errMsg) {
|
||||
model.addAttribute("fileType", fileAttribute.getSuffix());
|
||||
model.addAttribute("msg", errMsg);
|
||||
return NOT_SUPPORTED_FILE_PAGE;
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,7 +6,6 @@ import cn.keking.model.ReturnResponse;
|
||||
import cn.keking.service.FilePreview;
|
||||
import cn.keking.utils.DownloadUtils;
|
||||
import cn.keking.service.FileHandlerService;
|
||||
import cn.keking.utils.PdfUtils;
|
||||
import cn.keking.web.filter.BaseUrlFilter;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.ui.Model;
|
||||
@ -21,18 +20,17 @@ import java.util.List;
|
||||
public class PdfFilePreviewImpl implements FilePreview {
|
||||
|
||||
private final FileHandlerService fileHandlerService;
|
||||
private final PdfUtils pdfUtils;
|
||||
private final OtherFilePreviewImpl otherFilePreview;
|
||||
private static final String FILE_DIR = ConfigConstants.getFileDir();
|
||||
|
||||
public PdfFilePreviewImpl(FileHandlerService fileHandlerService, PdfUtils pdfUtils) {
|
||||
public PdfFilePreviewImpl(FileHandlerService fileHandlerService, OtherFilePreviewImpl otherFilePreview) {
|
||||
this.fileHandlerService = fileHandlerService;
|
||||
this.pdfUtils = pdfUtils;
|
||||
this.otherFilePreview = otherFilePreview;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String filePreviewHandle(String url, Model model, FileAttribute fileAttribute) {
|
||||
String suffix=fileAttribute.getSuffix();
|
||||
String fileName=fileAttribute.getName();
|
||||
String fileName = fileAttribute.getName();
|
||||
String officePreviewType = fileAttribute.getOfficePreviewType();
|
||||
String baseUrl = BaseUrlFilter.getBaseUrl();
|
||||
String pdfName = fileName.substring(0, fileName.lastIndexOf(".") + 1) + "pdf";
|
||||
@ -41,10 +39,8 @@ public class PdfFilePreviewImpl implements FilePreview {
|
||||
//当文件不存在时,就去下载
|
||||
if (!fileHandlerService.listConvertedFiles().containsKey(pdfName) || !ConfigConstants.isCacheEnabled()) {
|
||||
ReturnResponse<String> response = DownloadUtils.downLoad(fileAttribute, fileName);
|
||||
if (0 != response.getCode()) {
|
||||
model.addAttribute("fileType", suffix);
|
||||
model.addAttribute("msg", response.getMsg());
|
||||
return "fileNotSupported";
|
||||
if (response.isFailure()) {
|
||||
return otherFilePreview.notSupportedFile(model, fileAttribute, response.getMsg());
|
||||
}
|
||||
outFilePath = response.getContent();
|
||||
if (ConfigConstants.isCacheEnabled()) {
|
||||
@ -52,28 +48,24 @@ public class PdfFilePreviewImpl implements FilePreview {
|
||||
fileHandlerService.addConvertedFile(pdfName, fileHandlerService.getRelativePath(outFilePath));
|
||||
}
|
||||
}
|
||||
List<String> imageUrls = pdfUtils.pdf2jpg(outFilePath, pdfName, baseUrl);
|
||||
List<String> imageUrls = fileHandlerService.pdf2jpg(outFilePath, pdfName, baseUrl);
|
||||
if (imageUrls == null || imageUrls.size() < 1) {
|
||||
model.addAttribute("msg", "pdf转图片异常,请联系管理员");
|
||||
model.addAttribute("fileType",fileAttribute.getSuffix());
|
||||
return "fileNotSupported";
|
||||
return otherFilePreview.notSupportedFile(model, fileAttribute, "pdf转图片异常,请联系管理员");
|
||||
}
|
||||
model.addAttribute("imgurls", imageUrls);
|
||||
model.addAttribute("currentUrl", imageUrls.get(0));
|
||||
if (OfficeFilePreviewImpl.OFFICE_PREVIEW_TYPE_IMAGE.equals(officePreviewType)) {
|
||||
return "officePicture";
|
||||
return OFFICE_PICTURE_FILE_PREVIEW_PAGE;
|
||||
} else {
|
||||
return "picture";
|
||||
return PICTURE_FILE_PREVIEW_PAGE;
|
||||
}
|
||||
} else {
|
||||
// 不是http开头,浏览器不能直接访问,需下载到本地
|
||||
if (url != null && !url.toLowerCase().startsWith("http")) {
|
||||
if (!fileHandlerService.listConvertedFiles().containsKey(pdfName) || !ConfigConstants.isCacheEnabled()) {
|
||||
ReturnResponse<String> response = DownloadUtils.downLoad(fileAttribute, pdfName);
|
||||
if (0 != response.getCode()) {
|
||||
model.addAttribute("fileType", suffix);
|
||||
model.addAttribute("msg", response.getMsg());
|
||||
return "fileNotSupported";
|
||||
if (response.isFailure()) {
|
||||
return otherFilePreview.notSupportedFile(model, fileAttribute, response.getMsg());
|
||||
}
|
||||
model.addAttribute("pdfUrl", fileHandlerService.getRelativePath(response.getContent()));
|
||||
if (ConfigConstants.isCacheEnabled()) {
|
||||
@ -87,6 +79,6 @@ public class PdfFilePreviewImpl implements FilePreview {
|
||||
model.addAttribute("pdfUrl", url);
|
||||
}
|
||||
}
|
||||
return "pdf";
|
||||
return PDF_FILE_PREVIEW_PAGE;
|
||||
}
|
||||
}
|
||||
|
||||
@ -19,9 +19,11 @@ import java.util.List;
|
||||
public class PictureFilePreviewImpl implements FilePreview {
|
||||
|
||||
private final FileHandlerService fileHandlerService;
|
||||
private final OtherFilePreviewImpl otherFilePreview;
|
||||
|
||||
public PictureFilePreviewImpl(FileHandlerService fileHandlerService) {
|
||||
public PictureFilePreviewImpl(FileHandlerService fileHandlerService, OtherFilePreviewImpl otherFilePreview) {
|
||||
this.fileHandlerService = fileHandlerService;
|
||||
this.otherFilePreview = otherFilePreview;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -36,10 +38,8 @@ public class PictureFilePreviewImpl implements FilePreview {
|
||||
// 不是http开头,浏览器不能直接访问,需下载到本地
|
||||
if (url != null && !url.toLowerCase().startsWith("http")) {
|
||||
ReturnResponse<String> response = DownloadUtils.downLoad(fileAttribute, null);
|
||||
if (0 != response.getCode()) {
|
||||
model.addAttribute("fileType", fileAttribute.getSuffix());
|
||||
model.addAttribute("msg", response.getMsg());
|
||||
return "fileNotSupported";
|
||||
if (response.isFailure()) {
|
||||
return otherFilePreview.notSupportedFile(model, fileAttribute, response.getMsg());
|
||||
} else {
|
||||
String file = fileHandlerService.getRelativePath(response.getContent());
|
||||
imgUrls.clear();
|
||||
@ -51,6 +51,6 @@ public class PictureFilePreviewImpl implements FilePreview {
|
||||
model.addAttribute("imgurls", imgUrls);
|
||||
model.addAttribute("currentUrl", url);
|
||||
}
|
||||
return "picture";
|
||||
return PICTURE_FILE_PREVIEW_PAGE;
|
||||
}
|
||||
}
|
||||
|
||||
@ -23,28 +23,30 @@ public class SimTextFilePreviewImpl implements FilePreview {
|
||||
public static final String TEXT_TYPE = "textType";
|
||||
public static final String DEFAULT_TEXT_TYPE = "simText";
|
||||
|
||||
private final OtherFilePreviewImpl otherFilePreview;
|
||||
|
||||
public SimTextFilePreviewImpl(OtherFilePreviewImpl otherFilePreview) {
|
||||
this.otherFilePreview = otherFilePreview;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String filePreviewHandle(String url, Model model, FileAttribute fileAttribute) {
|
||||
String fileName = fileAttribute.getName();
|
||||
ReturnResponse<String> response = DownloadUtils.downLoad(fileAttribute, fileName);
|
||||
if (0 != response.getCode()) {
|
||||
model.addAttribute("msg", response.getMsg());
|
||||
model.addAttribute("fileType", fileAttribute.getSuffix());
|
||||
return "fileNotSupported";
|
||||
if (response.isFailure()) {
|
||||
return otherFilePreview.notSupportedFile(model, fileAttribute, response.getMsg());
|
||||
}
|
||||
try {
|
||||
File originFile = new File(response.getContent());
|
||||
String xmlString = FileUtils.readFileToString(originFile, StandardCharsets.UTF_8);
|
||||
model.addAttribute("textData", Base64Utils.encodeToString(xmlString.getBytes()));
|
||||
} catch (IOException e) {
|
||||
model.addAttribute("msg", e.getLocalizedMessage());
|
||||
model.addAttribute("fileType", fileAttribute.getSuffix());
|
||||
return "fileNotSupported";
|
||||
return otherFilePreview.notSupportedFile(model, fileAttribute, e.getLocalizedMessage());
|
||||
}
|
||||
if (!model.containsAttribute(TEXT_TYPE)) {
|
||||
model.addAttribute(TEXT_TYPE, DEFAULT_TEXT_TYPE);
|
||||
}
|
||||
return "txt";
|
||||
return TXT_FILE_PREVIEW_PAGE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -20,7 +20,6 @@ public class XmlFilePreviewImpl implements FilePreview {
|
||||
this.simTextFilePreview = simTextFilePreview;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String filePreviewHandle(String url, Model model, FileAttribute fileAttribute) {
|
||||
model.addAttribute(TEXT_TYPE,"xml");
|
||||
|
||||
@ -1,50 +0,0 @@
|
||||
package cn.keking.utils;
|
||||
|
||||
import com.aspose.cad.Color;
|
||||
import com.aspose.cad.fileformats.cad.CadDrawTypeMode;
|
||||
import com.aspose.cad.imageoptions.CadRasterizationOptions;
|
||||
import com.aspose.cad.imageoptions.PdfOptions;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
* @author chenjhc
|
||||
* @since 2019/11/21 14:34
|
||||
*/
|
||||
@Component
|
||||
public class CadUtils {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(CadUtils.class);
|
||||
|
||||
public boolean cadToPdf(String inputFilePath, String outputFilePath) {
|
||||
com.aspose.cad.Image cadImage = com.aspose.cad.Image.load(inputFilePath);
|
||||
CadRasterizationOptions cadRasterizationOptions = new CadRasterizationOptions();
|
||||
cadRasterizationOptions.setLayouts(new String[]{"Model"});
|
||||
cadRasterizationOptions.setNoScaling(true);
|
||||
cadRasterizationOptions.setBackgroundColor(Color.getWhite());
|
||||
cadRasterizationOptions.setPageWidth(cadImage.getWidth());
|
||||
cadRasterizationOptions.setPageHeight(cadImage.getHeight());
|
||||
cadRasterizationOptions.setPdfProductLocation("center");
|
||||
cadRasterizationOptions.setAutomaticLayoutsScaling(true);
|
||||
cadRasterizationOptions.setDrawType(CadDrawTypeMode.UseObjectColor);
|
||||
PdfOptions pdfOptions = new PdfOptions();
|
||||
pdfOptions.setVectorRasterizationOptions(cadRasterizationOptions);
|
||||
File outputFile = new File(outputFilePath);
|
||||
OutputStream stream;
|
||||
try {
|
||||
stream = new FileOutputStream(outputFile);
|
||||
cadImage.save(stream, pdfOptions);
|
||||
cadImage.close();
|
||||
return true;
|
||||
} catch (FileNotFoundException e) {
|
||||
logger.error("PDFFileNotFoundException,inputFilePath:{}", inputFilePath, e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -57,6 +57,16 @@ public class FileUtils {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过文件名获取文件后缀
|
||||
* @param fileName 文件名称
|
||||
* @return 文件后缀
|
||||
*/
|
||||
public static String suffixFromFileName(String fileName) {
|
||||
return fileName.substring(fileName.lastIndexOf(".") + 1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据文件路径删除文件
|
||||
*
|
||||
|
||||
@ -1,79 +0,0 @@
|
||||
package cn.keking.utils;
|
||||
|
||||
import cn.keking.service.FileHandlerService;
|
||||
import org.apache.pdfbox.pdmodel.PDDocument;
|
||||
import org.apache.pdfbox.rendering.ImageType;
|
||||
import org.apache.pdfbox.rendering.PDFRenderer;
|
||||
import org.apache.pdfbox.tools.imageio.ImageIOUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
public class PdfUtils {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(PdfUtils.class);
|
||||
|
||||
private final FileHandlerService fileHandlerService;
|
||||
|
||||
@Value("${server.tomcat.uri-encoding:UTF-8}")
|
||||
private String uriEncoding;
|
||||
|
||||
public PdfUtils(FileHandlerService fileHandlerService) {
|
||||
this.fileHandlerService = fileHandlerService;
|
||||
}
|
||||
|
||||
public List<String> pdf2jpg(String pdfFilePath, String pdfName, String baseUrl) {
|
||||
List<String> imageUrls = new ArrayList<>();
|
||||
Integer imageCount = fileHandlerService.getConvertedPdfImage(pdfFilePath);
|
||||
String imageFileSuffix = ".jpg";
|
||||
String pdfFolder = pdfName.substring(0, pdfName.length() - 4);
|
||||
String urlPrefix = null;
|
||||
try {
|
||||
urlPrefix = baseUrl + URLEncoder.encode(URLEncoder.encode(pdfFolder, uriEncoding).replaceAll("\\+", "%20"), uriEncoding);
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
logger.error("UnsupportedEncodingException", e);
|
||||
urlPrefix = baseUrl + pdfFolder;
|
||||
}
|
||||
if (imageCount != null && imageCount > 0) {
|
||||
for (int i = 0; i < imageCount ; i++)
|
||||
imageUrls.add(urlPrefix + "/" + i + imageFileSuffix);
|
||||
return imageUrls;
|
||||
}
|
||||
try {
|
||||
File pdfFile = new File(pdfFilePath);
|
||||
PDDocument doc = PDDocument.load(pdfFile);
|
||||
int pageCount = doc.getNumberOfPages();
|
||||
PDFRenderer pdfRenderer = new PDFRenderer(doc);
|
||||
|
||||
int index = pdfFilePath.lastIndexOf(".");
|
||||
String folder = pdfFilePath.substring(0, index);
|
||||
|
||||
File path = new File(folder);
|
||||
if (!path.exists()) {
|
||||
path.mkdirs();
|
||||
}
|
||||
String imageFilePath;
|
||||
for (int pageIndex = 0; pageIndex < pageCount; pageIndex++) {
|
||||
imageFilePath = folder + File.separator + pageIndex + imageFileSuffix;
|
||||
BufferedImage image = pdfRenderer.renderImageWithDPI(pageIndex, 105, ImageType.RGB);
|
||||
ImageIOUtil.writeImage(image, imageFilePath, 105);
|
||||
imageUrls.add(urlPrefix + "/" + pageIndex + imageFileSuffix);
|
||||
}
|
||||
doc.close();
|
||||
fileHandlerService.addConvertedPdfImage(pdfFilePath, pageCount);
|
||||
} catch (IOException e) {
|
||||
logger.error("Convert pdf to jpg exception, pdfFilePath:{}", pdfFilePath, e);
|
||||
}
|
||||
return imageUrls;
|
||||
}
|
||||
}
|
||||
@ -57,4 +57,30 @@ public class WebUtils {
|
||||
}
|
||||
return strAllParam;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从url中剥离出文件名
|
||||
*
|
||||
* @param url 格式如:http://www.com.cn/20171113164107_月度绩效表模板(新).xls?UCloudPublicKey=ucloudtangshd@weifenf.com14355492830001993909323&Expires=&Signature=I D1NOFtAJSPT16E6imv6JWuq0k=
|
||||
* @return 文件名
|
||||
*/
|
||||
public static String getFileNameFromURL(String url) {
|
||||
// 因为url的参数中可能会存在/的情况,所以直接url.lastIndexOf("/")会有问题
|
||||
// 所以先从?处将url截断,然后运用url.lastIndexOf("/")获取文件名
|
||||
String noQueryUrl = url.substring(0, url.contains("?") ? url.indexOf("?") : url.length());
|
||||
return noQueryUrl.substring(noQueryUrl.lastIndexOf("/") + 1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 从url中获取文件后缀
|
||||
*
|
||||
* @param url url
|
||||
* @return 文件后缀
|
||||
*/
|
||||
public static String suffixFromUrl(String url) {
|
||||
String nonPramStr = url.substring(0, url.contains("?") ? url.indexOf("?") : url.length());
|
||||
String fileName = nonPramStr.substring(nonPramStr.lastIndexOf("/") + 1);
|
||||
return FileUtils.suffixFromFileName(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@ -28,9 +28,7 @@ public class FileController {
|
||||
private final Logger logger = LoggerFactory.getLogger(FileController.class);
|
||||
|
||||
private final String fileDir = ConfigConstants.getFileDir();
|
||||
|
||||
private final String demoDir = "demo";
|
||||
|
||||
private final String demoPath = demoDir + File.separator;
|
||||
|
||||
@RequestMapping(value = "fileUpload", method = RequestMethod.POST)
|
||||
@ -49,7 +47,7 @@ public class FileController {
|
||||
}
|
||||
// 判断是否存在同名文件
|
||||
if (existsFile(fileName)) {
|
||||
return new ObjectMapper().writeValueAsString(new ReturnResponse<String>(1, "存在同名文件,请先删除原有文件再次上传", null));
|
||||
return new ObjectMapper().writeValueAsString(ReturnResponse.failure("存在同名文件,请先删除原有文件再次上传"));
|
||||
}
|
||||
File outFile = new File(fileDir + demoPath);
|
||||
if (!outFile.exists() && !outFile.mkdirs()) {
|
||||
@ -58,10 +56,10 @@ public class FileController {
|
||||
logger.info("上传文件:{}", fileDir + demoPath + fileName);
|
||||
try(InputStream in = file.getInputStream(); OutputStream out = new FileOutputStream(fileDir + demoPath + fileName)) {
|
||||
StreamUtils.copy(in, out);
|
||||
return new ObjectMapper().writeValueAsString(new ReturnResponse<String>(0, "SUCCESS", null));
|
||||
return new ObjectMapper().writeValueAsString(ReturnResponse.success(null));
|
||||
} catch (IOException e) {
|
||||
logger.error("文件上传失败", e);
|
||||
return new ObjectMapper().writeValueAsString(new ReturnResponse<String>(1, "FAILURE", null));
|
||||
return new ObjectMapper().writeValueAsString(ReturnResponse.failure());
|
||||
}
|
||||
}
|
||||
|
||||
@ -75,7 +73,7 @@ public class FileController {
|
||||
if (file.exists() && !file.delete()) {
|
||||
logger.error("删除文件【{}】失败,请检查目录权限!",file.getPath());
|
||||
}
|
||||
return new ObjectMapper().writeValueAsString(new ReturnResponse<String>(0, "SUCCESS", null));
|
||||
return new ObjectMapper().writeValueAsString(ReturnResponse.success());
|
||||
}
|
||||
|
||||
@RequestMapping(value = "listFiles", method = RequestMethod.GET)
|
||||
|
||||
@ -7,12 +7,12 @@ import cn.keking.service.FilePreviewFactory;
|
||||
import cn.keking.service.cache.CacheService;
|
||||
import cn.keking.utils.DownloadUtils;
|
||||
import cn.keking.service.FileHandlerService;
|
||||
import com.thoughtworks.xstream.core.util.Base64JavaUtilCodec;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.util.Base64Utils;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
@ -20,10 +20,11 @@ import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.*;
|
||||
import java.net.URLDecoder;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.keking.service.FilePreview.PICTURE_FILE_PREVIEW_PAGE;
|
||||
|
||||
/**
|
||||
* @author yudian-it
|
||||
*/
|
||||
@ -45,26 +46,27 @@ public class OnlinePreviewController {
|
||||
@RequestMapping(value = "/onlinePreview")
|
||||
public String onlinePreview(String url, Model model, HttpServletRequest req) {
|
||||
String fileUrl = new String(Base64Utils.decodeFromString(url));
|
||||
FileAttribute fileAttribute = fileHandlerService.getFileAttribute(fileUrl,req);
|
||||
FileAttribute fileAttribute = fileHandlerService.getFileAttribute(fileUrl, req);
|
||||
FilePreview filePreview = previewFactory.get(fileAttribute);
|
||||
logger.info("预览文件url:{},previewType:{}", fileUrl, fileAttribute.getType());
|
||||
return filePreview.filePreviewHandle(fileUrl, model, fileAttribute);
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/picturesPreview")
|
||||
public String picturesPreview(Model model, HttpServletRequest req) throws UnsupportedEncodingException {
|
||||
String urls = req.getParameter("urls");
|
||||
String currentUrl = req.getParameter("currentUrl");
|
||||
logger.info("预览文件url:{},urls:{}", currentUrl, urls);
|
||||
// 路径转码
|
||||
String decodedUrl = URLDecoder.decode(urls, "utf-8");
|
||||
String decodedCurrentUrl = URLDecoder.decode(currentUrl, "utf-8");
|
||||
public String picturesPreview(String urls, Model model, HttpServletRequest req) throws UnsupportedEncodingException {
|
||||
String fileUrls = new String(Base64Utils.decodeFromString(urls));
|
||||
logger.info("预览文件url:{},urls:{}", fileUrls, urls);
|
||||
// 抽取文件并返回文件列表
|
||||
String[] imgs = decodedUrl.split("\\|");
|
||||
String[] imgs = fileUrls.split("\\|");
|
||||
List<String> imgUrls = Arrays.asList(imgs);
|
||||
model.addAttribute("imgUrls", imgUrls);
|
||||
model.addAttribute("currentUrl",decodedCurrentUrl);
|
||||
return "picture";
|
||||
|
||||
String currentUrl = req.getParameter("currentUrl");
|
||||
if(StringUtils.hasText(currentUrl)){
|
||||
String decodedCurrentUrl = new String(Base64Utils.decodeFromString(currentUrl));
|
||||
model.addAttribute("currentUrl", decodedCurrentUrl);
|
||||
}
|
||||
return PICTURE_FILE_PREVIEW_PAGE;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -87,6 +89,7 @@ public class OnlinePreviewController {
|
||||
|
||||
/**
|
||||
* 通过api接口入队
|
||||
*
|
||||
* @param url 请编码后在入队
|
||||
*/
|
||||
@RequestMapping("/addTask")
|
||||
|
||||
@ -85,6 +85,24 @@ window.open('http://127.0.0.1:8012/picturesPreview?urls='+encodeURIComponent(bas
|
||||
<div id="collapseThree" class="panel-collapse collapse in">
|
||||
<div class="panel-body">
|
||||
<div>
|
||||
2020年12月27日 :<br>
|
||||
2020年年终大版本更新,架构全面设计,代码全面重构,代码质量全面提升,二次开发更便捷,欢迎拉源码品鉴,提issue、pr共同建设
|
||||
1. 架构模块调整,大量的代码重构,代码质量提升N个等级,欢迎品鉴<br>
|
||||
2. 增强XML文件预览效果,新增XML文档数结构预览<br>
|
||||
3. 新增markdown文件预览支持,预览支持md渲染和源文本切换支持<br>
|
||||
4. 切换底层web server为jetty,解决这个issue:<a href="https://github.com/kekingcn/kkFileView/issues/168">#issues/168</a><br>
|
||||
5. 引入cpdetector,解决文件编码识别问题<br>
|
||||
6. url采用base64+urlencode双编码,彻底解决各种奇葩文件名预览问题<br>
|
||||
7. 新增配置项office.preview.switch.disabled,控制offic文件预览切换开关<br>
|
||||
8. 优化文本类型文件预览逻辑,采用Base64传输内容,避免预览时再次请求文件内容<br>
|
||||
9. office预览图片模式禁用图片放大效果,达到图片和pdf预览效果一致的体验<br>
|
||||
10. 直接代码静态设置pdfbox兼容低版本jdk,在IDEA中运行也不会有警告提示<br>
|
||||
11. 移除guava、hutool等非必须的工具包,减少代码体积<br>
|
||||
12. Office组件加载异步化,提速应用启动速度最快到5秒内<br>
|
||||
13. 合理设置预览消费队列的线程数<br>
|
||||
14. 修复压缩包里文件再次预览失败的bug<br>
|
||||
15. 修复图片预览的bug<br><br>
|
||||
|
||||
2020年05月20日 :<br>
|
||||
1. 新增支持全局水印,并支持通过参数动态改变水印内容<br>
|
||||
2. 新增支持CAD文件预览<br>
|
||||
|
||||
Reference in New Issue
Block a user