Compare commits

...

27 Commits

Author SHA1 Message Date
b1fdbd26a3 新功能点:全部能识别的纯文本直接预览,不用再转跳下载(.md、.java、.py等浏览器不认识的后缀名) 2019-10-25 15:16:25 +08:00
fa7241bd4e 新功能点:所有配置项支持从环境变量里读取,方便Docker镜像部署 2019-10-25 15:16:25 +08:00
8fdf462c6c 新功能点:缓存清理时间cron表达式支持自定义 link #I1147X 2019-10-25 15:16:25 +08:00
f7c7411bcf fixup! 优化:目录调整,符合maven规范;maven编译指定.sh脚本换行符为unix换行 2019-10-25 15:16:25 +08:00
845cb2e657 修复:参数包含特殊字符时url解码失败 2019-10-25 15:16:25 +08:00
a4bfde68bd 优化:目录调整,符合maven规范;maven编译指定.sh脚本换行符为unix换行 2019-10-25 15:16:25 +08:00
19d1ba6cf9 优化:(内部)移除为pdf文档提供base64缩略图 2019-10-25 15:16:25 +08:00
1060bdd00f 新功能点:支持base url配置(主要用于nginx反向代理等) 2019-10-17 11:36:43 +08:00
8c2fb2bdee 优化:默认启用缓存 2019-10-17 11:36:43 +08:00
0fe75387eb 优化:启动脚本加入官网链接,点star推广等文案 close #I1148F 2019-09-16 11:49:49 +08:00
fbea49e54f 优化:加入查看日志脚本 2019-09-16 11:49:49 +08:00
41a72798d9 优化:去除可能导致文件不更新的缓存 2019-09-16 11:49:49 +08:00
03cc185085 修复:压缩包中文件名有空格异常 2019-09-16 11:49:49 +08:00
bfbd8ee25e 新功能点:(内部)为pdf文档提供base64缩略图 2019-09-10 18:24:06 +08:00
f3f36169ff 优化:压缩文件名支持有特殊字符 2019-09-10 18:24:06 +08:00
2df88544d3 修复:macOS下office组件默认路径错误 2019-09-10 18:24:06 +08:00
6b744d77c7 修复:RocksDB缓存实现压缩包图片url缓存失效 2019-09-10 18:24:06 +08:00
ba57dedebb "加入是否启用缓存配置项"后,excel转成的html文件不再转换编码,修复因此出现的乱码问题 2019-08-26 11:17:37 +08:00
affd5b3057 图片和pdf预览模式切换按钮大小调整 2019-08-23 18:18:37 +08:00
30c3128995 修复压缩文件中文fileKey未编码 link #I111PD 2019-08-23 18:18:37 +08:00
b003a05775 加入是否启用缓存配置项 2019-08-23 18:18:37 +08:00
98ec3d7dab 首页预览打开新页面 2019-08-23 18:18:37 +08:00
69e23dbb99 shutdown脚本更新 2019-08-23 18:18:37 +08:00
47bda1023a 修复Chrome76+删除弹出新窗口 2019-08-23 18:18:37 +08:00
fd538a74af 中文语言环境 2019-08-23 18:18:37 +08:00
300d213a7a cdn资源不指定http/https 2019-08-23 18:18:37 +08:00
4c0a70f300 2.2.0迭代 2019-08-23 18:18:37 +08:00
28 changed files with 213 additions and 121 deletions

View File

@ -1,15 +1,17 @@
FROM centos:centos7.6.1810
MAINTAINER chenjh "842761733@qq.com"
ADD jodconverter-web/target/kkFileView-*.tar.gz /opt/
COPY fonts/* /usr/share/fonts/
COPY fonts/* /usr/share/fonts/chienes/
RUN yum install -y kde-l10n-Chinese &&\
yum install -y glibc-common &&\
yum install -y fontconfig &&\
yum install -y mkfontscale &&\
localedef -c -f UTF-8 -i zh_CN zh_CN.utf8 &&\
echo "LANG=zh_CN.UTF-8" > /etc/locale.conf &&\
source /etc/locale.conf &&\
export LANG=zh_CN.UTF-8 &&\
echo "export LANG=zh_CN.UTF-8" >> /etc/locale.conf &&\
LANG="zh_CN.UTF-8" &&\
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime &&\
yum install -y java-1.8.0-openjdk.x86_64 &&\
yum install -y wget &&\
yum install -y libXext.x86_64 &&\
@ -22,10 +24,11 @@ RUN yum install -y kde-l10n-Chinese &&\
rpm -Uvih desktop-integration/openoffice4.1.6-redhat-menus-4.1.6-9790.noarch.rpm &&\
rm -f /tmp/openoffice_rpm.tar.gz &&\
rm -rf /tmp/zh-CN &&\
cd /usr/share/fonts &&\
mkfontscale &&\
cd /usr/share/fonts/chienes &&\
mkfontscale &&\
mkfontdir &&\
fc-cache -fv
ENV LANG zh_CN.UTF-8
ENV LC_ALL zh_CN.UTF-8
ENV KKFILEVIEW_BIN_FOLDER /opt/kkFileView-2.1.2/bin
ENTRYPOINT ["java","-Dfile.encoding=UTF-8","-Dsun.java2d.cmm=sun.java2d.cmm.kcms.KcmsServiceProvider","-Dspring.config.location=/opt/kkFileView-2.1.2/conf/application.properties","-jar","/opt/kkFileView-2.1.2/bin/kkFileView-2.1.2.jar"]
ENV KKFILEVIEW_BIN_FOLDER /opt/kkFileView-2.2.0-SNAPSHOT/bin
ENTRYPOINT ["java","-Dfile.encoding=UTF-8","-Dsun.java2d.cmm=sun.java2d.cmm.kcms.KcmsServiceProvider","-Dspring.config.location=/opt/kkFileView-2.2.0-SNAPSHOT/config/application.properties","-jar","/opt/kkFileView-2.2.0-SNAPSHOT/bin/kkFileView-2.2.0-SNAPSHOT.jar"]

View File

@ -15,6 +15,7 @@ package org.artofsolving.jodconverter.office;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
@ -26,6 +27,8 @@ import com.sun.star.uno.UnoRuntime;
public class OfficeUtils {
public static final String SERVICE_DESKTOP = "com.sun.star.frame.Desktop";
public static final String OFFICE_HOME_KEY = "office.home";
public static final String DEFAULT_OFFICE_HOME_VALUE = "default";
private OfficeUtils() {
throw new AssertionError("utility class must not be instantiated");
@ -69,9 +72,11 @@ public class OfficeUtils {
try {
BufferedReader bufferedReader = new BufferedReader(new FileReader(customizedConfigPath));
properties.load(bufferedReader);
restorePropertiesFromEnvFormat(properties);
} catch (Exception e) {}
if (properties.getProperty("office.home") != null) {
return new File(properties.getProperty("office.home"));
String officeHome = properties.getProperty(OFFICE_HOME_KEY);
if (officeHome != null && !DEFAULT_OFFICE_HOME_VALUE.equals(officeHome)) {
return new File(officeHome);
}
if (PlatformUtils.isWindows()) {
// %ProgramFiles(x86)% on 64-bit machines; %ProgramFiles% on 32-bit ones
@ -116,7 +121,7 @@ public class OfficeUtils {
public static File getOfficeExecutable(File officeHome) {
if (PlatformUtils.isMac()) {
return new File(officeHome, "MacOS/soffice.bin");
return new File(officeHome, "MacOS/soffice");
} else {
return new File(officeHome, "program/soffice.bin");
}
@ -143,8 +148,36 @@ public class OfficeUtils {
public static String getCustomizedConfigPath() {
String homePath = OfficeUtils.getHomePath();
String separator = java.io.File.separator;
String configFilePath = homePath + separator + "conf" + separator + "application.properties";
String configFilePath = homePath + separator + "config" + separator + "application.properties";
return configFilePath;
}
/**
* SpringBoot application.properties 支持从环境变量获取值
* @param properties
*/
public synchronized static void restorePropertiesFromEnvFormat(Properties properties) {
Iterator<Map.Entry<Object, Object>> iterator = properties.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<Object, Object> entry = iterator.next();
String key = entry.getKey().toString();
String value = entry.getValue().toString();
if (value.trim().startsWith("${") && value.trim().endsWith("}")) {
int beginIndex = value.indexOf(":");
if (beginIndex < 0) {
beginIndex = value.length() - 1;
}
int endIndex = value.length() - 1;
String envKey = value.substring(2, beginIndex);
String envValue = System.getenv(envKey);
if (envValue == null || "".equals(envValue.trim())) {
value = value.substring(beginIndex + 1, endIndex);
} else {
value = envValue;
}
properties.setProperty(key, value);
}
}
}
}

View File

@ -12,7 +12,7 @@
<groupId>cn.keking</groupId>
<artifactId>kkFileView</artifactId>
<version>2.1.2</version>
<version>2.2.0-SNAPSHOT</version>
<properties>
@ -194,7 +194,7 @@
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/conf</directory>
<directory>src/main/config</directory>
<excludes>
<exclude>${build.exclude.resource}</exclude>
</excludes>
@ -210,7 +210,7 @@
<configuration>
<appendAssemblyId>false</appendAssemblyId>
<descriptors>
<descriptor>src/main/resources/assembly.xml</descriptor>
<descriptor>src/main/assembly/assembly.xml</descriptor>
</descriptors>
</configuration>
<executions>

View File

@ -11,18 +11,24 @@
<includeBaseDirectory>true</includeBaseDirectory>
<fileSets>
<fileSet>
<directory>src/main/conf</directory>
<outputDirectory>${file.separator}conf</outputDirectory>
<directory>src/main/bin</directory>
<outputDirectory>${file.separator}bin</outputDirectory>
<includes>
<include>*.sh</include>
</includes>
<fileMode>755</fileMode>
<lineEnding>unix</lineEnding>
</fileSet>
<fileSet>
<directory>src/main/bin</directory>
<outputDirectory>${file.separator}bin</outputDirectory>
<fileMode>755</fileMode>
<includes>
<include>*.bat</include>
</includes>
</fileSet>
<fileSet>
<directory>src/main/script</directory>
<outputDirectory>${file.separator}script</outputDirectory>
<fileMode>755</fileMode>
<directory>src/main/config</directory>
<outputDirectory>${file.separator}config</outputDirectory>
</fileSet>
<fileSet>
<directory>src/main/log</directory>

View File

@ -0,0 +1,2 @@
#!/bin/bash
tail -fn 300 ../log/kkFileView.log

View File

@ -1,2 +1,2 @@
#!/bin/bash
kill 15 `ps -ef|grep kkFileView|awk '{print $2}'`
kill -15 `ps -ef|grep kkFileView|awk 'NR==1{print $2}'`

View File

@ -3,5 +3,7 @@ set "KKFILEVIEW_BIN_FOLDER=%cd%"
cd "%KKFILEVIEW_BIN_FOLDER%"
echo Using KKFILEVIEW_BIN_FOLDER %KKFILEVIEW_BIN_FOLDER%
echo Starting kkFileView...
echo Please check log file for more information
java -Dsun.java2d.cmm=sun.java2d.cmm.kcms.KcmsServiceProvider -Dspring.config.location=..\conf\application.properties -jar kkFileView-2.1.2.jar -> ..\log\kkFileView.log
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.0-SNAPSHOT.jar -> ..\log\kkFileView.log

View File

@ -6,7 +6,7 @@ KKFILEVIEW_BIN_FOLDER=$(cd "$(dirname "$0")";pwd)
export KKFILEVIEW_BIN_FOLDER=$KKFILEVIEW_BIN_FOLDER
cd $KKFILEVIEW_BIN_FOLDER
echo "Using KKFILEVIEW_BIN_FOLDER $KKFILEVIEW_BIN_FOLDER"
grep 'office\.home' ../conf/application.properties | grep '!^#'
grep 'office\.home' ../config/application.properties | grep '!^#'
if [ $? -eq 0 ]; then
echo "Using customized office.home"
else
@ -20,11 +20,13 @@ else
done
if [ ! -n "${FLAG}" ]; then
echo "Installing OpenOffice"
sh ../script/install.sh
sh ./install.sh
else
echo "Detected office component has been installed in $OFFICE_HOME"
fi
fi
echo "Starting kkFileView..."
echo "Please check log file for more information"
nohup java -Dfile.encoding=UTF-8 -Dsun.java2d.cmm=sun.java2d.cmm.kcms.KcmsServiceProvider -Dspring.config.location=../conf/application.properties -jar kkFileView-2.1.2.jar > ../log/kkFileView.log 2>&1 &
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.0-SNAPSHOT.jar > ../log/kkFileView.log 2>&1 &

View File

@ -1,5 +1,5 @@
#######################################不可动态配置,需要重启生效#######################################
server.port = 8012
server.port = ${KK_SERVER_PORT:8012}
spring.http.encoding.charset = utf8
## Freemarker 配置
spring.freemarker.template-loader-path = classpath:/web/
@ -19,30 +19,39 @@ spring.http.multipart.max-file-size=100MB
#文件资源路径默认为打包根路径下的file目录下
#file.dir = D:\\kkFileview\\
file.dir = ${KK_FILE_DIR:default}
#openoffice home路径
#office.home = C:\\Program Files (x86)\\OpenOffice 4
office.home = ${KK_OFFICE_HOME:default}
#缓存实现类型不配默认为内嵌RocksDB实现可配置为redis(type = redis)实现需要配置spring.redisson.address等参数和 JDK 内置对象实现type = jdk,
#cache.type = redis
#redis连接
#spring.redisson.address = 192.168.1.204:6379
#spring.redisson.password = xxx
#缓存自动清理(每晚3点自动清理) true 为开启,注释掉或其他值都为关闭
cache.clean = true
#缓存实现类型不配默认为内嵌RocksDB(type = default)实现可配置为redis(type = redis)实现需要配置spring.redisson.address等参数和 JDK 内置对象实现type = jdk,
cache.type = ${KK_CACHE_TYPE:default}
#redis连接只有当cache.type = redis时才有用
spring.redisson.address = ${KK_SPRING_REDISSON_ADDRESS:127.0.0.1:6379}
spring.redisson.password = ${KK_SPRING_REDISSON_PASSWORD:123456}
#缓存是否自动清理 true 为开启,注释掉或其他值都为关闭
cache.clean.enabled = ${KK_CACHE_CLEAN_ENABLED:true}
#缓存自动清理时间cache.clean.enabled = true时才有用cron表达式基于Quartz cron
cache.clean.cron = ${KK_CACHE_CLEAN_CRON:0 0 3 * * ?}
#######################################可在运行时动态配置#######################################
#提供预览服务的地址默认从请求url读如果使用nginx等反向代理需要手动设置
#base.url = https://file.keking.cn
base.url = ${KK_BASE_URL:default}
#是否启用缓存
cache.enabled = ${KK_CACHE_ENABLED:true}
#文本类型,默认如下,可自定义添加
#simText = txt,html,xml,properties,md,java,py,c,cpp,sql
simText = ${KK_SIMTEXT:txt,html,htm,asp,jsp,xml,json,properties,md,gitignore,,java,py,c,cpp,sql,sh,bat,m,bas,prg,cmd}
#多媒体类型,默认如下,可自定义添加
#media = mp3,wav,mp4,flv
#文件转换编码,默认根据操作系统获取
#converted.file.charset = GBK
media = ${KK_MEDIA:mp3,wav,mp4,flv}
#office类型文档(word ppt)样式,默认为图片(image)可配置为pdf预览时也有按钮切换
#office.preview.type = pdf
office.preview.type = ${KK_OFFICE_PREVIEW_TYPE:image}
#预览源为FTP时 FTP用户名可在ftp url后面加参数ftp.username=ftpuser指定不指定默认用配置的
ftp.username = ftpuser
ftp.username = ${KK_FTP_USERNAME:ftpuser}
#预览源为FTP时 FTP密码可在ftp url后面加参数ftp.password=123456指定不指定默认用配置的
ftp.password = 123456
ftp.password = ${KK_FTP_PASSWORD:123456}
#预览源为FTP时, FTP连接默认ControlEncoding(根据FTP服务器操作系统选择Linux一般为UTF-8Windows一般为GBK)可在ftp url后面加参数ftp.control.encoding=UTF-8指定不指定默认用配置的
ftp.control.encoding = UTF-8
ftp.control.encoding = ${KK_FTP_CONTROL_ENCODING:UTF-8}

View File

@ -14,14 +14,25 @@ import java.io.File;
@Component
public class ConfigConstants {
private static Boolean cacheEnabled;
private static String[] simText = {};
private static String[] media = {};
private static String convertedFileCharset;
private static String officePreviewType;
private static String ftpUsername;
private static String ftpPassword;
private static String ftpControlEncoding;
private static String fileDir = OfficeUtils.getHomePath() + File.separator + "file" + File.separator;
private static String baseUrl;
public static final String DEFAULT_FILE_DIR_VALUE = "default";
public static Boolean isCacheEnabled() {
return cacheEnabled;
}
public static void setCacheEnabled(Boolean cacheEnabled) {
ConfigConstants.cacheEnabled = cacheEnabled;
}
public static String[] getSimText() {
return simText;
@ -39,14 +50,6 @@ public class ConfigConstants {
ConfigConstants.media = media;
}
public static String getConvertedFileCharset() {
return convertedFileCharset;
}
public static void setConvertedFileCharset(String convertedFileCharset) {
ConfigConstants.convertedFileCharset = convertedFileCharset;
}
public static String getOfficePreviewType() {
return officePreviewType;
}
@ -83,9 +86,17 @@ public class ConfigConstants {
return fileDir;
}
public static String getBaseUrl() {
return baseUrl;
}
public static void setBaseUrl(String baseUrl) {
ConfigConstants.baseUrl = baseUrl;
}
@Value("${file.dir:default}")
public void setFileDir(String fileDir) {
if (!"default".equals(fileDir)) {
if (!DEFAULT_FILE_DIR_VALUE.equals(fileDir.toLowerCase())) {
if (!fileDir.endsWith(File.separator)) {
fileDir = fileDir + File.separator;
}

View File

@ -22,13 +22,14 @@ public class ConfigRefreshComponent {
private static final Logger LOGGER = LoggerFactory.getLogger(ConfigRefreshComponent.class);
public static final String DEFAULT_TXT_TYPE = "txt,html,xml,properties,md,java,py,c,cpp,sql";
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,,java,py,c,cpp,sql,sh,bat,m,bas,prg,cmd";
public static final String DEFAULT_MEDIA_TYPE = "mp3,wav,mp4,flv";
public static final String DEFAULT_CONVERTER_CHARSET = System.getProperty("sun.jnu.encoding");
public static final String DEFAULT_FTP_USERNAME = null;
public static final String DEFAULT_FTP_PASSWORD = null;
public static final String DEFAULT_FTP_CONTROL_ENCODING = "UTF-8";
public static final String DEFAULT_BASE_URL = "default";
@PostConstruct
void refresh() {
@ -43,34 +44,38 @@ public class ConfigRefreshComponent {
Properties properties = new Properties();
String text;
String media;
Boolean cacheEnabled;
String[] textArray;
String[] mediaArray;
String convertedFileCharset;
String officePreviewType;
String ftpUsername;
String ftpPassword;
String ftpControlEncoding;
String configFilePath = OfficeUtils.getCustomizedConfigPath();
String baseUlr;
while (true) {
FileReader fileReader = new FileReader(configFilePath);
BufferedReader bufferedReader = new BufferedReader(fileReader);
properties.load(bufferedReader);
OfficeUtils.restorePropertiesFromEnvFormat(properties);
cacheEnabled = new Boolean(properties.getProperty("cache.enabled", DEFAULT_CACHE_ENABLED));
text = properties.getProperty("simText", DEFAULT_TXT_TYPE);
media = properties.getProperty("media", DEFAULT_MEDIA_TYPE);
convertedFileCharset = properties.getProperty("converted.file.charset", DEFAULT_CONVERTER_CHARSET);
officePreviewType = properties.getProperty("office.preview.type", OfficeFilePreviewImpl.OFFICE_PREVIEW_TYPE_IMAGE);
ftpUsername = properties.getProperty("ftp.username", DEFAULT_FTP_USERNAME);
ftpPassword = properties.getProperty("ftp.password", DEFAULT_FTP_PASSWORD);
ftpControlEncoding = properties.getProperty("ftp.control.encoding", DEFAULT_FTP_CONTROL_ENCODING);
textArray = text.split(",");
mediaArray = media.split(",");
baseUlr = properties.getProperty("base.url", DEFAULT_BASE_URL);
ConfigConstants.setCacheEnabled(cacheEnabled);
ConfigConstants.setSimText(textArray);
ConfigConstants.setMedia(mediaArray);
ConfigConstants.setConvertedFileCharset(convertedFileCharset);
ConfigConstants.setOfficePreviewType(officePreviewType);
ConfigConstants.setFtpUsername(ftpUsername);
ConfigConstants.setFtpPassword(ftpPassword);
ConfigConstants.setFtpControlEncoding(ftpControlEncoding);
ConfigConstants.setBaseUrl(baseUlr);
bufferedReader.close();
fileReader.close();
Thread.sleep(1000L);

View File

@ -1,5 +1,8 @@
package cn.keking.filters;
import cn.keking.config.ConfigConstants;
import cn.keking.config.ConfigRefreshComponent;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
@ -19,10 +22,20 @@ public class ChinesePathFilter implements Filter {
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
StringBuilder pathBuilder = new StringBuilder();
pathBuilder.append(request.getScheme()).append("://").append(request.getServerName()).append(":")
.append(request.getServerPort()).append(((HttpServletRequest)request).getContextPath()).append("/");
request.setAttribute("baseUrl", pathBuilder.toString());
String baseUrl;
String baseUrlTmp = ConfigConstants.getBaseUrl();
if (baseUrlTmp != null && !ConfigRefreshComponent.DEFAULT_BASE_URL.equals(baseUrlTmp.toLowerCase())) {
if (!baseUrlTmp.endsWith("/")) {
baseUrlTmp = baseUrlTmp.concat("/");
}
baseUrl = baseUrlTmp;
} else {
StringBuilder pathBuilder = new StringBuilder();
pathBuilder.append(request.getScheme()).append("://").append(request.getServerName()).append(":")
.append(request.getServerPort()).append(((HttpServletRequest) request).getContextPath()).append("/");
baseUrl = pathBuilder.toString();
}
request.setAttribute("baseUrl", baseUrl);
chain.doFilter(request, response);
}

View File

@ -92,7 +92,7 @@ public class CacheServiceRocksDBImpl implements CacheService {
try {
Map<String, List<String>> imgCacheItem = getImgCache();
imgCacheItem.put(key, value);
db.put(REDIS_FILE_PREVIEW_PDF_KEY.getBytes(), toByteArray(imgCacheItem));
db.put(REDIS_FILE_PREVIEW_IMGS_KEY.getBytes(), toByteArray(imgCacheItem));
} catch (RocksDBException | IOException e) {
LOGGER.error("Put into RocksDB Exception" + e);
}

View File

@ -1,5 +1,6 @@
package cn.keking.service.impl;
import cn.keking.config.ConfigConstants;
import cn.keking.model.FileAttribute;
import cn.keking.model.ReturnResponse;
import cn.keking.service.FilePreview;
@ -33,7 +34,7 @@ public class CompressFilePreviewImpl implements FilePreview{
String suffix=fileAttribute.getSuffix();
String fileTree = null;
// 判断文件名是否存在(redis缓存读取)
if (!StringUtils.hasText(fileUtils.getConvertedFile(fileName))) {
if (!StringUtils.hasText(fileUtils.getConvertedFile(fileName)) || !ConfigConstants.isCacheEnabled()) {
ReturnResponse<String> response = downloadUtils.downLoad(fileAttribute, fileName);
if (0 != response.getCode()) {
model.addAttribute("fileType", suffix);
@ -48,7 +49,7 @@ public class CompressFilePreviewImpl implements FilePreview{
} else if ("7z".equalsIgnoreCase(suffix)) {
fileTree = zipReader.read7zFile(filePath, fileName);
}
if (fileTree != null && !"null".equals(fileTree)) {
if (fileTree != null && !"null".equals(fileTree) && ConfigConstants.isCacheEnabled()) {
fileUtils.addConvertedFile(fileName, fileTree);
}
} else {

View File

@ -52,29 +52,25 @@ public class OfficeFilePreviewImpl implements FilePreview {
String pdfName = fileName.substring(0, fileName.lastIndexOf(".") + 1) + (isHtml ? "html" : "pdf");
String outFilePath = fileDir + pdfName;
// 判断之前是否已转换过,如果转换过,直接返回,否则执行转换
if (!fileUtils.listConvertedFiles().containsKey(pdfName)) {
if (!fileUtils.listConvertedFiles().containsKey(pdfName) || !ConfigConstants.isCacheEnabled()) {
String filePath = fileDir + fileName;
if (!new File(filePath).exists()) {
ReturnResponse<String> response = downloadUtils.downLoad(fileAttribute, null);
if (0 != response.getCode()) {
model.addAttribute("fileType", suffix);
model.addAttribute("msg", response.getMsg());
return "fileNotSupported";
}
filePath = response.getContent();
ReturnResponse<String> response = downloadUtils.downLoad(fileAttribute, null);
if (0 != response.getCode()) {
model.addAttribute("fileType", suffix);
model.addAttribute("msg", response.getMsg());
return "fileNotSupported";
}
filePath = response.getContent();
if (StringUtils.hasText(outFilePath)) {
officeToPdf.openOfficeToPDF(filePath, outFilePath);
File f = new File(filePath);
if (f.exists()) {
f.delete();
}
if (isHtml) {
// 对转换后的文件进行操作(改变编码方式)
fileUtils.doActionConvertedFile(outFilePath);
}
// 加入缓存
fileUtils.addConvertedFile(pdfName, fileUtils.getRelativePath(outFilePath));
if (ConfigConstants.isCacheEnabled()) {
// 加入缓存
fileUtils.addConvertedFile(pdfName, fileUtils.getRelativePath(outFilePath));
}
}
}
if (!isHtml && originUrl != null && (OFFICE_PREVIEW_TYPE_IMAGE.equals(officePreviewType) || OFFICE_PREVIEW_TYPE_ALLIMAGES.equals(officePreviewType))) {

View File

@ -44,15 +44,13 @@ public class PdfFilePreviewImpl implements FilePreview{
String outFilePath = fileDir + pdfName;
if (OfficeFilePreviewImpl.OFFICE_PREVIEW_TYPE_IMAGE.equals(officePreviewType) || OfficeFilePreviewImpl.OFFICE_PREVIEW_TYPE_ALLIMAGES.equals(officePreviewType)) {
//当文件不存在时,就去下载
if (!new File(outFilePath).exists()) {
ReturnResponse<String> response = downloadUtils.downLoad(fileAttribute, fileName);
if (0 != response.getCode()) {
model.addAttribute("fileType", suffix);
model.addAttribute("msg", response.getMsg());
return "fileNotSupported";
}
outFilePath = response.getContent();
ReturnResponse<String> response = downloadUtils.downLoad(fileAttribute, fileName);
if (0 != response.getCode()) {
model.addAttribute("fileType", suffix);
model.addAttribute("msg", response.getMsg());
return "fileNotSupported";
}
outFilePath = response.getContent();
List<String> imageUrls = pdfUtils.pdf2jpg(outFilePath, pdfName, originUrl);
if (imageUrls == null || imageUrls.size() < 1) {
model.addAttribute("msg", "pdf转图片异常请联系管理员");

View File

@ -9,6 +9,10 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.ui.Model;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
/**
* Created by kl on 2018/1/17.
* Content :处理文本文件
@ -32,7 +36,16 @@ public class SimTextFilePreviewImpl implements FilePreview{
model.addAttribute("fileType",fileAttribute.getSuffix());
return "fileNotSupported";
}
model.addAttribute("ordinaryUrl", response.getMsg());
try {
File originFile = new File(response.getContent());
File previewFile = new File(response.getContent() + ".txt");
Files.copy(originFile.toPath(), previewFile.toPath());
} catch (IOException e) {
model.addAttribute("msg", e.getLocalizedMessage());
model.addAttribute("fileType",fileAttribute.getSuffix());
return "fileNotSupported";
}
model.addAttribute("ordinaryUrl", response.getMsg() + ".txt");
return "txt";
}

View File

@ -46,7 +46,9 @@ public class DownloadUtils {
urlAddress = replacePlusMark(urlAddress);
urlAddress = encodeUrlParam(urlAddress);
// 因为tomcat不能处理'+'号,所以讲'+'号替换成'%20%'
// 也不能处理空格
urlAddress = urlAddress.replaceAll("\\+", "%20");
urlAddress = urlAddress.replaceAll(" ", "%20");
url = new URL(urlAddress);
} catch (MalformedURLException e) {
e.printStackTrace();

View File

@ -12,7 +12,6 @@ import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import java.io.*;
import java.net.URLDecoder;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.HashMap;
@ -26,6 +25,9 @@ import java.util.Map;
*/
@Component
public class FileUtils {
public static final String DEFAULT_CONVERTER_CHARSET = System.getProperty("sun.jnu.encoding");
Logger log= LoggerFactory.getLogger(getClass());
@Autowired
@ -234,9 +236,8 @@ public class FileUtils {
*/
public void doActionConvertedFile(String outFilePath) {
StringBuffer sb = new StringBuffer();
String charset = ConfigConstants.getConvertedFileCharset();
try (InputStream inputStream = new FileInputStream(outFilePath);
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, charset))){
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, DEFAULT_CONVERTER_CHARSET))){
String line;
while(null != (line = reader.readLine())){
if (line.contains("charset=gb2312")) {
@ -247,7 +248,7 @@ public class FileUtils {
// 添加sheet控制头
sb.append("<script src=\"js/jquery-3.0.0.min.js\" type=\"text/javascript\"></script>");
sb.append("<script src=\"js/excel.header.js\" type=\"text/javascript\"></script>");
sb.append("<link rel=\"stylesheet\" href=\"http://cdn.static.runoob.com/libs/bootstrap/3.3.7/css/bootstrap.min.css\">");
sb.append("<link rel=\"stylesheet\" href=\"//cdn.static.runoob.com/libs/bootstrap/3.3.7/css/bootstrap.min.css\">");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
@ -328,26 +329,19 @@ public class FileUtils {
public FileAttribute getFileAttribute(String url) {
String decodedUrl = null;
try {
decodedUrl = URLDecoder.decode(url, "utf-8");
} catch (UnsupportedEncodingException e){
log.error("url解码失败");
}
String fileName;
FileType type;
String suffix;
String fullFileName = getUrlParameterReg(decodedUrl, "fullfilename");
String fullFileName = getUrlParameterReg(url, "fullfilename");
if (!StringUtils.isEmpty(fullFileName)) {
fileName = fullFileName;
type = typeFromFileName(fileName);
suffix = suffixFromFileName(fileName);
} else {
fileName = getFileNameFromURL(decodedUrl);
fileName = getFileNameFromURL(url);
type = typeFromUrl(url);
suffix = suffixFromUrl(url);
}
return new FileAttribute(type,suffix,fileName,url,decodedUrl);
return new FileAttribute(type,suffix,fileName,url,url);
}
}

View File

@ -14,7 +14,7 @@ import org.springframework.stereotype.Component;
* @since: 2019/6/11 7:45
*/
@Component
@ConditionalOnExpression("'${cache.clean:false}'.equals('true')")
@ConditionalOnExpression("'${cache.clean.enabled:false}'.equals('true')")
public class ShedulerClean {
private static final Logger LOGGER = LoggerFactory.getLogger(ShedulerClean.class);
@ -24,7 +24,8 @@ public class ShedulerClean {
private String fileDir = ConfigConstants.getFileDir();
@Scheduled(cron = "0 0 3 * * ?") //每晚3点执行一次
//默认每晚3点执行一次
@Scheduled(cron = "${cache.clean.cron:0 0 3 * * ?}")
public void clean() {
LOGGER.info("Cache clean start");
cacheService.cleanCache();

View File

@ -1,5 +1,6 @@
package cn.keking.web.controller;
import cn.keking.config.ConfigConstants;
import cn.keking.model.FileAttribute;
import cn.keking.service.FilePreview;
import cn.keking.service.FilePreviewFactory;
@ -41,6 +42,8 @@ public class OnlinePreviewController {
@Autowired
private FileUtils fileUtils;
private String fileDir = ConfigConstants.getFileDir();
/**
* @param url
* @param model

View File

@ -1 +0,0 @@
app.id=file-preview

View File

@ -68,7 +68,7 @@
fulls += ",resizable"; // 对于不支持screen属性的浏览器可以手工进行最大化。 manually
}
window.open("onlinePreview?url="
+ encodeURIComponent("${baseUrl}" + treeNode.fileName)+"&fileKey="+treeNode.fileKey, "_blank",fulls);
+ encodeURIComponent("${baseUrl}" + treeNode.fileName)+"&fileKey="+ encodeURIComponent(treeNode.fileKey), "_blank",fulls);
}
}
}

View File

@ -2,11 +2,11 @@
<html lang="en">
<head>
<title>图片预览图</title>
<title>kkFileView演示首页</title>
<link rel="stylesheet" href="css/viewer.min.css">
<link rel="stylesheet" href="css/loading.css">
<link rel="stylesheet" href="http://cdn.static.runoob.com/libs/bootstrap/3.3.7/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-table/1.11.1/bootstrap-table.css" />
<link rel="stylesheet" href="//cdn.static.runoob.com/libs/bootstrap/3.3.7/css/bootstrap.min.css">
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/bootstrap-table/1.11.1/bootstrap-table.css" />
<style type="text/css">
</style>
</head>
@ -117,7 +117,7 @@ window.open('http://127.0.0.1:8012/picturesPreview?urls='+encodeURIComponent(fil
<div style="width: 80%">
<!-- 多说评论框 start -->
<div id="SOHUCS" sid="kkfileView"></div>
<script charset="utf-8" type="text/javascript" src="https://changyan.sohu.com/upload/changyan.js" ></script>
<script charset="utf-8" type="text/javascript" src="//changyan.sohu.com/upload/changyan.js" ></script>
<script type="text/javascript">
window.changyan.api.config({
appid: 'cytx6wU4N',
@ -154,9 +154,9 @@ window.open('http://127.0.0.1:8012/picturesPreview?urls='+encodeURIComponent(fil
</div>
</div>
<script src="js/jquery-3.0.0.min.js" type="text/javascript"></script>
<script src="https://cdn.bootcss.com/jquery.form/3.09/jquery.form.min.js" type="text/javascript"></script>
<script src="http://cdn.static.runoob.com/libs/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-table/1.11.1/bootstrap-table.js"></script>
<script src="//cdn.bootcss.com/jquery.form/3.09/jquery.form.min.js" type="text/javascript"></script>
<script src="//cdn.static.runoob.com/libs/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/bootstrap-table/1.11.1/bootstrap-table.js"></script>
<script>
function deleteFile(fileName) {
$.ajax({
@ -165,7 +165,7 @@ window.open('http://127.0.0.1:8012/picturesPreview?urls='+encodeURIComponent(fil
// 删除完成刷新table
if (1 == data.code) {
alert(data.msg);
}else{
} else{
$('#table').bootstrapTable('refresh', {});
}
},
@ -187,9 +187,8 @@ window.open('http://127.0.0.1:8012/picturesPreview?urls='+encodeURIComponent(fil
}).on('pre-body.bs.table', function (e,data) {
// 每个data添加一列用来操作
$(data).each(function (index, item) {
item.action = "<a class='btn btn-default' target='_blank' href='${baseUrl}onlinePreview?url="
+ encodeURIComponent('${baseUrl}' + item.fileName ) +"'>预览</a>" +
"<a class='btn btn-default' target='_blank' href='javascript:void(0);' onclick='deleteFile(\""+item.fileName+"\")'>删除</a>";
item.action = "<a class='btn btn-default' target='_blank' href='${baseUrl}onlinePreview?url="+ encodeURIComponent('${baseUrl}' + item.fileName ) +"'>预览</a>" +
"<a class='btn btn-default' href='javascript:void(0);' onclick='deleteFile(\""+item.fileName+"\")'>删除</a>";
});
return data;
}).on('post-body.bs.table', function (e,data) {

View File

@ -25,7 +25,7 @@
</#list>
</div>
<#--<img src="images/right.png" style="position: fixed; cursor: pointer; top: 40%; right: 60px; z-index: 999;" alt="使用PDF预览" title="使用PDF预览" onclick="changePreviewType('pdf')"/>-->
<span class="fa fa-file-pdf-o fa-5x" style="position: fixed; cursor: pointer; top: 40%; right: 50px; z-index: 999;" title="使用PDF预览" onclick="changePreviewType('pdf')"></span>
<span class="fa fa-file-pdf-o fa-4x" style="position: fixed; cursor: pointer; top: 40%; right: 50px; z-index: 999;" title="使用PDF预览" onclick="changePreviewType('pdf')"></span>
<script>
window.onload=checkImgs;
window.onscroll = throttle(checkImgs);

View File

@ -20,7 +20,7 @@
<iframe src="" width="100%" frameborder="0"></iframe>
<#-- <img src="images/left.png" style="position: fixed; cursor: pointer; top: 40%; right: 60px; z-index: 999;" alt="使用图片预览" title="使用图片预览" onclick="goForImage()"/>-->
<span class="fa fa-file-image-o fa-5x" style="position: fixed; cursor: pointer; top: 40%; right: 50px; z-index: 999;" title="使用图片预览" onclick="goForImage()"></span>
<span class="fa fa-file-image-o fa-4x" style="position: fixed; cursor: pointer; top: 40%; right: 50px; z-index: 999;" title="使用图片预览" onclick="goForImage()"></span>
</body>

View File

@ -5,7 +5,7 @@
<groupId>cn.keking</groupId>
<artifactId>filepreview</artifactId>
<version>2.1.2</version>
<version>2.2.0-SNAPSHOT</version>
<modules>
<module>jodconverter-core</module>
<module>jodconverter-web</module>