mirror of
https://gitee.com/kekingcn/file-online-preview.git
synced 2026-04-30 12:06:46 +00:00
Compare commits
47 Commits
klboke-pat
...
v4.2.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
523623698a | ||
|
|
f714dffe70 | ||
|
|
7a9ad7546c | ||
|
|
138e58a1e1 | ||
|
|
55ca17203f | ||
|
|
8916bee786 | ||
|
|
c055d3d992 | ||
|
|
7b699e08fc | ||
|
|
c7367dfcec | ||
|
|
75a46a14a8 | ||
|
|
181897ec5a | ||
|
|
e5e9611646 | ||
|
|
78d517a16e | ||
|
|
e855c9c7ed | ||
|
|
195f56e9b9 | ||
|
|
888e550453 | ||
|
|
f771d361ae | ||
|
|
2cd23b06f1 | ||
|
|
75e568e15f | ||
|
|
60b91eb79f | ||
|
|
dd7a6465aa | ||
|
|
4cd6a4e4b9 | ||
|
|
3942346f49 | ||
|
|
e697c255fc | ||
|
|
65fa326262 | ||
|
|
81043034f9 | ||
|
|
6c5bceba41 | ||
|
|
b524963892 | ||
|
|
dd4997cedc | ||
|
|
ead5505d53 | ||
|
|
bf6cee4a6a | ||
|
|
bd458bfbe9 | ||
|
|
7895597176 | ||
|
|
a44e5ba518 | ||
|
|
cc7da00001 | ||
|
|
41449aeea6 | ||
|
|
33277bc457 | ||
|
|
f2cfb4cf4a | ||
|
|
d646d72a26 | ||
|
|
1807dbd615 | ||
|
|
1e771ed649 | ||
|
|
83d04ca45d | ||
|
|
ee2dadb40d | ||
|
|
c9eb51213f | ||
|
|
81f28baabf | ||
|
|
1245e9f327 | ||
|
|
007889339b |
@@ -1,5 +1,5 @@
|
|||||||
FROM keking/kkfileview-jdk:4.1.1
|
FROM keking/kkfileview-jdk:4.1.1
|
||||||
MAINTAINER chenjh "842761733@qq.com"
|
MAINTAINER chenjh "842761733@qq.com"
|
||||||
ADD server/target/kkFileView-*.tar.gz /opt/
|
ADD server/target/kkFileView-*.tar.gz /opt/
|
||||||
ENV KKFILEVIEW_BIN_FOLDER /opt/kkFileView-4.2.0-SNAPSHOT/bin
|
ENV KKFILEVIEW_BIN_FOLDER /opt/kkFileView-4.2.0/bin
|
||||||
ENTRYPOINT ["java","-Dfile.encoding=UTF-8","-Dspring.config.location=/opt/kkFileView-4.2.0-SNAPSHOT/config/application.properties","-jar","/opt/kkFileView-4.2.0-SNAPSHOT/bin/kkFileView-4.2.0-SNAPSHOT.jar"]
|
ENTRYPOINT ["java","-Dfile.encoding=UTF-8","-Dspring.config.location=/opt/kkFileView-4.2.0/config/application.properties","-jar","/opt/kkFileView-4.2.0/bin/kkFileView-4.2.0.jar"]
|
||||||
|
|||||||
@@ -47,8 +47,7 @@
|
|||||||
### 联系我们,加入组织
|
### 联系我们,加入组织
|
||||||
> 我们会用心回答解决大家在项目使用中的问题,也请大家在提问前至少 Google 或 baidu 过,珍爱生命远离无效的交流沟通
|
> 我们会用心回答解决大家在项目使用中的问题,也请大家在提问前至少 Google 或 baidu 过,珍爱生命远离无效的交流沟通
|
||||||
|
|
||||||

|
<img src="./doc/gitee星球.png/" width="60%">
|
||||||
|
|
||||||
|
|
||||||
### 文档预览效果
|
### 文档预览效果
|
||||||
#### 1. 文本预览
|
#### 1. 文本预览
|
||||||
|
|||||||
BIN
doc/gitee星球.png
BIN
doc/gitee星球.png
Binary file not shown.
|
Before Width: | Height: | Size: 92 KiB After Width: | Height: | Size: 156 KiB |
4
pom.xml
4
pom.xml
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
<groupId>cn.keking</groupId>
|
<groupId>cn.keking</groupId>
|
||||||
<artifactId>kkFileView-parent</artifactId>
|
<artifactId>kkFileView-parent</artifactId>
|
||||||
<version>4.2.0-SNAPSHOT</version>
|
<version>4.2.0</version>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<java.version>1.8</java.version>
|
<java.version>1.8</java.version>
|
||||||
@@ -31,7 +31,7 @@
|
|||||||
<opencv.version>4.1.2-1.5.2</opencv.version>
|
<opencv.version>4.1.2-1.5.2</opencv.version>
|
||||||
<openblas.version>0.3.6-1.5.1</openblas.version>
|
<openblas.version>0.3.6-1.5.1</openblas.version>
|
||||||
<ffmpeg.version>4.2.1-1.5.2</ffmpeg.version>
|
<ffmpeg.version>4.2.1-1.5.2</ffmpeg.version>
|
||||||
<itext.version>2.1.7</itext.version>
|
<itextpdf.version>5.5.13.3</itextpdf.version>
|
||||||
<httpclient.version>3.1</httpclient.version>
|
<httpclient.version>3.1</httpclient.version>
|
||||||
|
|
||||||
<commons-cli.version>1.2</commons-cli.version>
|
<commons-cli.version>1.2</commons-cli.version>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>kkFileView-parent</artifactId>
|
<artifactId>kkFileView-parent</artifactId>
|
||||||
<groupId>cn.keking</groupId>
|
<groupId>cn.keking</groupId>
|
||||||
<version>4.2.0-SNAPSHOT</version>
|
<version>4.2.0</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>kkFileView</artifactId>
|
<artifactId>kkFileView</artifactId>
|
||||||
@@ -244,10 +244,10 @@
|
|||||||
<classifier>windows-x86_64</classifier>
|
<classifier>windows-x86_64</classifier>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.lowagie</groupId>
|
<groupId>com.itextpdf</groupId>
|
||||||
<artifactId>itext</artifactId>
|
<artifactId>itextpdf</artifactId>
|
||||||
<version>${itext.version}</version>
|
<version>${itextpdf.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>javax.media</groupId>
|
<groupId>javax.media</groupId>
|
||||||
|
|||||||
@@ -7,4 +7,4 @@ echo Please check log file in ../log/kkFileView.log for more information
|
|||||||
echo You can get help in our official home site: https://kkview.cn
|
echo You can get help in our official home site: https://kkview.cn
|
||||||
echo If you need further help, please join our kk opensource community: https://t.zsxq.com/09ZHSXbsQ
|
echo If you need further help, please join our kk opensource community: https://t.zsxq.com/09ZHSXbsQ
|
||||||
echo If this project is helpful to you, please star it on https://gitee.com/kekingcn/file-online-preview/stargazers
|
echo If this project is helpful to you, please star it on https://gitee.com/kekingcn/file-online-preview/stargazers
|
||||||
java -Dspring.config.location=..\config\application.properties -jar kkFileView-4.2.0-SNAPSHOT.jar -> ..\log\kkFileView.log
|
java -Dspring.config.location=..\config\application.properties -jar kkFileView-4.2.0.jar -> ..\log\kkFileView.log
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ else
|
|||||||
|
|
||||||
## 启动kkFileView
|
## 启动kkFileView
|
||||||
echo "Starting kkFileView..."
|
echo "Starting kkFileView..."
|
||||||
nohup java -Dfile.encoding=UTF-8 -Dspring.config.location=../config/application.properties -jar kkFileView-4.2.0-SNAPSHOT.jar > ../log/kkFileView.log 2>&1 &
|
nohup java -Dfile.encoding=UTF-8 -Dspring.config.location=../config/application.properties -jar kkFileView-4.2.0.jar > ../log/kkFileView.log 2>&1 &
|
||||||
echo "Please execute ./showlog.sh to check log for more information"
|
echo "Please execute ./showlog.sh to check log for more information"
|
||||||
echo "You can get help in our official home site: https://kkview.cn"
|
echo "You can get help in our official home site: https://kkview.cn"
|
||||||
echo "If you need further help, please join our kk opensource community: https://t.zsxq.com/09ZHSXbsQ"
|
echo "If you need further help, please join our kk opensource community: https://t.zsxq.com/09ZHSXbsQ"
|
||||||
|
|||||||
@@ -2,8 +2,9 @@
|
|||||||
server.port = ${KK_SERVER_PORT:8012}
|
server.port = ${KK_SERVER_PORT:8012}
|
||||||
server.servlet.context-path= ${KK_CONTEXT_PATH:/}
|
server.servlet.context-path= ${KK_CONTEXT_PATH:/}
|
||||||
server.servlet.encoding.charset = utf-8
|
server.servlet.encoding.charset = utf-8
|
||||||
#文件上传限制
|
#文件上传限制前端
|
||||||
spring.servlet.multipart.max-file-size=500MB
|
spring.servlet.multipart.max-file-size=500MB
|
||||||
|
#文件上传限制
|
||||||
spring.servlet.multipart.max-request-size=500MB
|
spring.servlet.multipart.max-request-size=500MB
|
||||||
## Freemarker 配置
|
## Freemarker 配置
|
||||||
spring.freemarker.template-loader-path = classpath:/web/
|
spring.freemarker.template-loader-path = classpath:/web/
|
||||||
@@ -117,3 +118,9 @@ watermark.angle = ${WATERMARK_ANGLE:10}
|
|||||||
#Tif类型图片浏览模式:tif(利用前端js插件浏览);jpg(转换为jpg后前端显示);pdf(转换为pdf后显示,便于打印)
|
#Tif类型图片浏览模式:tif(利用前端js插件浏览);jpg(转换为jpg后前端显示);pdf(转换为pdf后显示,便于打印)
|
||||||
tif.preview.type = ${KK_TIF_PREVIEW_TYPE:tif}
|
tif.preview.type = ${KK_TIF_PREVIEW_TYPE:tif}
|
||||||
|
|
||||||
|
# 备案信息
|
||||||
|
BeiAn =
|
||||||
|
#禁止上传类型
|
||||||
|
prohibit =exe,dll,dat
|
||||||
|
#删除密码
|
||||||
|
sc.password =123456
|
||||||
|
|||||||
@@ -42,6 +42,10 @@ public class ConfigConstants {
|
|||||||
private static String pdfBookmarkDisable;
|
private static String pdfBookmarkDisable;
|
||||||
private static Boolean fileUploadDisable;
|
private static Boolean fileUploadDisable;
|
||||||
private static String tifPreviewType;
|
private static String tifPreviewType;
|
||||||
|
private static String BeiAn;
|
||||||
|
private static String[] prohibit= {};
|
||||||
|
private static String size;
|
||||||
|
private static String password;
|
||||||
|
|
||||||
public static final String DEFAULT_CACHE_ENABLED = "true";
|
public static final String DEFAULT_CACHE_ENABLED = "true";
|
||||||
public static final String DEFAULT_TXT_TYPE = "txt,html,htm,asp,jsp,xml,json,properties,md,gitignore,log,java,py,c,cpp,sql,sh,bat,m,bas,prg,cmd";
|
public static final String DEFAULT_TXT_TYPE = "txt,html,htm,asp,jsp,xml,json,properties,md,gitignore,log,java,py,c,cpp,sql,sh,bat,m,bas,prg,cmd";
|
||||||
@@ -62,6 +66,10 @@ public class ConfigConstants {
|
|||||||
public static final String DEFAULT_PDF_BOOKMARK_DISABLE = "true";
|
public static final String DEFAULT_PDF_BOOKMARK_DISABLE = "true";
|
||||||
public static final String DEFAULT_FILE_UPLOAD_DISABLE = "false";
|
public static final String DEFAULT_FILE_UPLOAD_DISABLE = "false";
|
||||||
public static final String DEFAULT_TIF_PREVIEW_TYPE = "tif";
|
public static final String DEFAULT_TIF_PREVIEW_TYPE = "tif";
|
||||||
|
public static final String DEFAULT_BeiAn_DISABLE = "无";
|
||||||
|
public static final String DEFAULT_size_DISABLE = "500MB";
|
||||||
|
public static final String DEFAULT_prohibit_DISABLE = "exe,dll";
|
||||||
|
public static final String DEFAULT_password_DISABLE = "123456";
|
||||||
|
|
||||||
public static Boolean isCacheEnabled() {
|
public static Boolean isCacheEnabled() {
|
||||||
return cacheEnabled;
|
return cacheEnabled;
|
||||||
@@ -353,4 +361,49 @@ public class ConfigConstants {
|
|||||||
public static void setTifPreviewTypeValue(String tifPreviewType) {
|
public static void setTifPreviewTypeValue(String tifPreviewType) {
|
||||||
ConfigConstants.tifPreviewType = tifPreviewType;
|
ConfigConstants.tifPreviewType = tifPreviewType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String getBeiAn() {
|
||||||
|
return BeiAn;
|
||||||
|
}
|
||||||
|
@Value("${BeiAn:无}")
|
||||||
|
public void setBeiAn(String BeiAn) {
|
||||||
|
setBeiAnValue(BeiAn);
|
||||||
|
}
|
||||||
|
public static void setBeiAnValue(String BeiAn) {
|
||||||
|
ConfigConstants.BeiAn = BeiAn;
|
||||||
|
}
|
||||||
|
public static String[] getprohibit() {
|
||||||
|
return prohibit;
|
||||||
|
}
|
||||||
|
@Value("${prohibit:exe,dll}")
|
||||||
|
public void setprohibit(String prohibit) {
|
||||||
|
String[] prohibittArr = prohibit.split(",");
|
||||||
|
setprohibitValue(prohibittArr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setprohibitValue(String[] prohibit) {
|
||||||
|
ConfigConstants.prohibit = prohibit;
|
||||||
|
}
|
||||||
|
public static String maxsize() {
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
@Value("${spring.servlet.multipart.max-file-size:500MB}")
|
||||||
|
public void setsize(String size) {
|
||||||
|
setsizeValue(size);
|
||||||
|
}
|
||||||
|
public static void setsizeValue(String size) {
|
||||||
|
ConfigConstants.size = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getpassword() {
|
||||||
|
return password;
|
||||||
|
}
|
||||||
|
@Value("${sc.password:123456}")
|
||||||
|
public void setpassword(String password) {
|
||||||
|
setpasswordValue(password);
|
||||||
|
}
|
||||||
|
public static void setpasswordValue(String password) {
|
||||||
|
ConfigConstants.password = password;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,7 +53,11 @@ public class ConfigRefreshComponent {
|
|||||||
String pdfBookmarkDisable;
|
String pdfBookmarkDisable;
|
||||||
boolean fileUploadDisable;
|
boolean fileUploadDisable;
|
||||||
String tifPreviewType;
|
String tifPreviewType;
|
||||||
|
String prohibit;
|
||||||
|
String[] prohibitArray;
|
||||||
|
String BeiAn;
|
||||||
|
String size;
|
||||||
|
String password;
|
||||||
while (true) {
|
while (true) {
|
||||||
FileReader fileReader = new FileReader(configFilePath);
|
FileReader fileReader = new FileReader(configFilePath);
|
||||||
BufferedReader bufferedReader = new BufferedReader(fileReader);
|
BufferedReader bufferedReader = new BufferedReader(fileReader);
|
||||||
@@ -78,6 +82,11 @@ public class ConfigRefreshComponent {
|
|||||||
pdfBookmarkDisable = properties.getProperty("pdf.bookmark.disable", ConfigConstants.DEFAULT_PDF_BOOKMARK_DISABLE);
|
pdfBookmarkDisable = properties.getProperty("pdf.bookmark.disable", ConfigConstants.DEFAULT_PDF_BOOKMARK_DISABLE);
|
||||||
fileUploadDisable = Boolean.parseBoolean(properties.getProperty("file.upload.disable", ConfigConstants.DEFAULT_FILE_UPLOAD_DISABLE));
|
fileUploadDisable = Boolean.parseBoolean(properties.getProperty("file.upload.disable", ConfigConstants.DEFAULT_FILE_UPLOAD_DISABLE));
|
||||||
tifPreviewType = properties.getProperty("tif.preview.type", ConfigConstants.DEFAULT_TIF_PREVIEW_TYPE);
|
tifPreviewType = properties.getProperty("tif.preview.type", ConfigConstants.DEFAULT_TIF_PREVIEW_TYPE);
|
||||||
|
size = properties.getProperty("spring.servlet.multipart.max-file-size", ConfigConstants.DEFAULT_size_DISABLE);
|
||||||
|
BeiAn = properties.getProperty("BeiAn", ConfigConstants.DEFAULT_BeiAn_DISABLE);
|
||||||
|
prohibit = properties.getProperty("prohibit", ConfigConstants.DEFAULT_prohibit_DISABLE);
|
||||||
|
password = properties.getProperty("sc.password", ConfigConstants.DEFAULT_password_DISABLE);
|
||||||
|
prohibitArray = prohibit.split(",");
|
||||||
|
|
||||||
ConfigConstants.setCacheEnabledValueValue(cacheEnabled);
|
ConfigConstants.setCacheEnabledValueValue(cacheEnabled);
|
||||||
ConfigConstants.setSimTextValue(textArray);
|
ConfigConstants.setSimTextValue(textArray);
|
||||||
@@ -96,6 +105,10 @@ public class ConfigRefreshComponent {
|
|||||||
ConfigConstants.setPdfBookmarkDisableValue(pdfBookmarkDisable);
|
ConfigConstants.setPdfBookmarkDisableValue(pdfBookmarkDisable);
|
||||||
ConfigConstants.setFileUploadDisableValue(fileUploadDisable);
|
ConfigConstants.setFileUploadDisableValue(fileUploadDisable);
|
||||||
ConfigConstants.setTifPreviewTypeValue(tifPreviewType);
|
ConfigConstants.setTifPreviewTypeValue(tifPreviewType);
|
||||||
|
ConfigConstants.setBeiAnValue(BeiAn);
|
||||||
|
ConfigConstants.setsizeValue(size);
|
||||||
|
ConfigConstants.setprohibitValue(prohibitArray);
|
||||||
|
ConfigConstants.setpasswordValue(password);
|
||||||
setWatermarkConfig(properties);
|
setWatermarkConfig(properties);
|
||||||
bufferedReader.close();
|
bufferedReader.close();
|
||||||
fileReader.close();
|
fileReader.close();
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -27,6 +27,8 @@ 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.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;
|
||||||
@@ -273,6 +275,14 @@ public class FileHandlerService {
|
|||||||
FileType type;
|
FileType type;
|
||||||
String fileName;
|
String fileName;
|
||||||
String fullFileName = WebUtils.getUrlParameterReg(url, "fullfilename");
|
String fullFileName = WebUtils.getUrlParameterReg(url, "fullfilename");
|
||||||
|
String urlStrr = null;
|
||||||
|
URL urll;
|
||||||
|
try {
|
||||||
|
urll = new URL(url);
|
||||||
|
urlStrr = URLDecoder.decode(urll.getPath(), "UTF-8");
|
||||||
|
} catch (Exception e) {
|
||||||
|
|
||||||
|
}
|
||||||
if (StringUtils.hasText(fullFileName)) {
|
if (StringUtils.hasText(fullFileName)) {
|
||||||
fileName = fullFileName;
|
fileName = fullFileName;
|
||||||
type = FileType.typeFromFileName(fullFileName);
|
type = FileType.typeFromFileName(fullFileName);
|
||||||
@@ -283,8 +293,10 @@ public class FileHandlerService {
|
|||||||
suffix = WebUtils.suffixFromUrl(url);
|
suffix = WebUtils.suffixFromUrl(url);
|
||||||
}
|
}
|
||||||
if (url.contains("?fileKey=")) {
|
if (url.contains("?fileKey=")) {
|
||||||
|
fileName=urlStrr;
|
||||||
attribute.setSkipDownLoad(true);
|
attribute.setSkipDownLoad(true);
|
||||||
}
|
}
|
||||||
|
// System.out.println(fileName);
|
||||||
url = WebUtils.encodeUrlFileName(url);
|
url = WebUtils.encodeUrlFileName(url);
|
||||||
fileName = KkFileUtils.htmlEscape(fileName); //文件名处理
|
fileName = KkFileUtils.htmlEscape(fileName); //文件名处理
|
||||||
attribute.setType(type);
|
attribute.setType(type);
|
||||||
|
|||||||
20
server/src/main/java/cn/keking/service/ZtreeNodeVo.java
Normal file
20
server/src/main/java/cn/keking/service/ZtreeNodeVo.java
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
package cn.keking.service;
|
||||||
|
import java.util.List;
|
||||||
|
public class ZtreeNodeVo {
|
||||||
|
public String id;
|
||||||
|
public String pid;
|
||||||
|
public String name;
|
||||||
|
public List<ZtreeNodeVo> children;
|
||||||
|
public void setId(String id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
public void setPid(String pid) {
|
||||||
|
this.pid = pid;
|
||||||
|
}
|
||||||
|
public void setChildren(List<ZtreeNodeVo> children) {
|
||||||
|
this.children = children;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,10 +7,15 @@ import cn.keking.service.FilePreview;
|
|||||||
import cn.keking.utils.DownloadUtils;
|
import cn.keking.utils.DownloadUtils;
|
||||||
import cn.keking.service.FileHandlerService;
|
import cn.keking.service.FileHandlerService;
|
||||||
import cn.keking.service.CompressFileReader;
|
import cn.keking.service.CompressFileReader;
|
||||||
|
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||||
|
import org.apache.poi.EncryptedDocumentException;
|
||||||
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;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by kl on 2018/1/17.
|
* Created by kl on 2018/1/17.
|
||||||
* Content :处理压缩包文件
|
* Content :处理压缩包文件
|
||||||
@@ -21,7 +26,7 @@ public class CompressFilePreviewImpl implements FilePreview {
|
|||||||
private final FileHandlerService fileHandlerService;
|
private final FileHandlerService fileHandlerService;
|
||||||
private final CompressFileReader compressFileReader;
|
private final CompressFileReader compressFileReader;
|
||||||
private final OtherFilePreviewImpl otherFilePreview;
|
private final OtherFilePreviewImpl otherFilePreview;
|
||||||
|
private static final String Rar_PASSWORD_MSG = "password";
|
||||||
public CompressFilePreviewImpl(FileHandlerService fileHandlerService, CompressFileReader compressFileReader, OtherFilePreviewImpl otherFilePreview) {
|
public CompressFilePreviewImpl(FileHandlerService fileHandlerService, CompressFileReader compressFileReader, OtherFilePreviewImpl otherFilePreview) {
|
||||||
this.fileHandlerService = fileHandlerService;
|
this.fileHandlerService = fileHandlerService;
|
||||||
this.compressFileReader = compressFileReader;
|
this.compressFileReader = compressFileReader;
|
||||||
@@ -31,7 +36,8 @@ public class CompressFilePreviewImpl implements FilePreview {
|
|||||||
@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 fileTree;
|
String filePassword = fileAttribute.getFilePassword();
|
||||||
|
String fileTree = null;
|
||||||
// 判断文件名是否存在(redis缓存读取)
|
// 判断文件名是否存在(redis缓存读取)
|
||||||
if (!StringUtils.hasText(fileHandlerService.getConvertedFile(fileName)) || !ConfigConstants.isCacheEnabled()) {
|
if (!StringUtils.hasText(fileHandlerService.getConvertedFile(fileName)) || !ConfigConstants.isCacheEnabled()) {
|
||||||
ReturnResponse<String> response = DownloadUtils.downLoad(fileAttribute, fileName);
|
ReturnResponse<String> response = DownloadUtils.downLoad(fileAttribute, fileName);
|
||||||
@@ -39,21 +45,32 @@ public class CompressFilePreviewImpl implements FilePreview {
|
|||||||
return otherFilePreview.notSupportedFile(model, fileAttribute, response.getMsg());
|
return otherFilePreview.notSupportedFile(model, fileAttribute, response.getMsg());
|
||||||
}
|
}
|
||||||
String filePath = response.getContent();
|
String filePath = response.getContent();
|
||||||
fileTree = compressFileReader.unRar(filePath, fileName);
|
try {
|
||||||
if (fileTree != null && !"null".equals(fileTree)) {
|
fileTree = compressFileReader.unRar(filePath, filePassword,fileName);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Throwable[] throwableArray = ExceptionUtils.getThrowables(e);
|
||||||
|
for (Throwable throwable : throwableArray) {
|
||||||
|
if (throwable instanceof IOException || throwable instanceof EncryptedDocumentException) {
|
||||||
|
if (e.getMessage().toLowerCase().contains(Rar_PASSWORD_MSG)) {
|
||||||
|
model.addAttribute("needFilePassword", true);
|
||||||
|
return EXEL_FILE_PREVIEW_PAGE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!ObjectUtils.isEmpty(fileTree)) {
|
||||||
if (ConfigConstants.isCacheEnabled()) {
|
if (ConfigConstants.isCacheEnabled()) {
|
||||||
// 加入缓存
|
// 加入缓存
|
||||||
fileHandlerService.addConvertedFile(fileName, fileTree);
|
fileHandlerService.addConvertedFile(fileName, fileTree);
|
||||||
}
|
}
|
||||||
|
}else {
|
||||||
|
return otherFilePreview.notSupportedFile(model, fileAttribute, "压缩文件密码错误! 压缩文件损坏! 压缩文件类型不受支持!");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fileTree = fileHandlerService.getConvertedFile(fileName);
|
fileTree = fileHandlerService.getConvertedFile(fileName);
|
||||||
}
|
}
|
||||||
if (fileTree != null && !"null".equals(fileTree)) {
|
model.addAttribute("fileName", fileName);
|
||||||
model.addAttribute("fileTree", fileTree);
|
model.addAttribute("fileTree", fileTree);
|
||||||
return COMPRESS_FILE_PREVIEW_PAGE;
|
return COMPRESS_FILE_PREVIEW_PAGE;
|
||||||
} else {
|
|
||||||
return otherFilePreview.notSupportedFile(model, fileAttribute, "压缩文件类型不受支持");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,13 +3,11 @@ 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.ReturnResponse;
|
import cn.keking.model.ReturnResponse;
|
||||||
|
import cn.keking.service.FileHandlerService;
|
||||||
import cn.keking.service.FilePreview;
|
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.WebUtils;
|
|
||||||
import cn.keking.web.filter.BaseUrlFilter;
|
import cn.keking.web.filter.BaseUrlFilter;
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
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.StringUtils;
|
||||||
@@ -27,72 +25,64 @@ import java.util.List;
|
|||||||
@Service
|
@Service
|
||||||
public class TiffFilePreviewImpl implements FilePreview {
|
public class TiffFilePreviewImpl implements FilePreview {
|
||||||
|
|
||||||
private final static Logger logger = LoggerFactory.getLogger(TiffFilePreviewImpl.class);
|
private final FileHandlerService fileHandlerService;
|
||||||
|
private final OtherFilePreviewImpl otherFilePreview;
|
||||||
private final PictureFilePreviewImpl pictureFilePreview;
|
public TiffFilePreviewImpl(FileHandlerService fileHandlerService,OtherFilePreviewImpl otherFilePreview) {
|
||||||
private static final String INITIALIZE_MEMORY_SIZE = "initializeMemorySize";
|
this.fileHandlerService = fileHandlerService;
|
||||||
//默认初始化 50MB 内存
|
this.otherFilePreview = otherFilePreview;
|
||||||
private static final long INITIALIZE_MEMORY_SIZE_VALUE_DEFAULT = 1024L * 1024 * 50;
|
|
||||||
|
|
||||||
private final String fileDir = ConfigConstants.getFileDir();
|
|
||||||
|
|
||||||
public TiffFilePreviewImpl(PictureFilePreviewImpl pictureFilePreview) {
|
|
||||||
this.pictureFilePreview = pictureFilePreview;
|
|
||||||
}
|
}
|
||||||
|
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 baseUrl = BaseUrlFilter.getBaseUrl();
|
||||||
String tifPreviewType = ConfigConstants.getTifPreviewType();
|
String tifPreviewType = ConfigConstants.getTifPreviewType();
|
||||||
String tifOnLinePreviewType = fileAttribute.getTifPreviewType();
|
String tifOnLinePreviewType = fileAttribute.getTifPreviewType();
|
||||||
if (StringUtils.hasText(tifOnLinePreviewType)) {
|
if (StringUtils.hasText(tifOnLinePreviewType)) {
|
||||||
tifPreviewType = tifOnLinePreviewType;
|
tifPreviewType = tifOnLinePreviewType;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ("tif".equalsIgnoreCase(tifPreviewType)) {
|
if ("tif".equalsIgnoreCase(tifPreviewType)) {
|
||||||
|
model.addAttribute("currentUrl", url);
|
||||||
pictureFilePreview.filePreviewHandle(url, model, fileAttribute);
|
|
||||||
String fileSize = WebUtils.getUrlParameterReg(url, INITIALIZE_MEMORY_SIZE);
|
|
||||||
if (StringUtils.hasText(fileSize)) {
|
|
||||||
model.addAttribute(INITIALIZE_MEMORY_SIZE, fileSize);
|
|
||||||
} else {
|
|
||||||
model.addAttribute(INITIALIZE_MEMORY_SIZE, Long.toString(INITIALIZE_MEMORY_SIZE_VALUE_DEFAULT));
|
|
||||||
}
|
|
||||||
return TIFF_FILE_PREVIEW_PAGE;
|
return TIFF_FILE_PREVIEW_PAGE;
|
||||||
|
|
||||||
} else if ("jpg".equalsIgnoreCase(tifPreviewType) || "pdf".equalsIgnoreCase(tifPreviewType)) {
|
} else if ("jpg".equalsIgnoreCase(tifPreviewType) || "pdf".equalsIgnoreCase(tifPreviewType)) {
|
||||||
String inputFileName = url.substring(url.lastIndexOf("/") + 1);
|
String pdfName = fileName.substring(0, fileName.lastIndexOf(".") + 1) + "pdf";
|
||||||
String inputFileNamePrefix = inputFileName.substring(0, inputFileName.lastIndexOf("."));
|
String jpgName = fileName.substring(0, fileName.lastIndexOf(".") + 1) + "jpg";
|
||||||
|
String strLocalTif = fileDir + fileName;
|
||||||
String strLocalTif = fileDir + inputFileName;
|
String outFilePath = fileDir + pdfName;
|
||||||
File fileTiff = new File(strLocalTif);
|
|
||||||
// 如果本地不存在这个tif文件,则下载
|
|
||||||
if (!fileTiff.exists()) {
|
|
||||||
ReturnResponse<String> response = DownloadUtils.downLoad(fileAttribute, inputFileName);
|
|
||||||
if (response.isFailure()) {
|
|
||||||
return NOT_SUPPORTED_FILE_PAGE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String baseUrl = BaseUrlFilter.getBaseUrl();
|
|
||||||
if ("pdf".equalsIgnoreCase(tifPreviewType)) {
|
if ("pdf".equalsIgnoreCase(tifPreviewType)) {
|
||||||
// 以PDF模式预览的过程
|
//当文件不存在时,就去下载
|
||||||
File filePdf = new File(fileDir + inputFileNamePrefix + ".pdf");
|
if (!fileHandlerService.listConvertedFiles().containsKey(pdfName) || !ConfigConstants.isCacheEnabled()) {
|
||||||
// 如果本地不存在对应的pdf,则调用转换过程。否则直接用现有的pdf文件
|
ReturnResponse<String> response = DownloadUtils.downLoad(fileAttribute, fileName);
|
||||||
if (!filePdf.exists()) {
|
if (response.isFailure()) {
|
||||||
filePdf = ConvertPicUtil.convertTif2Pdf(strLocalTif, fileDir + inputFileNamePrefix + ".pdf");
|
return otherFilePreview.notSupportedFile(model, fileAttribute, response.getMsg());
|
||||||
}
|
}
|
||||||
|
String filePath = response.getContent();
|
||||||
// 如果pdf已经存在,则将url路径加入到对象中,返回给页面
|
if (ConfigConstants.isCacheEnabled()) {
|
||||||
assert filePdf != null;
|
// 加入缓存
|
||||||
if (filePdf.exists()) {
|
fileHandlerService.addConvertedFile(pdfName, fileHandlerService.getRelativePath(outFilePath));
|
||||||
String pdfUrl = baseUrl + inputFileNamePrefix + ".pdf";
|
}
|
||||||
model.addAttribute("pdfUrl", pdfUrl);
|
if(ConvertPicUtil.convertJpg2Pdf(filePath, outFilePath)){
|
||||||
|
model.addAttribute("pdfUrl", pdfName);
|
||||||
|
return PDF_FILE_PREVIEW_PAGE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
model.addAttribute("pdfUrl", pdfName);
|
||||||
return PDF_FILE_PREVIEW_PAGE;
|
return PDF_FILE_PREVIEW_PAGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
File fileTiff = new File(strLocalTif);
|
||||||
|
// 如果本地不存在这个tif文件,则下载
|
||||||
|
if (!fileTiff.exists()) {
|
||||||
|
ReturnResponse<String> response = DownloadUtils.downLoad(fileAttribute, fileName);
|
||||||
|
if (response.isFailure()) {
|
||||||
|
return otherFilePreview.notSupportedFile(model, fileAttribute, response.getMsg());
|
||||||
|
}
|
||||||
|
strLocalTif = response.getContent();
|
||||||
|
}
|
||||||
// 以JPG模式预览的过程
|
// 以JPG模式预览的过程
|
||||||
String strJpgFilePathName = fileDir + inputFileNamePrefix + ".jpg";
|
String strJpgFilePathName = fileDir + jpgName;
|
||||||
// 将tif转换为jpg,返回转换后的文件路径、文件名的list
|
// 将tif转换为jpg,返回转换后的文件路径、文件名的list
|
||||||
List<String> listPic2Jpg = ConvertPicUtil.convertTif2Jpg(strLocalTif, strJpgFilePathName);
|
List<String> listPic2Jpg = ConvertPicUtil.convertTif2Jpg(strLocalTif, strJpgFilePathName);
|
||||||
// 将返回页面的图片url的list对象
|
// 将返回页面的图片url的list对象
|
||||||
@@ -101,19 +91,11 @@ public class TiffFilePreviewImpl implements FilePreview {
|
|||||||
for (String strJpg : listPic2Jpg) {
|
for (String strJpg : listPic2Jpg) {
|
||||||
listImageUrls.add(baseUrl + strJpg);
|
listImageUrls.add(baseUrl + strJpg);
|
||||||
}
|
}
|
||||||
|
|
||||||
model.addAttribute("imgUrls", listImageUrls);
|
model.addAttribute("imgUrls", listImageUrls);
|
||||||
model.addAttribute("currentUrl", listImageUrls.get(0));
|
model.addAttribute("currentUrl", listImageUrls.get(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 转换后的tif没用了,可以删掉了
|
|
||||||
if (fileTiff.exists() && !fileTiff.delete()) {
|
|
||||||
logger.error("{} 清理失败", strLocalTif);
|
|
||||||
}
|
|
||||||
|
|
||||||
return PICTURE_FILE_PREVIEW_PAGE;
|
return PICTURE_FILE_PREVIEW_PAGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NOT_SUPPORTED_FILE_PAGE;
|
return NOT_SUPPORTED_FILE_PAGE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +1,17 @@
|
|||||||
package cn.keking.utils;
|
package cn.keking.utils;
|
||||||
|
|
||||||
|
|
||||||
import com.lowagie.text.Document;
|
import cn.keking.config.ConfigConstants;
|
||||||
import com.lowagie.text.Image;
|
|
||||||
import com.lowagie.text.Rectangle;
|
|
||||||
import com.lowagie.text.pdf.PdfWriter;
|
|
||||||
import com.lowagie.text.pdf.RandomAccessFileOrArray;
|
|
||||||
import com.lowagie.text.pdf.codec.TiffImage;
|
|
||||||
import com.sun.media.jai.codec.*;
|
import com.sun.media.jai.codec.*;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import com.itextpdf.text.Document;
|
||||||
|
import com.itextpdf.text.Image;
|
||||||
|
import com.itextpdf.text.io.FileChannelRandomAccessSource;
|
||||||
|
import com.itextpdf.text.pdf.PdfWriter;
|
||||||
|
import com.itextpdf.text.pdf.RandomAccessFileOrArray;
|
||||||
|
import com.itextpdf.text.pdf.codec.TiffImage;
|
||||||
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;
|
||||||
@@ -18,13 +19,14 @@ import java.awt.image.renderable.ParameterBlock;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.RandomAccessFile;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class ConvertPicUtil {
|
public class ConvertPicUtil {
|
||||||
|
|
||||||
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();
|
||||||
/**
|
/**
|
||||||
* Tif 转 JPG。
|
* Tif 转 JPG。
|
||||||
*
|
*
|
||||||
@@ -42,25 +44,21 @@ public class ConvertPicUtil {
|
|||||||
logger.info("找不到文件【" + strInputFile + "】");
|
logger.info("找不到文件【" + strInputFile + "】");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
strInputFile = strInputFile.replaceAll("\\\\", "/");
|
strInputFile = strInputFile.replaceAll("\\\\", "/");
|
||||||
strOutputFile = strOutputFile.replaceAll("\\\\", "/");
|
strOutputFile = strOutputFile.replaceAll("\\\\", "/");
|
||||||
|
|
||||||
FileSeekableStream fileSeekStream = null;
|
FileSeekableStream fileSeekStream = null;
|
||||||
try {
|
try {
|
||||||
JPEGEncodeParam jpegEncodeParam = new JPEGEncodeParam();
|
JPEGEncodeParam jpegEncodeParam = new JPEGEncodeParam();
|
||||||
|
|
||||||
TIFFEncodeParam tiffEncodeParam = new TIFFEncodeParam();
|
TIFFEncodeParam tiffEncodeParam = new TIFFEncodeParam();
|
||||||
tiffEncodeParam.setCompression(TIFFEncodeParam.COMPRESSION_GROUP4);
|
tiffEncodeParam.setCompression(TIFFEncodeParam.COMPRESSION_GROUP4);
|
||||||
tiffEncodeParam.setLittleEndian(false);
|
tiffEncodeParam.setLittleEndian(false);
|
||||||
|
String jpgname = strInputFile.replace(fileDir.replace("\\","/"), "");
|
||||||
String strFilePrefix = strInputFile.substring(strInputFile.lastIndexOf("/") + 1, strInputFile.lastIndexOf("."));
|
int index = jpgname.lastIndexOf(".");
|
||||||
|
String strFilePrefix = jpgname.substring(0, index);
|
||||||
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;
|
String strJpgPath;
|
||||||
String strJpgUrl;
|
String strJpgUrl;
|
||||||
if (intTifCount == 1) {
|
if (intTifCount == 1) {
|
||||||
@@ -87,9 +85,7 @@ public class ConvertPicUtil {
|
|||||||
strJpg = strJpgPath + "/" + i + ".jpg";
|
strJpg = strJpgPath + "/" + i + ".jpg";
|
||||||
strJpgUrl = strFilePrefix + "/" + i + ".jpg";
|
strJpgUrl = strFilePrefix + "/" + i + ".jpg";
|
||||||
}
|
}
|
||||||
|
|
||||||
File fileJpg = new File(strJpg);
|
File fileJpg = new File(strJpg);
|
||||||
|
|
||||||
// 如果文件不存在,则生成
|
// 如果文件不存在,则生成
|
||||||
if (!fileJpg.exists()) {
|
if (!fileJpg.exists()) {
|
||||||
RenderedImage renderedImage = imageDecoder.decodeAsRenderedImage(i);
|
RenderedImage renderedImage = imageDecoder.decodeAsRenderedImage(i);
|
||||||
@@ -98,13 +94,11 @@ public class ConvertPicUtil {
|
|||||||
pb.add(fileJpg.toString());
|
pb.add(fileJpg.toString());
|
||||||
pb.add("JPEG");
|
pb.add("JPEG");
|
||||||
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());
|
||||||
} else {
|
} else {
|
||||||
logger.info("JPG文件已存在: " + fileJpg.getCanonicalPath());
|
// logger.info("JPG文件已存在: " + fileJpg.getCanonicalPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
listImageFiles.add(strJpgUrl);
|
listImageFiles.add(strJpgUrl);
|
||||||
@@ -131,101 +125,45 @@ public class ConvertPicUtil {
|
|||||||
* @param strJpgFile 输入的jpg的路径和文件名
|
* @param strJpgFile 输入的jpg的路径和文件名
|
||||||
* @param strPdfFile 输出的pdf的路径和文件名
|
* @param strPdfFile 输出的pdf的路径和文件名
|
||||||
*/
|
*/
|
||||||
public static void convertJpg2Pdf(String strJpgFile, String strPdfFile) {
|
private static final int FIT_WIDTH = 500;
|
||||||
Document document = new Document();
|
private static final int FIT_HEIGHT = 900;
|
||||||
// 设置文档页边距
|
public static boolean convertJpg2Pdf(String strJpgFile, String strPdfFile) {
|
||||||
document.setMargins(0, 0, 0, 0);
|
Document document= null;
|
||||||
|
RandomAccessFileOrArray rafa = null;
|
||||||
FileOutputStream fos = null;
|
|
||||||
try {
|
try {
|
||||||
fos = new FileOutputStream(strPdfFile);
|
document = new Document();
|
||||||
PdfWriter.getInstance(document, fos);
|
PdfWriter.getInstance(document, new FileOutputStream(strPdfFile));
|
||||||
// 打开文档
|
|
||||||
document.open();
|
document.open();
|
||||||
// 获取图片的宽高
|
rafa = new RandomAccessFileOrArray(new FileChannelRandomAccessSource(new RandomAccessFile(strJpgFile, "r").getChannel()));
|
||||||
Image image = Image.getInstance(strJpgFile);
|
int pages = TiffImage.getNumberOfPages(rafa);
|
||||||
float floatImageHeight = image.getScaledHeight();
|
Image image;
|
||||||
float floatImageWidth = image.getScaledWidth();
|
for (int i = 1; i <= pages; i++) {
|
||||||
// 设置页面宽高与图片一致
|
try {
|
||||||
Rectangle rectangle = new Rectangle(floatImageWidth, floatImageHeight);
|
image = TiffImage.getTiffImage(rafa, i);
|
||||||
document.setPageSize(rectangle);
|
image.scaleToFit(FIT_WIDTH, FIT_HEIGHT);
|
||||||
// 图片居中
|
document.add(image);
|
||||||
image.setAlignment(Image.ALIGN_CENTER);
|
} catch (Exception e) {
|
||||||
//新建一页添加图片
|
document.close();
|
||||||
document.newPage();
|
rafa.close();
|
||||||
document.add(image);
|
e.printStackTrace();
|
||||||
} catch (Exception ioe) {
|
}
|
||||||
ioe.printStackTrace();
|
}
|
||||||
} finally {
|
document.close();
|
||||||
//关闭文档
|
rafa.close();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
System.out.println("错误:"+ e.getMessage());
|
||||||
|
}
|
||||||
|
finally {
|
||||||
document.close();
|
document.close();
|
||||||
try {
|
try {
|
||||||
assert fos != null;
|
rafa.close();
|
||||||
fos.flush();
|
|
||||||
fos.close();
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 将Tif图片转换为Pdf文件(支持多页Tif)
|
|
||||||
*
|
|
||||||
* @param strTifFile 输入的tif的路径和文件名
|
|
||||||
* @param strPdfFile 输出的pdf的路径和文件名
|
|
||||||
* @return File
|
|
||||||
*/
|
|
||||||
public static File convertTif2Pdf(String strTifFile, String strPdfFile) {
|
|
||||||
try {
|
|
||||||
RandomAccessFileOrArray rafa = new RandomAccessFileOrArray(strTifFile);
|
|
||||||
|
|
||||||
Document document = new Document();
|
|
||||||
// 设置文档页边距
|
|
||||||
document.setMargins(0, 0, 0, 0);
|
|
||||||
|
|
||||||
PdfWriter.getInstance(document, new FileOutputStream(strPdfFile));
|
|
||||||
document.open();
|
|
||||||
int intPages = TiffImage.getNumberOfPages(rafa);
|
|
||||||
Image image;
|
|
||||||
File filePDF;
|
|
||||||
|
|
||||||
if (intPages == 1) {
|
|
||||||
String strJpg = strTifFile.substring(0, strTifFile.lastIndexOf(".")) + ".jpg";
|
|
||||||
File fileJpg = new File(strJpg);
|
|
||||||
List<String> listPic2Jpg = convertTif2Jpg(strTifFile, strJpg);
|
|
||||||
|
|
||||||
if (listPic2Jpg != null && fileJpg.exists()) {
|
|
||||||
convertJpg2Pdf(strJpg, strPdfFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
for (int i = 1; i <= intPages; i++) {
|
|
||||||
image = TiffImage.getTiffImage(rafa, i);
|
|
||||||
// 设置页面宽高与图片一致
|
|
||||||
Rectangle pageSize = new Rectangle(image.getScaledWidth(), image.getScaledHeight());
|
|
||||||
document.setPageSize(pageSize);
|
|
||||||
// 图片居中
|
|
||||||
image.setAlignment(Image.ALIGN_CENTER);
|
|
||||||
//新建一页添加图片
|
|
||||||
document.newPage();
|
|
||||||
document.add(image);
|
|
||||||
}
|
|
||||||
|
|
||||||
document.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
rafa.close();
|
|
||||||
|
|
||||||
filePDF = new File(strPdfFile);
|
|
||||||
|
|
||||||
return filePDF;
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.error(e.getMessage(), e);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -3,16 +3,17 @@ package cn.keking.utils;
|
|||||||
import cn.keking.config.ConfigConstants;
|
import cn.keking.config.ConfigConstants;
|
||||||
import cn.keking.model.FileAttribute;
|
import cn.keking.model.FileAttribute;
|
||||||
import cn.keking.model.ReturnResponse;
|
import cn.keking.model.ReturnResponse;
|
||||||
import cn.keking.service.FileHandlerService;
|
|
||||||
import io.mola.galimatias.GalimatiasParseException;
|
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.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
import org.springframework.web.util.HtmlUtils;
|
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.File;
|
||||||
import java.net.*;
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLDecoder;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import static cn.keking.utils.KkFileUtils.isFtpUrl;
|
import static cn.keking.utils.KkFileUtils.isFtpUrl;
|
||||||
@@ -36,13 +37,30 @@ public class DownloadUtils {
|
|||||||
*/
|
*/
|
||||||
public static ReturnResponse<String> downLoad(FileAttribute fileAttribute, String fileName) {
|
public static ReturnResponse<String> downLoad(FileAttribute fileAttribute, String fileName) {
|
||||||
// 忽略ssl证书
|
// 忽略ssl证书
|
||||||
|
String urlStr = null;
|
||||||
|
String urlStrr = null;
|
||||||
|
URL urll;
|
||||||
try {
|
try {
|
||||||
SslUtils.ignoreSsl();
|
SslUtils.ignoreSsl();
|
||||||
|
urlStr = fileAttribute.getUrl().replaceAll("\\+", "%20");
|
||||||
|
urll = new URL(urlStr);
|
||||||
|
urlStrr = URLDecoder.decode(urll.getPath(), "UTF-8");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.error("忽略SSL证书异常:", e);
|
logger.error("忽略SSL证书异常:", e);
|
||||||
}
|
}
|
||||||
String urlStr = fileAttribute.getUrl().replaceAll("\\+", "%20");
|
|
||||||
ReturnResponse<String> response = new ReturnResponse<>(0, "下载成功!!!", "");
|
ReturnResponse<String> response = new ReturnResponse<>(0, "下载成功!!!", "");
|
||||||
|
if (!KkFileUtils.isAllowedUpload(fileName)) {
|
||||||
|
response.setCode(1);
|
||||||
|
response.setContent(null);
|
||||||
|
response.setMsg("下载失败:不支持的类型!" + urlStr);
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
assert urlStr != null;
|
||||||
|
if (urlStr.contains("?fileKey=")) {
|
||||||
|
response.setContent(fileDir + urlStrr);
|
||||||
|
response.setMsg(fileName);
|
||||||
|
return response;
|
||||||
|
}
|
||||||
String realPath = DownloadUtils.getRelFilePath(fileName, fileAttribute);
|
String realPath = DownloadUtils.getRelFilePath(fileName, fileAttribute);
|
||||||
if(!StringUtils.hasText(realPath)){
|
if(!StringUtils.hasText(realPath)){
|
||||||
response.setCode(1);
|
response.setCode(1);
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
package cn.keking.utils;
|
package cn.keking.utils;
|
||||||
|
|
||||||
|
import cn.keking.config.ConfigConstants;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.util.ObjectUtils;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
import org.springframework.web.util.HtmlUtils;
|
import org.springframework.web.util.HtmlUtils;
|
||||||
|
|
||||||
@@ -174,4 +176,19 @@ public class KkFileUtils {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断文件是否允许上传
|
||||||
|
*
|
||||||
|
* @param file 文件扩展名
|
||||||
|
* @return 是否允许上传
|
||||||
|
*/
|
||||||
|
public static boolean isAllowedUpload(String file) {
|
||||||
|
String fileType = suffixFromFileName(file);
|
||||||
|
for (String type : ConfigConstants.getprohibit()) {
|
||||||
|
if (type.equals(fileType))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return !ObjectUtils.isEmpty(fileType);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
130
server/src/main/java/cn/keking/utils/RarUtils.java
Normal file
130
server/src/main/java/cn/keking/utils/RarUtils.java
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
package cn.keking.utils;
|
||||||
|
import cn.keking.config.ConfigConstants;
|
||||||
|
import cn.keking.service.ZtreeNodeVo;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author : Gao
|
||||||
|
* create : 2023-04-08
|
||||||
|
**/
|
||||||
|
public class RarUtils {
|
||||||
|
private static final String fileDir = ConfigConstants.getFileDir();
|
||||||
|
|
||||||
|
public static byte[] getUTF8BytesFromGBKString(String gbkStr) {
|
||||||
|
int n = gbkStr.length();
|
||||||
|
byte[] utfBytes = new byte[3 * n];
|
||||||
|
int k = 0;
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
int m = gbkStr.charAt(i);
|
||||||
|
if (m < 128 && m >= 0) {
|
||||||
|
utfBytes[k++] = (byte) m;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
utfBytes[k++] = (byte) (0xe0 | (m >> 12));
|
||||||
|
utfBytes[k++] = (byte) (0x80 | ((m >> 6) & 0x3f));
|
||||||
|
utfBytes[k++] = (byte) (0x80 | (m & 0x3f));
|
||||||
|
}
|
||||||
|
if (k < utfBytes.length) {
|
||||||
|
byte[] tmp = new byte[k];
|
||||||
|
System.arraycopy(utfBytes, 0, tmp, 0, k);
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
return utfBytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getUtf8String(String str) {
|
||||||
|
if (str != null && str.length() > 0) {
|
||||||
|
String needEncodeCode = "ISO-8859-1";
|
||||||
|
String neeEncodeCode = "ISO-8859-2";
|
||||||
|
String gbkEncodeCode = "GBK";
|
||||||
|
try {
|
||||||
|
if (Charset.forName(needEncodeCode).newEncoder().canEncode(str)) {
|
||||||
|
str = new String(str.getBytes(needEncodeCode), StandardCharsets.UTF_8);
|
||||||
|
}
|
||||||
|
if (Charset.forName(neeEncodeCode).newEncoder().canEncode(str)) {
|
||||||
|
str = new String(str.getBytes(neeEncodeCode), StandardCharsets.UTF_8);
|
||||||
|
}
|
||||||
|
if (Charset.forName(gbkEncodeCode).newEncoder().canEncode(str)) {
|
||||||
|
str = new String(getUTF8BytesFromGBKString(str), StandardCharsets.UTF_8);
|
||||||
|
}
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 判断是否是中日韩文字
|
||||||
|
*/
|
||||||
|
private static boolean isChinese(char c) {
|
||||||
|
Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);
|
||||||
|
return ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS
|
||||||
|
|| ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS
|
||||||
|
|| ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A
|
||||||
|
|| ub == Character.UnicodeBlock.GENERAL_PUNCTUATION
|
||||||
|
|| ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION
|
||||||
|
|| ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS;
|
||||||
|
}
|
||||||
|
public static boolean judge(char c){
|
||||||
|
return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z');
|
||||||
|
}
|
||||||
|
public static boolean isMessyCode(String strName) {
|
||||||
|
//去除字符串中的空格 制表符 换行 回车
|
||||||
|
Pattern p = Pattern.compile("\\s*|\t*|\r*|\n*");
|
||||||
|
Matcher m = p.matcher(strName);
|
||||||
|
String after = m.replaceAll("").replaceAll("\\+", "").replaceAll("#", "").replaceAll("&", "");
|
||||||
|
//去除字符串中的标点符号
|
||||||
|
String temp = after.replaceAll("\\p{P}", "");
|
||||||
|
//处理之后转换成字符数组
|
||||||
|
char[] ch = temp.trim().toCharArray();
|
||||||
|
for (char c : ch) {
|
||||||
|
//判断是否是数字或者英文字符
|
||||||
|
if (!judge(c)) {
|
||||||
|
//判断是否是中日韩文
|
||||||
|
if (!isChinese(c)) {
|
||||||
|
//如果不是数字或者英文字符也不是中日韩文则表示是乱码返回true
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//表示不是乱码 返回false
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 读取文件目录树
|
||||||
|
*/
|
||||||
|
public static List<ZtreeNodeVo> getTree(String rootPath) {
|
||||||
|
List<ZtreeNodeVo> nodes = new ArrayList<>();
|
||||||
|
File file = new File(fileDir+rootPath);
|
||||||
|
ZtreeNodeVo node = traverse(file);
|
||||||
|
nodes.add(node);
|
||||||
|
return nodes;
|
||||||
|
}
|
||||||
|
private static ZtreeNodeVo traverse(File file) {
|
||||||
|
ZtreeNodeVo pathNodeVo = new ZtreeNodeVo();
|
||||||
|
pathNodeVo.setId(file.getAbsolutePath().replace(fileDir, "").replace("\\", "/"));
|
||||||
|
pathNodeVo.setName(file.getName());
|
||||||
|
pathNodeVo.setPid(file.getParent().replace(fileDir, "").replace("\\", "/"));
|
||||||
|
if (file.isDirectory()) {
|
||||||
|
List<ZtreeNodeVo> subNodeVos = new ArrayList<>();
|
||||||
|
File[] subFiles = file.listFiles();
|
||||||
|
if (subFiles == null) {
|
||||||
|
return pathNodeVo;
|
||||||
|
}
|
||||||
|
for (File subFile : subFiles) {
|
||||||
|
ZtreeNodeVo subNodeVo = traverse(subFile);
|
||||||
|
subNodeVos.add(subNodeVo);
|
||||||
|
}
|
||||||
|
pathNodeVo.setChildren(subNodeVos);
|
||||||
|
}
|
||||||
|
return pathNodeVo;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,6 +3,7 @@ package cn.keking.web.controller;
|
|||||||
import cn.keking.config.ConfigConstants;
|
import cn.keking.config.ConfigConstants;
|
||||||
import cn.keking.model.ReturnResponse;
|
import cn.keking.model.ReturnResponse;
|
||||||
import cn.keking.utils.KkFileUtils;
|
import cn.keking.utils.KkFileUtils;
|
||||||
|
import cn.keking.utils.RarUtils;
|
||||||
import cn.keking.utils.WebUtils;
|
import cn.keking.utils.WebUtils;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@@ -20,12 +21,7 @@ import java.io.InputStream;
|
|||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author yudian-it
|
* @author yudian-it
|
||||||
@@ -40,7 +36,6 @@ public class FileController {
|
|||||||
private final String demoDir = "demo";
|
private final String demoDir = "demo";
|
||||||
private final String demoPath = demoDir + File.separator;
|
private final String demoPath = demoDir + File.separator;
|
||||||
public static final String BASE64_DECODE_ERROR_MSG = "Base64解码失败,请检查你的 %s 是否采用 Base64 + urlEncode 双重编码了!";
|
public static final String BASE64_DECODE_ERROR_MSG = "Base64解码失败,请检查你的 %s 是否采用 Base64 + urlEncode 双重编码了!";
|
||||||
private static final String[] not_allowed = { "dll", "exe", "msi" }; // 不允许上传的文件扩展名
|
|
||||||
|
|
||||||
@PostMapping("/fileUpload")
|
@PostMapping("/fileUpload")
|
||||||
public ReturnResponse<Object> fileUpload(@RequestParam("file") MultipartFile file) {
|
public ReturnResponse<Object> fileUpload(@RequestParam("file") MultipartFile file) {
|
||||||
@@ -64,12 +59,16 @@ public class FileController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/deleteFile")
|
@GetMapping("/deleteFile")
|
||||||
public ReturnResponse<Object> deleteFile(String fileName) {
|
public ReturnResponse<Object> deleteFile(String fileName,String password) {
|
||||||
ReturnResponse<Object> checkResult = this.deleteFileCheck(fileName);
|
ReturnResponse<Object> checkResult = this.deleteFileCheck(fileName);
|
||||||
if (checkResult.isFailure()) {
|
if (checkResult.isFailure()) {
|
||||||
return checkResult;
|
return checkResult;
|
||||||
}
|
}
|
||||||
fileName = checkResult.getContent().toString();
|
fileName = checkResult.getContent().toString();
|
||||||
|
if(!ConfigConstants.getpassword().equalsIgnoreCase(password)){
|
||||||
|
logger.error("删除文件【{}】失败,密码错误!",fileName);
|
||||||
|
return ReturnResponse.failure("删除文件失败,密码错误!");
|
||||||
|
}
|
||||||
File file = new File(fileDir + demoPath + fileName);
|
File file = new File(fileDir + demoPath + fileName);
|
||||||
logger.info("删除文件:{}", file.getAbsolutePath());
|
logger.info("删除文件:{}", file.getAbsolutePath());
|
||||||
if (file.exists() && !file.delete()) {
|
if (file.exists() && !file.delete()) {
|
||||||
@@ -107,8 +106,10 @@ public class FileController {
|
|||||||
return ReturnResponse.failure("文件传接口已禁用");
|
return ReturnResponse.failure("文件传接口已禁用");
|
||||||
}
|
}
|
||||||
String fileName = WebUtils.getFileNameFromMultipartFile(file);
|
String fileName = WebUtils.getFileNameFromMultipartFile(file);
|
||||||
|
if(fileName.lastIndexOf(".")==-1){
|
||||||
if (!isAllowedUpload(fileName)) {
|
return ReturnResponse.failure("不允许上传的类型");
|
||||||
|
}
|
||||||
|
if (!KkFileUtils.isAllowedUpload(fileName)) {
|
||||||
return ReturnResponse.failure("不允许上传的文件类型: " + fileName);
|
return ReturnResponse.failure("不允许上传的文件类型: " + fileName);
|
||||||
}
|
}
|
||||||
if (KkFileUtils.isIllegalFileName(fileName)) {
|
if (KkFileUtils.isIllegalFileName(fileName)) {
|
||||||
@@ -121,20 +122,6 @@ public class FileController {
|
|||||||
return ReturnResponse.success(fileName);
|
return ReturnResponse.success(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 判断文件是否允许上传
|
|
||||||
*
|
|
||||||
* @param file 文件扩展名
|
|
||||||
* @return 是否允许上传
|
|
||||||
*/
|
|
||||||
private boolean isAllowedUpload(String file) {
|
|
||||||
String fileType = KkFileUtils.suffixFromFileName(file);
|
|
||||||
for (String type : not_allowed) {
|
|
||||||
if (type.equals(fileType))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return !ObjectUtils.isEmpty(fileType);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除文件前校验
|
* 删除文件前校验
|
||||||
@@ -162,6 +149,21 @@ public class FileController {
|
|||||||
return ReturnResponse.success(fileName);
|
return ReturnResponse.success(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/directory")
|
||||||
|
public Object directory(String urls) {
|
||||||
|
String fileUrl;
|
||||||
|
try {
|
||||||
|
fileUrl = WebUtils.decodeUrl(urls);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
String errorMsg = String.format(BASE64_DECODE_ERROR_MSG, "url");
|
||||||
|
return ReturnResponse.failure(errorMsg);
|
||||||
|
}
|
||||||
|
if (KkFileUtils.isIllegalFileName(fileUrl)) {
|
||||||
|
return ReturnResponse.failure("不允许访问的路径:");
|
||||||
|
}
|
||||||
|
return RarUtils.getTree(fileUrl);
|
||||||
|
}
|
||||||
|
|
||||||
private boolean existsFile(String fileName) {
|
private boolean existsFile(String fileName) {
|
||||||
File file = new File(fileDir + demoPath + fileName);
|
File file = new File(fileDir + demoPath + fileName);
|
||||||
return file.exists();
|
return file.exists();
|
||||||
|
|||||||
@@ -40,6 +40,8 @@ public class AttributeSetFilter implements Filter {
|
|||||||
request.setAttribute("fileKey", httpRequest.getParameter("fileKey"));
|
request.setAttribute("fileKey", httpRequest.getParameter("fileKey"));
|
||||||
request.setAttribute("switchDisabled", ConfigConstants.getOfficePreviewSwitchDisabled());
|
request.setAttribute("switchDisabled", ConfigConstants.getOfficePreviewSwitchDisabled());
|
||||||
request.setAttribute("fileUploadDisable", ConfigConstants.getFileUploadDisable());
|
request.setAttribute("fileUploadDisable", ConfigConstants.getFileUploadDisable());
|
||||||
|
request.setAttribute("BeiAn", ConfigConstants.getBeiAn());
|
||||||
|
request.setAttribute("size", ConfigConstants.maxsize());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
|_|\_\ |_|\_\ |_| |_| |_| \___| \/ |_| \___| \_/\_/
|
|_|\_\ |_|\_\ |_| |_| |_| \___| \/ |_| \___| \_/\_/
|
||||||
|
|
||||||
=> Spring Boot :: ${spring-boot.version}
|
=> Spring Boot :: ${spring-boot.version}
|
||||||
=> kkFileView :: 4.2.0-SNAPSHOT
|
=> kkFileView :: 4.2.0
|
||||||
=> Home site :: https://kkview.cn
|
=> Home site :: https://kkview.cn
|
||||||
=> Github :: https://github.com/kekingcn/kkFileView
|
=> Github :: https://github.com/kekingcn/kkFileView
|
||||||
=> Gitee :: https://gitee.com/kekingcn/file-online-preview
|
=> Gitee :: https://gitee.com/kekingcn/file-online-preview
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -25685,7 +25685,7 @@
|
|||||||
if (!e)
|
if (!e)
|
||||||
return t;
|
return t;
|
||||||
if (!g || "" == y) {
|
if (!g || "" == y) {
|
||||||
var r, i = 10, o = l(e.pages);
|
var r, i = e.pages.length, o = l(e.pages);
|
||||||
try {
|
try {
|
||||||
for (o.s(); !(r = o.n()).done; ) {
|
for (o.s(); !(r = o.n()).done; ) {
|
||||||
var a = r.value
|
var a = r.value
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -10,18 +10,15 @@
|
|||||||
<meta name=keywords content="Xmind,mindmap,mind map,mind mapping,mind mapping software,free mind mapping software,work from home,WFH,remote">
|
<meta name=keywords content="Xmind,mindmap,mind map,mind mapping,mind mapping software,free mind mapping software,work from home,WFH,remote">
|
||||||
<link rel=stylesheet href=css/bootstrap-customized-2821153174.min.css>
|
<link rel=stylesheet href=css/bootstrap-customized-2821153174.min.css>
|
||||||
<link rel=stylesheet href=css/index-5376440060.css>
|
<link rel=stylesheet href=css/index-5376440060.css>
|
||||||
<script src=js/jquery-3-c9f5aeeca3.2.1.min.js> </script>
|
<script src="../js/jquery-3.6.1.min.js"></script>
|
||||||
<meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">
|
<meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">
|
||||||
<link rel=stylesheet href=css/share-embed-39eba5407f.css> </head>
|
<link rel=stylesheet href=css/share-embed-39eba5407f.css> </head>
|
||||||
<body>
|
<body>
|
||||||
<script>
|
<script>
|
||||||
window.manifests={snowbrush:"js/snowbrush.js"},window.metadataString=""
|
window.manifests={snowbrush:"js/snowbrush.js"},window.metadataString=""
|
||||||
</script>
|
</script>
|
||||||
<script src=js/text-autospace-fed758f4a6.min.js> </script>
|
|
||||||
<script src=js/polyfill-45b9836beb.min.js> </script>
|
<script src=js/polyfill-45b9836beb.min.js> </script>
|
||||||
<script src=js/js-cookie-a978ac7394.js> </script>
|
<script src=js/js-cookie-a978ac7394.js> </script>
|
||||||
<script src=js/popper-135fa9e662.min.js> </script>
|
|
||||||
<script src=js/bootstrap-26779614c4.min.js> </script>
|
|
||||||
<script src=js/base.61517cade8.js> </script>
|
<script src=js/base.61517cade8.js> </script>
|
||||||
<script src=js/share-embed.68f7476360.js> </script>
|
<script src=js/share-embed.68f7476360.js> </script>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -1,108 +1,71 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
<html lang="en">
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8"/>
|
||||||
<meta name="viewport" content="width=device-width, user-scalable=yes, initial-scale=1.0">
|
<title>压缩包预览</title>
|
||||||
<#include "*/commonHeader.ftl">
|
<script src="js/jquery-3.6.1.min.js"></script>
|
||||||
<script src="js/jquery-3.6.1.min.js" type="text/javascript"></script>
|
<#include "*/commonHeader.ftl">
|
||||||
<link href="css/zTreeStyle.css" rel="stylesheet" type="text/css">
|
<script src="js/base64.min.js" type="text/javascript"></script>
|
||||||
<script src="js/base64.min.js" type="text/javascript"></script>
|
<link href="css/zTreeStyle.css" rel="stylesheet" type="text/css">
|
||||||
<style type="text/css">
|
<script type="text/javascript" src="js/jquery.ztree.core.js"></script>
|
||||||
|
<style type="text/css">
|
||||||
body {
|
body {
|
||||||
background-color: #404040;
|
background-color: #404040;
|
||||||
}
|
}
|
||||||
h1, h2, h3, h4, h5, h6 {color: #2f332a;font-weight: bold;font-family: Helvetica, Arial, sans-serif;padding-bottom: 5px;}
|
|
||||||
h1 {font-size: 24px;line-height: 34px;text-align: center;}
|
h1 {font-size: 24px;line-height: 34px;text-align: center;}
|
||||||
h2 {font-size: 14px;line-height: 24px;padding-top: 5px;}
|
|
||||||
h6 {font-weight: normal;font-size: 12px;letter-spacing: 1px;line-height: 24px;text-align: center;}
|
|
||||||
a {color:#3C6E31;text-decoration: underline;}
|
a {color:#3C6E31;text-decoration: underline;}
|
||||||
a:hover {background-color:#3C6E31;color:white;}
|
a:hover {background-color:#3C6E31;color:white;}
|
||||||
code {color: #2f332a;}
|
code {color: #2f332a;}
|
||||||
div.zTreeDemoBackground {width:600px;text-align:center;margin: 0 auto;background-color: #ffffff;}
|
div.zTreeDemoBackground {
|
||||||
|
max-width: 880px;
|
||||||
|
text-align:center;
|
||||||
|
margin:0 auto;
|
||||||
|
border-radius:3px;
|
||||||
|
box-shadow:rgba(0,0,0,0.15) 0 0 8px;
|
||||||
|
background:#FBFBFB;
|
||||||
|
border:1px solid #ddd;
|
||||||
|
margin:1px auto;
|
||||||
|
padding:5px;
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<div class="zTreeDemoBackground left">
|
<div class="zTreeDemoBackground left">
|
||||||
|
<h1>kkFileView</h1>
|
||||||
<ul id="treeDemo" class="ztree"></ul>
|
<ul id="treeDemo" class="ztree"></ul>
|
||||||
</div>
|
</div>
|
||||||
<script type="text/javascript" src="js/jquery.ztree.core.js"></script>
|
<script>
|
||||||
|
var settings = {
|
||||||
<script type="text/javascript">
|
|
||||||
const data = JSON.parse('${fileTree}');
|
|
||||||
var baseUrl = "${baseUrl}";
|
|
||||||
var setting = {
|
|
||||||
view: {
|
|
||||||
fontCss : {"color":"blue"},
|
|
||||||
showLine: true
|
|
||||||
},
|
|
||||||
data: {
|
data: {
|
||||||
key: {
|
simpleData: {
|
||||||
children: 'childList',
|
enable: true, //true 、 false 分别表示 使用 、 不使用 简单数据模式
|
||||||
name: 'originName'
|
idKey: "id", //节点数据中保存唯一标识的属性名称
|
||||||
|
pIdKey: "pid", //节点数据中保存其父节点唯一标识的属性名称
|
||||||
|
rootPId: ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
callback:{
|
callback: {
|
||||||
beforeClick:function (treeId, treeNode, clickFlag) {
|
onClick: chooseNode,
|
||||||
console.log("节点参数:treeId-" + treeId + "treeNode-"
|
|
||||||
+ JSON.stringify(treeNode) + "clickFlag-" + clickFlag);
|
|
||||||
},
|
|
||||||
onClick:function (event, treeId, treeNode) {
|
|
||||||
if (!treeNode.directory) {
|
|
||||||
/**实现窗口最大化**/
|
|
||||||
var fulls = "left=0,screenX=0,top=0,screenY=0,scrollbars=1"; //定义弹出窗口的参数
|
|
||||||
if (window.screen) {
|
|
||||||
var ah = screen.availHeight - 30;
|
|
||||||
var aw = (screen.availWidth - 10) / 2;
|
|
||||||
fulls += ",height=" + ah;
|
|
||||||
fulls += ",innerHeight=" + ah;
|
|
||||||
fulls += ",width=" + aw;
|
|
||||||
fulls += ",innerWidth=" + aw;
|
|
||||||
fulls += ",resizable"
|
|
||||||
} else {
|
|
||||||
fulls += ",resizable"; // 对于不支持screen属性的浏览器,可以手工进行最大化。 manually
|
|
||||||
}
|
|
||||||
var previewUrl = baseUrl + treeNode.fileName +"?fileKey="+ treeNode.fileKey;
|
|
||||||
window.open("onlinePreview?url=" + encodeURIComponent(Base64.encode(previewUrl)), "_blank",fulls);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
var height = 0;
|
|
||||||
$(document).ready(function(){
|
function chooseNode(event, treeId, treeNode) {
|
||||||
var treeObj = $.fn.zTree.init($("#treeDemo"), setting, data);
|
var path = '${baseUrl}' + treeNode.id +"?fileKey="+'${fileName}';
|
||||||
treeObj.expandAll(true);
|
location.href = "${baseUrl}onlinePreview?url=" + encodeURIComponent(Base64.encode(path));
|
||||||
height = getZtreeDomHeight();
|
}
|
||||||
$(".zTreeDemoBackground").css("height", height);
|
|
||||||
|
$(document).ready(function () {
|
||||||
|
var url = '${fileTree}';
|
||||||
|
$.ajax({
|
||||||
|
type: "get",
|
||||||
|
url: "${baseUrl}directory?urls="+encodeURIComponent(Base64.encode(url)),
|
||||||
|
success: function (res) {
|
||||||
|
zTreeObj = $.fn.zTree.init($("#treeDemo"), settings, res); //初始化树
|
||||||
|
zTreeObj.expandAll(true); //true 节点全部展开、false节点收缩
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
/*初始化水印*/
|
|
||||||
window.onload = function() {
|
|
||||||
initWaterMark();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 计算ztreedom的高度
|
|
||||||
*/
|
|
||||||
function getZtreeDomHeight() {
|
|
||||||
return $("#treeDemo").height() > window.document.documentElement.clientHeight - 1
|
|
||||||
? $("#treeDemo").height() : window.document.documentElement.clientHeight - 1;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* 页面变化调整高度
|
|
||||||
*/
|
|
||||||
window.onresize = function(){
|
|
||||||
height = getZtreeDomHeight();
|
|
||||||
$(".zTreeDemoBackground").css("height", height);
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* 滚动时调整高度
|
|
||||||
*/
|
|
||||||
window.onscroll = function(){
|
|
||||||
height = getZtreeDomHeight();
|
|
||||||
$(".zTreeDemoBackground").css("height", height);
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
@@ -116,33 +116,10 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<#if fileUploadDisable == false>
|
<#if fileUploadDisable == false>
|
||||||
<div style="padding: 10px">
|
<div style="padding: 10px" >
|
||||||
<form enctype="multipart/form-data" id="fileUpload">
|
<form enctype="multipart/form-data" id="fileUpload">
|
||||||
<div class="form-group">
|
<input type="file" id="size" name="file"/>
|
||||||
<p id="fileName"></p>
|
<input type="button" id="btnSubmit" value=" 上 传 "/>
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-2">
|
|
||||||
<button type="button" class="btn btn-default" id="fileSelectBtn" style="margin-bottom:8px">
|
|
||||||
<span class="glyphicon glyphicon-cloud-upload" aria-hidden="true"></span> 选择文件
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-1">
|
|
||||||
<button id="btnSubmit" type="button" class="btn btn-success">上 传</button>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-9">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<input type="file" name="file" style="display: none" id="fileSelect"
|
|
||||||
onchange="onFileSelected()"/>
|
|
||||||
<div class="alert alert-danger alert-dismissable hide" role="alert" id="postFileAlert">
|
|
||||||
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
|
|
||||||
<span aria-hidden="true">×</span>
|
|
||||||
</button>
|
|
||||||
<strong>请选择需要上传的文件!</strong>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</#if>
|
</#if>
|
||||||
@@ -175,22 +152,34 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div style="display: grid; place-items: center;">
|
||||||
|
<div>
|
||||||
|
<a target="_blank" href="https://beian.miit.gov.cn/" >${BeiAn}</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<script>
|
<script>
|
||||||
function deleteFile(fileName) {
|
function deleteFile(fileName,password) {
|
||||||
$.ajax({
|
if(window.confirm('你确定要删除文件吗?')){
|
||||||
url: '${baseUrl}deleteFile?fileName=' + fileName,
|
password = prompt("请输入默认密码:123456");
|
||||||
success: function (data) {
|
$.ajax({
|
||||||
// 删除完成,刷新table
|
url: '${baseUrl}deleteFile?fileName=' + fileName +'&password='+password,
|
||||||
if (1 === data.code) {
|
success: function (data) {
|
||||||
alert(data.msg);
|
// console.log(data);
|
||||||
} else {
|
// 删除完成,刷新table
|
||||||
$('#table').bootstrapTable('refresh', {});
|
if ("删除文件失败,密码错误!" === data.msg) {
|
||||||
|
alert(data.msg);
|
||||||
|
} else {
|
||||||
|
$('#table').bootstrapTable('refresh', {});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: function (data) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
},
|
})
|
||||||
error: function (data) {
|
}else{
|
||||||
console.log(data);
|
return false;
|
||||||
}
|
}
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function showLoadingDiv() {
|
function showLoadingDiv() {
|
||||||
@@ -238,7 +227,8 @@
|
|||||||
}).on('pre-body.bs.table', function (e, data) {
|
}).on('pre-body.bs.table', function (e, data) {
|
||||||
// 每个data添加一列用来操作
|
// 每个data添加一列用来操作
|
||||||
$(data).each(function (index, item) {
|
$(data).each(function (index, item) {
|
||||||
item.action = "<a class='btn btn-success' target='_blank' href='${baseUrl}onlinePreview?url=" + encodeURIComponent(Base64.encode('${baseUrl}' + item.fileName)) + "'>预览</a>";
|
item.action = "<a class='btn btn-success' target='_blank' href='${baseUrl}onlinePreview?url=" + encodeURIComponent(Base64.encode('${baseUrl}' + item.fileName)) + "'>预览</a>" +
|
||||||
|
"<a class='btn btn-danger' style='margin-left:10px;' href='javascript:void(0);' onclick='deleteFile(\"" + encodeURIComponent(Base64.encode('${baseUrl}' + item.fileName)) + "\")'>删除</a>";
|
||||||
});
|
});
|
||||||
return data;
|
return data;
|
||||||
}).on('post-body.bs.table', function (e, data) {
|
}).on('post-body.bs.table', function (e, data) {
|
||||||
@@ -265,20 +255,9 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
$("#btnSubmit").click(function () {
|
$("#btnSubmit").click(function () {
|
||||||
var _fileName = $("#fileName").text()
|
var filepath = $("#size").val();
|
||||||
var index = _fileName.lastIndexOf(".");
|
if(!checkFileSize(filepath)){
|
||||||
//获取后缀
|
return false;
|
||||||
var ext = _fileName.substr(index + 1);
|
|
||||||
if (!ext || ext == "dll" || ext == "exe" || ext == "msi") {
|
|
||||||
window.alert(ext + "不支持上传")
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!_fileName) {
|
|
||||||
$("#postFileAlert").addClass("show");
|
|
||||||
window.setTimeout(function () {
|
|
||||||
$("#postFileAlert").removeClass("show");
|
|
||||||
}, 3000);//显示的时间
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
showLoadingDiv();
|
showLoadingDiv();
|
||||||
$("#fileUpload").ajaxSubmit({
|
$("#fileUpload").ajaxSubmit({
|
||||||
@@ -294,7 +273,6 @@
|
|||||||
},
|
},
|
||||||
error: function () {
|
error: function () {
|
||||||
alert('上传失败,请联系管理员');
|
alert('上传失败,请联系管理员');
|
||||||
$("#fileName").text("");
|
|
||||||
$(".loading_container").hide();
|
$(".loading_container").hide();
|
||||||
},
|
},
|
||||||
url: 'fileUpload', /*设置post提交到的页面*/
|
url: 'fileUpload', /*设置post提交到的页面*/
|
||||||
@@ -303,6 +281,37 @@
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
function checkFileSize(filepath) {
|
||||||
|
var daxiao= "${size}";
|
||||||
|
daxiao= daxiao.replace("MB","");
|
||||||
|
// console.log(daxiao)
|
||||||
|
var maxsize = daxiao * 1024 * 1024;
|
||||||
|
var errMsg = "上传的文件不能超过${size}喔!!!";
|
||||||
|
var tipMsg = "您的浏览器暂不支持上传,确保上传文件不要超过${size},建议使用IE、FireFox、Chrome浏览器";
|
||||||
|
try {
|
||||||
|
var filesize = 0;
|
||||||
|
var ua = window.navigator.userAgent;
|
||||||
|
if (ua.indexOf("MSIE") >= 1) {
|
||||||
|
//IE
|
||||||
|
var img = new Image();
|
||||||
|
img.src = filepath;
|
||||||
|
filesize = img.fileSize;
|
||||||
|
} else {
|
||||||
|
filesize = $("#size")[0].files[0].size; //byte
|
||||||
|
}
|
||||||
|
if (filesize > 0 && filesize > maxsize) {
|
||||||
|
alert(errMsg);
|
||||||
|
return false;
|
||||||
|
} else if (filesize == -1) {
|
||||||
|
alert(tipMsg);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
alert("上传失败,请重试");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -46,6 +46,47 @@
|
|||||||
<div class="page-header">
|
<div class="page-header">
|
||||||
<h1>版本发布记录</h1>
|
<h1>版本发布记录</h1>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="panel panel-success">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<h3 class="panel-title">2023年04月13日,v4.2.0 版本</h3>
|
||||||
|
</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
<div>
|
||||||
|
1. 新增 SVG 格式文件预览支持<br>
|
||||||
|
2. 新增加密的 Office 文件预览支持<br>
|
||||||
|
3. 新增加密的 zip、rar 等压缩包文件预览支持<br>
|
||||||
|
4. 新增 xmind 软件模型文件预览支持<br>
|
||||||
|
5. 新增 bpmn 工作流模型文件预览支持<br>
|
||||||
|
6. 新增 eml 邮件文件预览支持<br>
|
||||||
|
7. 新增 epub 电子书文件预览支持<br>
|
||||||
|
8. 新增 dotm,ett,xlt,xltm,wpt,dot,xlam,xla,dotx 等格式的办公文档预览支持<br>
|
||||||
|
9. 新增 obj, 3ds, stl, ply, gltf, glb, off, 3dm, fbx, dae, wrl, 3mf, ifc, brep, step, iges, fcstd, bim 等 3D 模型文件预览支持<br>
|
||||||
|
10. 新增可配置限制高风险文件上传的功能,比如 exe 文件<br>
|
||||||
|
11. 新增可配置站点的备案信息<br>
|
||||||
|
12. 新增演示站点删除文件需要密码的功能<br>
|
||||||
|
13. 文本文档预览加入缓存<br>
|
||||||
|
14. 美化 404、500 报错页<br>
|
||||||
|
15. 优化发票等 ofd 文件预览的印证渲染兼容性<br>
|
||||||
|
16. 移除 office-plugin 模块, 使用新版 jodconverter组件<br>
|
||||||
|
17. 优化 Excel 文件的预览效果<br>
|
||||||
|
18. 优化 CAD 文件的预览效果<br>
|
||||||
|
19. 更新 xstream 、junrar、pdfbox 等依赖的版本<br>
|
||||||
|
20. 更新 TIF 文件转换 PDF 的插件,添加转换缓存<br>
|
||||||
|
21. 优化演示页 UI 部署<br>
|
||||||
|
22. 压缩包文件预览支持目录<br>
|
||||||
|
23. 修复部分接口 XSS 问题<br>
|
||||||
|
24. 修复控制台打印的演示地址不跟着 content-path 配置走的问题<br>
|
||||||
|
25. 修复 ofd 文件预览跨域问题<br>
|
||||||
|
26. 修复内部自签证书 https 协议 url 文件无法下载的问题<br>
|
||||||
|
27. 修复特殊符号的文件无法删除的问题<br>
|
||||||
|
28. 修复 PDF 转图片,内存无法回收导致的 OOM<br>
|
||||||
|
29. 修复 xlsx7.4 以上版本文件预览乱码的问题<br>
|
||||||
|
30. 修复 TrustHostFilter 未拦截跨域接口的问题,这是一个安全问题,有使用到 TrustHost 功能的务必升级<br>
|
||||||
|
31. 修复压缩包文件预览在 Linux 系统下文件名乱码的问题<br>
|
||||||
|
32. 修复 ofd 文件预览页码只能显示 10 页的问题<br>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="panel panel-success">
|
<div class="panel panel-success">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<h3 class="panel-title">2022年12月14日,v4.1.0 版本</h3>
|
<h3 class="panel-title">2022年12月14日,v4.1.0 版本</h3>
|
||||||
|
|||||||
@@ -80,7 +80,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- JavaSript ================================================== -->
|
<!-- JavaSript ================================================== -->
|
||||||
<script src="pptx/jquery-3.5.1.min.js"></script>
|
<script src="js/jquery-3.6.1.min.js"></script>
|
||||||
<script src="pptx/jquery.contextMenu.js?v=11.2.5_20210128"></script>
|
<script src="pptx/jquery.contextMenu.js?v=11.2.5_20210128"></script>
|
||||||
<script src="pptx/idocv/idocv_common.min.js"></script>
|
<script src="pptx/idocv/idocv_common.min.js"></script>
|
||||||
<script src="pptx/jquery.mobile-events.min.js"></script>
|
<script src="pptx/jquery.mobile-events.min.js"></script>
|
||||||
|
|||||||
Reference in New Issue
Block a user