mirror of
https://github.com/kekingcn/kkFileView.git
synced 2026-03-30 13:02:53 +00:00
Compare commits
14 Commits
dependabot
...
pom
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0e86de1e8e | ||
|
|
106036d989 | ||
|
|
026656711d | ||
|
|
35a8c4a5a6 | ||
|
|
86960e3813 | ||
|
|
b099d52520 | ||
|
|
6efe15788c | ||
|
|
3e43c2f9d0 | ||
|
|
f1b949865f | ||
|
|
ab439a17a3 | ||
|
|
dd65564af6 | ||
|
|
acffcbfe98 | ||
|
|
04703aa03c | ||
|
|
584e6b2c77 |
53
.workflow/BranchPipeline.yml
Normal file
53
.workflow/BranchPipeline.yml
Normal file
@@ -0,0 +1,53 @@
|
||||
version: '1.0'
|
||||
name: branch-pipeline
|
||||
displayName: BranchPipeline
|
||||
stages:
|
||||
- stage:
|
||||
name: compile
|
||||
displayName: 编译
|
||||
steps:
|
||||
- step: build@maven
|
||||
name: build_maven
|
||||
displayName: Maven 构建
|
||||
# 支持6、7、8、9、10、11六个版本
|
||||
jdkVersion: 8
|
||||
# 支持2.2.1、3.2.5、3.3.9、3.5.2、3.5.3、3.5.4、3.6.1、3.6.3八个版本
|
||||
mavenVersion: 3.3.9
|
||||
# 构建命令
|
||||
commands:
|
||||
- mvn -B clean package -Dmaven.test.skip=true
|
||||
# 非必填字段,开启后表示将构建产物暂存,但不会上传到制品库中,7天后自动清除
|
||||
artifacts:
|
||||
# 构建产物名字,作为产物的唯一标识可向下传递,支持自定义,默认为BUILD_ARTIFACT。在下游可以通过${BUILD_ARTIFACT}方式引用来获取构建物地址
|
||||
- name: BUILD_ARTIFACT
|
||||
# 构建产物获取路径,是指代码编译完毕之后构建物的所在路径,如通常jar包在target目录下。当前目录为代码库根目录
|
||||
path:
|
||||
- ./server/target
|
||||
- step: publish@general_artifacts
|
||||
name: publish_general_artifacts
|
||||
displayName: 上传制品
|
||||
# 上游构建任务定义的产物名,默认BUILD_ARTIFACT
|
||||
dependArtifact: BUILD_ARTIFACT
|
||||
# 上传到制品库时的制品命名,默认output
|
||||
artifactName: output
|
||||
dependsOn: build_maven
|
||||
- stage:
|
||||
name: release
|
||||
displayName: 发布
|
||||
steps:
|
||||
- step: publish@release_artifacts
|
||||
name: publish_release_artifacts
|
||||
displayName: '发布'
|
||||
# 上游上传制品任务的产出
|
||||
dependArtifact: output
|
||||
# 发布制品版本号
|
||||
version: '1.0.0.0'
|
||||
# 是否开启版本号自增,默认开启
|
||||
autoIncrement: true
|
||||
triggers:
|
||||
push:
|
||||
branches:
|
||||
exclude:
|
||||
- master
|
||||
include:
|
||||
- .*
|
||||
51
.workflow/MasterPipeline.yml
Normal file
51
.workflow/MasterPipeline.yml
Normal file
@@ -0,0 +1,51 @@
|
||||
version: '1.0'
|
||||
name: master-pipeline
|
||||
displayName: MasterPipeline
|
||||
stages:
|
||||
- stage:
|
||||
name: compile
|
||||
displayName: 编译
|
||||
steps:
|
||||
- step: build@maven
|
||||
name: build_maven
|
||||
displayName: Maven 构建
|
||||
# 支持6、7、8、9、10、11六个版本
|
||||
jdkVersion: 8
|
||||
# 支持2.2.1、3.2.5、3.3.9、3.5.2、3.5.3、3.5.4、3.6.1、3.6.3八个版本
|
||||
mavenVersion: 3.3.9
|
||||
# 构建命令
|
||||
commands:
|
||||
- mvn -B clean package -Dmaven.test.skip=true
|
||||
# 非必填字段,开启后表示将构建产物暂存,但不会上传到制品库中,7天后自动清除
|
||||
artifacts:
|
||||
# 构建产物名字,作为产物的唯一标识可向下传递,支持自定义,默认为BUILD_ARTIFACT。在下游可以通过${BUILD_ARTIFACT}方式引用来获取构建物地址
|
||||
- name: BUILD_ARTIFACT
|
||||
# 构建产物获取路径,是指代码编译完毕之后构建物的所在路径,如通常jar包在target目录下。当前目录为代码库根目录
|
||||
path:
|
||||
- ./server/target
|
||||
- step: publish@general_artifacts
|
||||
name: publish_general_artifacts
|
||||
displayName: 上传制品
|
||||
# 上游构建任务定义的产物名,默认BUILD_ARTIFACT
|
||||
dependArtifact: BUILD_ARTIFACT
|
||||
# 上传到制品库时的制品命名,默认output
|
||||
artifactName: output
|
||||
dependsOn: build_maven
|
||||
- stage:
|
||||
name: release
|
||||
displayName: 发布
|
||||
steps:
|
||||
- step: publish@release_artifacts
|
||||
name: publish_release_artifacts
|
||||
displayName: '发布'
|
||||
# 上游上传制品任务的产出
|
||||
dependArtifact: output
|
||||
# 发布制品版本号
|
||||
version: '1.0.0.0'
|
||||
# 是否开启版本号自增,默认开启
|
||||
autoIncrement: true
|
||||
triggers:
|
||||
push:
|
||||
branches:
|
||||
include:
|
||||
- master
|
||||
40
.workflow/PRPipeline.yml
Normal file
40
.workflow/PRPipeline.yml
Normal file
@@ -0,0 +1,40 @@
|
||||
version: '1.0'
|
||||
name: pr-pipeline
|
||||
displayName: PRPipeline
|
||||
stages:
|
||||
- stage:
|
||||
name: compile
|
||||
displayName: 编译
|
||||
steps:
|
||||
- step: build@maven
|
||||
name: build_maven
|
||||
displayName: Maven 构建
|
||||
# 支持6、7、8、9、10、11六个版本
|
||||
jdkVersion: 8
|
||||
# 支持2.2.1、3.2.5、3.3.9、3.5.2、3.5.3、3.5.4、3.6.1、3.6.3八个版本
|
||||
mavenVersion: 3.3.9
|
||||
# 构建命令
|
||||
commands:
|
||||
- mvn -B clean package -Dmaven.test.skip=true
|
||||
# 非必填字段,开启后表示将构建产物暂存,但不会上传到制品库中,7天后自动清除
|
||||
artifacts:
|
||||
# 构建产物名字,作为产物的唯一标识可向下传递,支持自定义,默认为BUILD_ARTIFACT。在下游可以通过${BUILD_ARTIFACT}方式引用来获取构建物地址
|
||||
- name: BUILD_ARTIFACT
|
||||
# 构建产物获取路径,是指代码编译完毕之后构建物的所在路径,如通常jar包在target目录下。当前目录为代码库根目录
|
||||
path:
|
||||
- ./server/target
|
||||
- step: publish@general_artifacts
|
||||
name: publish_general_artifacts
|
||||
displayName: 上传制品
|
||||
# 上游构建任务定义的产物名,默认BUILD_ARTIFACT
|
||||
dependArtifact: BUILD_ARTIFACT
|
||||
# 构建产物制品库,默认default,系统默认创建
|
||||
artifactRepository: default
|
||||
# 上传到制品库时的制品命名,默认output
|
||||
artifactName: output
|
||||
dependsOn: build_maven
|
||||
triggers:
|
||||
pr:
|
||||
branches:
|
||||
include:
|
||||
- master
|
||||
36
.workflow/pipeline-20220716.yml
Normal file
36
.workflow/pipeline-20220716.yml
Normal file
@@ -0,0 +1,36 @@
|
||||
version: '1.0'
|
||||
name: pipeline-20220716
|
||||
displayName: pipeline-20220716
|
||||
triggers:
|
||||
trigger: manual
|
||||
push:
|
||||
branches:
|
||||
prefix:
|
||||
- ''
|
||||
stages:
|
||||
- name: stage-8b46aafe
|
||||
displayName: 未命名
|
||||
strategy: naturally
|
||||
trigger: auto
|
||||
executor: []
|
||||
steps:
|
||||
- step: build@maven
|
||||
name: build_maven
|
||||
displayName: Maven 构建
|
||||
jdkVersion: '8'
|
||||
mavenVersion: 3.3.9
|
||||
commands:
|
||||
- mvn -B clean package -Dmaven.test.skip=true
|
||||
artifacts:
|
||||
- name: BUILD_ARTIFACT
|
||||
path:
|
||||
- ./server/target
|
||||
settings: []
|
||||
caches:
|
||||
- ~/.m2
|
||||
notify: []
|
||||
strategy:
|
||||
retry: '0'
|
||||
permissions:
|
||||
- role: admin
|
||||
members: []
|
||||
39
Dockerfile
39
Dockerfile
@@ -1,42 +1,5 @@
|
||||
FROM ubuntu:20.04
|
||||
FROM keking/kkfileview-jdk:4.1.1
|
||||
MAINTAINER chenjh "842761733@qq.com"
|
||||
ADD server/target/kkFileView-*.tar.gz /opt/
|
||||
COPY fonts/* /usr/share/fonts/chinese/
|
||||
RUN echo "deb http://mirrors.aliyun.com/ubuntu/ focal main restricted universe multiverse\ndeb-src http://mirrors.aliyun.com/ubuntu/ focal main restricted universe multiverse\ndeb http://mirrors.aliyun.com/ubuntu/ focal-security main restricted universe multiverse\ndeb-src http://mirrors.aliyun.com/ubuntu/ focal-security main restricted universe multiverse\ndeb http://mirrors.aliyun.com/ubuntu/ focal-updates main restricted universe multiverse\ndeb-src http://mirrors.aliyun.com/ubuntu/ focal-updates main restricted universe multiverse\ndeb http://mirrors.aliyun.com/ubuntu/ focal-proposed main restricted universe multiverse\ndeb-src http://mirrors.aliyun.com/ubuntu/ focal-proposed main restricted universe multiverse\ndeb http://mirrors.aliyun.com/ubuntu/ focal-backports main restricted universe multiverse\ndeb-src http://mirrors.aliyun.com/ubuntu/ focal-backports main restricted universe multiverse" > /etc/apt/sources.list &&\
|
||||
apt-get clean && apt-get update &&\
|
||||
apt-get install -y locales && apt-get install -y language-pack-zh-hans &&\
|
||||
localedef -i zh_CN -c -f UTF-8 -A /usr/share/locale/locale.alias zh_CN.UTF-8 && locale-gen zh_CN.UTF-8 &&\
|
||||
export DEBIAN_FRONTEND=noninteractive &&\
|
||||
apt-get install -y tzdata && ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime &&\
|
||||
apt-get install -y libxrender1 && apt-get install -y libxt6 && apt-get install -y libxext-dev && apt-get install -y libfreetype6-dev &&\
|
||||
apt-get install -y wget && apt-get install -y ttf-mscorefonts-installer && apt-get install -y fontconfig &&\
|
||||
apt-get install ttf-wqy-microhei &&\
|
||||
apt-get install ttf-wqy-zenhei &&\
|
||||
apt-get install xfonts-wqy &&\
|
||||
cd /tmp &&\
|
||||
wget https://kkfileview.keking.cn/server-jre-8u251-linux-x64.tar.gz &&\
|
||||
tar -zxf /tmp/server-jre-8u251-linux-x64.tar.gz && mv /tmp/jdk1.8.0_251 /usr/local/ &&\
|
||||
|
||||
# 安装 OpenOffice
|
||||
# wget https://kkfileview.keking.cn/Apache_OpenOffice_4.1.6_Linux_x86-64_install-deb_zh-CN.tar.gz -cO openoffice_deb.tar.gz &&\
|
||||
# tar -zxf /tmp/openoffice_deb.tar.gz && cd /tmp/zh-CN/DEBS &&\
|
||||
# dpkg -i *.deb && dpkg -i desktop-integration/openoffice4.1-debian-menus_4.1.6-9790_all.deb &&\
|
||||
|
||||
# 安装 libreoffice
|
||||
apt-get install -y libxinerama1 libcairo2 libcups2 libx11-xcb1 &&\
|
||||
wget https://kkfileview.keking.cn/LibreOffice_7.1.4_Linux_x86-64_deb.tar.gz -cO libreoffice_deb.tar.gz &&\
|
||||
tar -zxf /tmp/libreoffice_deb.tar.gz && cd /tmp/LibreOffice_7.1.4.2_Linux_x86-64_deb/DEBS &&\
|
||||
dpkg -i *.deb &&\
|
||||
|
||||
rm -rf /tmp/* && rm -rf /var/lib/apt/lists/* &&\
|
||||
cd /usr/share/fonts/chinese &&\
|
||||
mkfontscale &&\
|
||||
mkfontdir &&\
|
||||
fc-cache -fv
|
||||
ENV JAVA_HOME /usr/local/jdk1.8.0_251
|
||||
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
|
||||
ENV PATH $PATH:$JAVA_HOME/bin
|
||||
ENV LANG zh_CN.UTF-8
|
||||
ENV LC_ALL zh_CN.UTF-8
|
||||
ENV KKFILEVIEW_BIN_FOLDER /opt/kkFileView-4.1.0-SNAPSHOT/bin
|
||||
ENTRYPOINT ["java","-Dfile.encoding=UTF-8","-Dspring.config.location=/opt/kkFileView-4.1.0-SNAPSHOT/config/application.properties","-jar","/opt/kkFileView-4.1.0-SNAPSHOT/bin/kkFileView-4.1.0-SNAPSHOT.jar"]
|
||||
38
docker/kkfileview-jdk/Dockerfile
Normal file
38
docker/kkfileview-jdk/Dockerfile
Normal file
@@ -0,0 +1,38 @@
|
||||
FROM ubuntu:20.04
|
||||
MAINTAINER chenjh "842761733@qq.com"
|
||||
# 内置一些常用的中文字体,避免普遍性乱码
|
||||
COPY fonts/* /usr/share/fonts/chinese/
|
||||
RUN echo "deb http://mirrors.aliyun.com/ubuntu/ focal main restricted universe multiverse\ndeb-src http://mirrors.aliyun.com/ubuntu/ focal main restricted universe multiverse\ndeb http://mirrors.aliyun.com/ubuntu/ focal-security main restricted universe multiverse\ndeb-src http://mirrors.aliyun.com/ubuntu/ focal-security main restricted universe multiverse\ndeb http://mirrors.aliyun.com/ubuntu/ focal-updates main restricted universe multiverse\ndeb-src http://mirrors.aliyun.com/ubuntu/ focal-updates main restricted universe multiverse\ndeb http://mirrors.aliyun.com/ubuntu/ focal-proposed main restricted universe multiverse\ndeb-src http://mirrors.aliyun.com/ubuntu/ focal-proposed main restricted universe multiverse\ndeb http://mirrors.aliyun.com/ubuntu/ focal-backports main restricted universe multiverse\ndeb-src http://mirrors.aliyun.com/ubuntu/ focal-backports main restricted universe multiverse" > /etc/apt/sources.list &&\
|
||||
apt-get clean && apt-get update &&\
|
||||
apt-get install -y locales && apt-get install -y language-pack-zh-hans &&\
|
||||
localedef -i zh_CN -c -f UTF-8 -A /usr/share/locale/locale.alias zh_CN.UTF-8 && locale-gen zh_CN.UTF-8 &&\
|
||||
export DEBIAN_FRONTEND=noninteractive &&\
|
||||
apt-get install -y tzdata && ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime &&\
|
||||
apt-get install -y libxrender1 && apt-get install -y libxt6 && apt-get install -y libxext-dev && apt-get install -y libfreetype6-dev &&\
|
||||
apt-get install -y wget && apt-get install -y ttf-mscorefonts-installer && apt-get install -y fontconfig &&\
|
||||
apt-get install ttf-wqy-microhei &&\
|
||||
apt-get install ttf-wqy-zenhei &&\
|
||||
apt-get install xfonts-wqy &&\
|
||||
cd /tmp &&\
|
||||
wget https://kkfileview.keking.cn/server-jre-8u251-linux-x64.tar.gz &&\
|
||||
tar -zxf /tmp/server-jre-8u251-linux-x64.tar.gz && mv /tmp/jdk1.8.0_251 /usr/local/ &&\
|
||||
|
||||
# 安装 libreoffice
|
||||
apt-get install -y libxinerama1 libcairo2 libcups2 libx11-xcb1 &&\
|
||||
wget https://kkfileview.keking.cn/LibreOffice_7.1.4_Linux_x86-64_deb.tar.gz -cO libreoffice_deb.tar.gz &&\
|
||||
tar -zxf /tmp/libreoffice_deb.tar.gz && cd /tmp/LibreOffice_7.1.4.2_Linux_x86-64_deb/DEBS &&\
|
||||
dpkg -i *.deb &&\
|
||||
|
||||
# 清理临时文件
|
||||
rm -rf /tmp/* && rm -rf /var/lib/apt/lists/* &&\
|
||||
cd /usr/share/fonts/chinese &&\
|
||||
mkfontscale &&\
|
||||
mkfontdir &&\
|
||||
fc-cache -fv
|
||||
|
||||
ENV JAVA_HOME /usr/local/jdk1.8.0_251
|
||||
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
|
||||
ENV PATH $PATH:$JAVA_HOME/bin
|
||||
ENV LANG zh_CN.UTF-8
|
||||
ENV LC_ALL zh_CN.UTF-8
|
||||
ENTRYPOINT ["java","-version"]
|
||||
2
docker/kkfileview-jdk/docker build.txt
Normal file
2
docker/kkfileview-jdk/docker build.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
# 执行如下命令构建基础镜像,加快kkfileview docker镜像构建与发布
|
||||
docker build --tag keking/kkfileview-jdk:4.1.1 .
|
||||
@@ -3,7 +3,6 @@
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<artifactId>kkFileView-parent</artifactId>
|
||||
<groupId>cn.keking</groupId>
|
||||
@@ -27,19 +26,9 @@
|
||||
<version>2.7</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openoffice</groupId>
|
||||
<artifactId>juh</artifactId>
|
||||
<version>3.2.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openoffice</groupId>
|
||||
<artifactId>ridl</artifactId>
|
||||
<version>3.2.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.openoffice</groupId>
|
||||
<artifactId>unoil</artifactId>
|
||||
<version>3.2.1</version>
|
||||
<groupId>org.libreoffice</groupId>
|
||||
<artifactId>libreoffice</artifactId>
|
||||
<version>7.1.4</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<!-- for the command line tool -->
|
||||
|
||||
@@ -12,18 +12,6 @@
|
||||
//
|
||||
package org.artofsolving.jodconverter;
|
||||
|
||||
import static org.artofsolving.jodconverter.office.OfficeUtils.SERVICE_DESKTOP;
|
||||
import static org.artofsolving.jodconverter.office.OfficeUtils.cast;
|
||||
import static org.artofsolving.jodconverter.office.OfficeUtils.toUnoProperties;
|
||||
import static org.artofsolving.jodconverter.office.OfficeUtils.toUrl;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Map;
|
||||
|
||||
import org.artofsolving.jodconverter.office.OfficeContext;
|
||||
import org.artofsolving.jodconverter.office.OfficeException;
|
||||
import org.artofsolving.jodconverter.office.OfficeTask;
|
||||
|
||||
import com.sun.star.frame.XComponentLoader;
|
||||
import com.sun.star.frame.XStorable;
|
||||
import com.sun.star.io.IOException;
|
||||
@@ -32,6 +20,14 @@ import com.sun.star.lang.XComponent;
|
||||
import com.sun.star.task.ErrorCodeIOException;
|
||||
import com.sun.star.util.CloseVetoException;
|
||||
import com.sun.star.util.XCloseable;
|
||||
import org.artofsolving.jodconverter.office.OfficeContext;
|
||||
import org.artofsolving.jodconverter.office.OfficeException;
|
||||
import org.artofsolving.jodconverter.office.OfficeTask;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.artofsolving.jodconverter.office.OfficeUtils.*;
|
||||
|
||||
public abstract class AbstractConversionTask implements OfficeTask {
|
||||
|
||||
@@ -47,6 +43,7 @@ public abstract class AbstractConversionTask implements OfficeTask {
|
||||
|
||||
protected abstract Map<String,?> getStoreProperties(File outputFile, XComponent document);
|
||||
|
||||
@Override
|
||||
public void execute(OfficeContext context) throws OfficeException {
|
||||
XComponent document = null;
|
||||
try {
|
||||
@@ -79,6 +76,7 @@ public abstract class AbstractConversionTask implements OfficeTask {
|
||||
}
|
||||
XComponentLoader loader = cast(XComponentLoader.class, context.getService(SERVICE_DESKTOP));
|
||||
Map<String,?> loadProperties = getLoadProperties(inputFile);
|
||||
|
||||
XComponent document = null;
|
||||
try {
|
||||
document = loader.loadComponentFromURL(toUrl(inputFile), "_blank", 0, toUnoProperties(loadProperties));
|
||||
|
||||
@@ -12,18 +12,18 @@
|
||||
//
|
||||
package org.artofsolving.jodconverter;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.sun.star.document.UpdateDocMode;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.artofsolving.jodconverter.document.DefaultDocumentFormatRegistry;
|
||||
import org.artofsolving.jodconverter.document.DocumentFormat;
|
||||
import org.artofsolving.jodconverter.document.DocumentFormatRegistry;
|
||||
import org.artofsolving.jodconverter.model.FileProperties;
|
||||
import org.artofsolving.jodconverter.office.OfficeException;
|
||||
import org.artofsolving.jodconverter.office.OfficeManager;
|
||||
|
||||
import com.sun.star.document.UpdateDocMode;
|
||||
import java.io.File;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class OfficeDocumentConverter {
|
||||
|
||||
@@ -60,14 +60,22 @@ public class OfficeDocumentConverter {
|
||||
public void convert(File inputFile, File outputFile) throws OfficeException {
|
||||
String outputExtension = FilenameUtils.getExtension(outputFile.getName());
|
||||
DocumentFormat outputFormat = formatRegistry.getFormatByExtension(outputExtension);
|
||||
convert(inputFile, outputFile, outputFormat);
|
||||
convert(inputFile, outputFile, outputFormat, null);
|
||||
}
|
||||
|
||||
public void convert(File inputFile, File outputFile, DocumentFormat outputFormat) throws OfficeException {
|
||||
public void convert(File inputFile, File outputFile, FileProperties fileProperties) throws OfficeException {
|
||||
String outputExtension = FilenameUtils.getExtension(outputFile.getName());
|
||||
DocumentFormat outputFormat = formatRegistry.getFormatByExtension(outputExtension);
|
||||
convert(inputFile, outputFile, outputFormat, fileProperties);
|
||||
}
|
||||
|
||||
public void convert(File inputFile, File outputFile, DocumentFormat outputFormat, FileProperties fileProperties) throws OfficeException {
|
||||
String inputExtension = FilenameUtils.getExtension(inputFile.getName());
|
||||
DocumentFormat inputFormat = formatRegistry.getFormatByExtension(inputExtension);
|
||||
Map<String, Object> properties = fileProperties.toMap();
|
||||
properties.putAll(defaultLoadProperties);
|
||||
StandardConversionTask conversionTask = new StandardConversionTask(inputFile, outputFile, outputFormat);
|
||||
conversionTask.setDefaultLoadProperties(defaultLoadProperties);
|
||||
conversionTask.setDefaultLoadProperties(properties);
|
||||
conversionTask.setInputFormat(inputFormat);
|
||||
officeManager.execute(conversionTask);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
package org.artofsolving.jodconverter.model;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Created by kl on 2018/1/17.
|
||||
* Content :
|
||||
*/
|
||||
public class FileProperties {
|
||||
|
||||
private String filePassword;
|
||||
|
||||
public FileProperties() {
|
||||
}
|
||||
|
||||
public Map<String, Object> toMap() {
|
||||
Map<String, Object> map = new HashMap();
|
||||
if (filePassword != null) {
|
||||
map.put("Password", filePassword);
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
public String getFilePassword() {
|
||||
return filePassword;
|
||||
}
|
||||
|
||||
public void setFilePassword(String filePassword) {
|
||||
this.filePassword = filePassword;
|
||||
}
|
||||
|
||||
}
|
||||
25
pom.xml
25
pom.xml
@@ -10,9 +10,34 @@
|
||||
|
||||
<properties>
|
||||
<java.version>1.8</java.version>
|
||||
|
||||
<spring.boot.version>2.4.2</spring.boot.version>
|
||||
<poi.version>5.2.2</poi.version>
|
||||
<xdocreport.version>1.0.6</xdocreport.version>
|
||||
<xstream.version>1.4.19</xstream.version>
|
||||
<junrar.version>7.4.1</junrar.version>
|
||||
<redisson.version>3.2.0</redisson.version>
|
||||
<sevenzipjbinding.version>16.02-2.01</sevenzipjbinding.version>
|
||||
<tukaani.version>1.8</tukaani.version>
|
||||
<jchardet.version>1.0</jchardet.version>
|
||||
<antlr.version>2.7.7</antlr.version>
|
||||
<concurrentlinkedhashmap.version>1.4.2</concurrentlinkedhashmap.version>
|
||||
<rocksdb.version>5.17.2</rocksdb.version>
|
||||
<pdfbox.version>2.0.26</pdfbox.version>
|
||||
<galimatias.version>0.2.1</galimatias.version>
|
||||
<bytedeco.version>1.5.2</bytedeco.version>
|
||||
<opencv.version>4.1.2-1.5.2</opencv.version>
|
||||
<openblas.version>0.3.6-1.5.1</openblas.version>
|
||||
<ffmpeg.version>4.2.1-1.5.2</ffmpeg.version>
|
||||
<itext.version>2.1.7</itext.version>
|
||||
<commons-cli.version>1.2</commons-cli.version>
|
||||
<commons-net.version>3.6</commons-net.version>
|
||||
<commons-lang3.version>3.7</commons-lang3.version>
|
||||
<commons-compress.version>1.21</commons-compress.version>
|
||||
|
||||
<maven.compiler.source>${java.version}</maven.compiler.source>
|
||||
<maven.compiler.target>${java.version}</maven.compiler.target>
|
||||
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
</properties>
|
||||
|
||||
167
server/pom.xml
167
server/pom.xml
@@ -25,20 +25,12 @@
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-freemarker</artifactId>
|
||||
</dependency>
|
||||
<!-- 对 rar5 的支持 和其他众多压缩支持 可参考 package net.sf.sevenzipjbinding.ArchiveFormat; -->
|
||||
<dependency>
|
||||
<groupId>net.sf.sevenzipjbinding</groupId>
|
||||
<artifactId>sevenzipjbinding</artifactId>
|
||||
<version>16.02-2.01</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.sf.sevenzipjbinding</groupId>
|
||||
<artifactId>sevenzipjbinding-all-platforms</artifactId>
|
||||
<version>16.02-2.01</version>
|
||||
<groupId>cn.keking</groupId>
|
||||
<artifactId>office-plugin</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- web start -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
@@ -53,42 +45,32 @@
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-jetty</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.keking</groupId>
|
||||
<artifactId>office-plugin</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>3.7</version>
|
||||
</dependency>
|
||||
<!-- REDISSON -->
|
||||
<dependency>
|
||||
<groupId>org.redisson</groupId>
|
||||
<artifactId>redisson</artifactId>
|
||||
<version>3.2.0</version>
|
||||
<artifactId>spring-boot-starter-freemarker</artifactId>
|
||||
</dependency>
|
||||
<!-- web end -->
|
||||
|
||||
<!-- poi start -->
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>poi</artifactId>
|
||||
<version>4.1.1</version>
|
||||
<version>${poi.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>poi-scratchpad</artifactId>
|
||||
<version>3.12</version>
|
||||
<version>${poi.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>poi-ooxml</artifactId>
|
||||
<version>${poi.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>fr.opensagres.xdocreport</groupId>
|
||||
<artifactId>org.apache.poi.xwpf.converter.core</artifactId>
|
||||
<version>1.0.5</version>
|
||||
<version>${xdocreport.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>poi</artifactId>
|
||||
@@ -99,88 +81,102 @@
|
||||
<dependency>
|
||||
<groupId>fr.opensagres.xdocreport</groupId>
|
||||
<artifactId>org.apache.poi.xwpf.converter.xhtml</artifactId>
|
||||
<version>1.0.5</version>
|
||||
<version>${xdocreport.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>fr.opensagres.xdocreport</groupId>
|
||||
<artifactId>fr.opensagres.xdocreport.document</artifactId>
|
||||
<version>1.0.5</version>
|
||||
<version>${xdocreport.version}</version>
|
||||
</dependency>
|
||||
<!-- poi start -->
|
||||
|
||||
<!-- 对 rar5 的支持 和其他众多压缩支持 可参考 package net.sf.sevenzipjbinding.ArchiveFormat; -->
|
||||
<dependency>
|
||||
<groupId>net.sf.sevenzipjbinding</groupId>
|
||||
<artifactId>sevenzipjbinding</artifactId>
|
||||
<version>${sevenzipjbinding.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.sf.sevenzipjbinding</groupId>
|
||||
<artifactId>sevenzipjbinding-all-platforms</artifactId>
|
||||
<version>${sevenzipjbinding.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>${commons-lang3.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.redisson</groupId>
|
||||
<artifactId>redisson</artifactId>
|
||||
<version>${redisson.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 解压(apache) -->
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-compress</artifactId>
|
||||
<version>1.21</version>
|
||||
<version>${commons-compress.version}</version>
|
||||
</dependency>
|
||||
<!-- 解压(rar)-->
|
||||
<dependency>
|
||||
<groupId>com.github.junrar</groupId>
|
||||
<artifactId>junrar</artifactId>
|
||||
<version>4.0.0</version>
|
||||
<version>${junrar.version}</version>
|
||||
</dependency>
|
||||
<!-- 解压(7z)-->
|
||||
<dependency>
|
||||
<groupId>org.tukaani</groupId>
|
||||
<artifactId>xz</artifactId>
|
||||
<version>1.8</version>
|
||||
<version>${tukaani.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.sourceforge.jchardet</groupId>
|
||||
<artifactId>jchardet</artifactId>
|
||||
<version>1.0</version>
|
||||
<version>${jchardet.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>antlr</groupId>
|
||||
<artifactId>antlr</artifactId>
|
||||
<version>2.7.7</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-httpclient</groupId>
|
||||
<artifactId>commons-httpclient</artifactId>
|
||||
<version>3.1</version>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
<groupId>commons-logging</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
<version>${antlr.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-cli</groupId>
|
||||
<artifactId>commons-cli</artifactId>
|
||||
<version>1.2</version>
|
||||
<version>${commons-cli.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- FTP -->
|
||||
<dependency>
|
||||
<groupId>commons-net</groupId>
|
||||
<artifactId>commons-net</artifactId>
|
||||
<version>3.6</version>
|
||||
<version>${commons-net.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.thoughtworks.xstream</groupId>
|
||||
<artifactId>xstream</artifactId>
|
||||
<version>1.4.18</version>
|
||||
<version>${xstream.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.googlecode.concurrentlinkedhashmap</groupId>
|
||||
<artifactId>concurrentlinkedhashmap-lru</artifactId>
|
||||
<version>1.4.2</version>
|
||||
<version>${concurrentlinkedhashmap.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.rocksdb</groupId>
|
||||
<artifactId>rocksdbjni</artifactId>
|
||||
<version>5.17.2</version>
|
||||
<version>${rocksdb.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.pdfbox</groupId>
|
||||
<artifactId>pdfbox</artifactId>
|
||||
<version>2.0.24</version>
|
||||
<version>${pdfbox.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.pdfbox</groupId>
|
||||
<artifactId>pdfbox-tools</artifactId>
|
||||
<version>2.0.15</version>
|
||||
<version>${pdfbox.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.aspose</groupId>
|
||||
@@ -201,70 +197,62 @@
|
||||
<dependency>
|
||||
<groupId>io.mola.galimatias</groupId>
|
||||
<artifactId>galimatias</artifactId>
|
||||
<version>0.2.1</version>
|
||||
<version>${galimatias.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 以下是bytedeco 基于opencv ffmpeg封装的javacv,用于视频处理 -->
|
||||
<dependency>
|
||||
<groupId>org.bytedeco</groupId>
|
||||
<artifactId>javacv</artifactId>
|
||||
<version>1.5.2</version>
|
||||
<version>${bytedeco.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.bytedeco</groupId>
|
||||
<artifactId>javacpp</artifactId>
|
||||
<version>1.5.2</version>
|
||||
<version>${bytedeco.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 此版本中主要兼容linux和windows系统,如需兼容其他系统平台,请引入对应依赖即可 -->
|
||||
<dependency>
|
||||
<groupId>org.bytedeco</groupId>
|
||||
<artifactId>opencv</artifactId>
|
||||
<version>4.1.2-1.5.2</version>
|
||||
<version>${opencv.version}</version>
|
||||
<classifier>linux-x86_64</classifier>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.bytedeco</groupId>
|
||||
<artifactId>opencv</artifactId>
|
||||
<version>4.1.2-1.5.2</version>
|
||||
<version>${opencv.version}</version>
|
||||
<classifier>windows-x86_64</classifier>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.bytedeco</groupId>
|
||||
<artifactId>openblas</artifactId>
|
||||
<version>0.3.6-1.5.1</version>
|
||||
<version>${openblas.version}</version>
|
||||
<classifier>linux-x86_64</classifier>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.bytedeco</groupId>
|
||||
<artifactId>openblas</artifactId>
|
||||
<version>0.3.6-1.5.1</version>
|
||||
<version>${openblas.version}</version>
|
||||
<classifier>windows-x86_64</classifier>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.bytedeco</groupId>
|
||||
<artifactId>ffmpeg</artifactId>
|
||||
<version>4.2.1-1.5.2</version>
|
||||
<version>${ffmpeg.version}</version>
|
||||
<classifier>linux-x86_64</classifier>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.bytedeco</groupId>
|
||||
<artifactId>ffmpeg</artifactId>
|
||||
<version>4.2.1-1.5.2</version>
|
||||
<version>${ffmpeg.version}</version>
|
||||
<classifier>windows-x86_64</classifier>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>com.lowagie</groupId>
|
||||
<artifactId>itext</artifactId>
|
||||
<version>2.1.7</version>
|
||||
<version>${itext.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@@ -274,7 +262,6 @@
|
||||
<scope>system</scope>
|
||||
<systemPath>${basedir}/lib/jai_core-1.1.3.jar</systemPath>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>javax.media</groupId>
|
||||
<artifactId>jai_codec</artifactId>
|
||||
@@ -283,6 +270,25 @@
|
||||
<systemPath>${basedir}/lib/jai_codec-1.1.3.jar</systemPath>
|
||||
</dependency>
|
||||
|
||||
<!-- test dependency - start -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-httpclient</groupId>
|
||||
<artifactId>commons-httpclient</artifactId>
|
||||
<version>3.1</version>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
<groupId>commons-logging</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<!-- test dependency - end -->
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
@@ -336,5 +342,4 @@
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
[#-- @ftlvariable name="file" type="cn.keking.model.FileAttribute" --]
|
||||
[#-- @ftlvariable name="fileName" type="java.lang.String" --]
|
||||
[#-- @ftlvariable name="fileTree" type="java.lang.String" --]
|
||||
[#-- @ftlvariable name="needFilePassword" type="java.lang.Boolean" --]
|
||||
[#-- @ftlvariable name="filePasswordError" type="java.lang.Boolean" --]
|
||||
[#-- @ftlvariable name="baseUrl" type="java.lang.String" --]
|
||||
[#-- @ftlvariable name="imgUrls" type="String" --]
|
||||
[#-- @ftlvariable name="textData" type="java.lang.String" --]
|
||||
|
||||
@@ -6,8 +6,8 @@ import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
|
||||
/**
|
||||
* @author: chenjh
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package cn.keking.model;
|
||||
|
||||
import cn.keking.config.ConfigConstants;
|
||||
import org.artofsolving.jodconverter.model.FileProperties;
|
||||
|
||||
/**
|
||||
* Created by kl on 2018/1/17.
|
||||
@@ -13,6 +14,8 @@ public class FileAttribute {
|
||||
private String name;
|
||||
private String url;
|
||||
private String fileKey;
|
||||
private String filePassword;
|
||||
private String userToken;
|
||||
private String officePreviewType = ConfigConstants.getOfficePreviewType();
|
||||
private String tifPreviewType;
|
||||
private Boolean skipDownLoad = false;
|
||||
@@ -35,6 +38,12 @@ public class FileAttribute {
|
||||
this.officePreviewType = officePreviewType;
|
||||
}
|
||||
|
||||
public FileProperties toFileProperties() {
|
||||
FileProperties fileProperties = new FileProperties();
|
||||
fileProperties.setFilePassword(filePassword);
|
||||
return fileProperties;
|
||||
}
|
||||
|
||||
public String getFileKey() {
|
||||
return fileKey;
|
||||
}
|
||||
@@ -43,6 +52,22 @@ public class FileAttribute {
|
||||
this.fileKey = fileKey;
|
||||
}
|
||||
|
||||
public String getFilePassword() {
|
||||
return filePassword;
|
||||
}
|
||||
|
||||
public void setFilePassword(String filePassword) {
|
||||
this.filePassword = filePassword;
|
||||
}
|
||||
|
||||
public String getUserToken() {
|
||||
return userToken;
|
||||
}
|
||||
|
||||
public void setUserToken(String userToken) {
|
||||
this.userToken = userToken;
|
||||
}
|
||||
|
||||
public String getOfficePreviewType() {
|
||||
return officePreviewType;
|
||||
}
|
||||
@@ -82,6 +107,7 @@ public class FileAttribute {
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public Boolean getSkipDownLoad() {
|
||||
return skipDownLoad;
|
||||
}
|
||||
@@ -89,6 +115,7 @@ public class FileAttribute {
|
||||
public void setSkipDownLoad(Boolean skipDownLoad) {
|
||||
this.skipDownLoad = skipDownLoad;
|
||||
}
|
||||
|
||||
public String getTifPreviewType() {
|
||||
return tifPreviewType;
|
||||
}
|
||||
@@ -96,4 +123,5 @@ public class FileAttribute {
|
||||
public void setTifPreviewType(String previewType) {
|
||||
this.tifPreviewType = previewType;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -292,7 +292,18 @@ public class FileHandlerService {
|
||||
if (StringUtils.hasText(tifPreviewType)) {
|
||||
attribute.setTifPreviewType(tifPreviewType);
|
||||
}
|
||||
|
||||
String filePassword = req.getParameter("filePassword");
|
||||
if (StringUtils.hasText(filePassword)) {
|
||||
attribute.setFilePassword(filePassword);
|
||||
}
|
||||
|
||||
String userToken = req.getParameter("userToken");
|
||||
if (StringUtils.hasText(userToken)) {
|
||||
attribute.setUserToken(userToken);
|
||||
}
|
||||
}
|
||||
|
||||
return attribute;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import org.artofsolving.jodconverter.OfficeDocumentConverter;
|
||||
import org.artofsolving.jodconverter.office.DefaultOfficeManagerConfiguration;
|
||||
import org.artofsolving.jodconverter.office.OfficeManager;
|
||||
import org.artofsolving.jodconverter.office.OfficeUtils;
|
||||
import org.artofsolving.jodconverter.util.PlatformUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
@@ -24,7 +25,6 @@ import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* 创建文件转换器
|
||||
@@ -50,7 +50,7 @@ public class OfficePluginManager {
|
||||
* 启动Office组件进程
|
||||
*/
|
||||
@PostConstruct
|
||||
public void startOfficeManager(){
|
||||
public void startOfficeManager() {
|
||||
File officeHome = OfficeUtils.getDefaultOfficeHome();
|
||||
if (officeHome == null) {
|
||||
throw new RuntimeException("找不到office组件,请确认'office.home'配置是否有误");
|
||||
@@ -62,7 +62,7 @@ public class OfficePluginManager {
|
||||
try {
|
||||
DefaultOfficeManagerConfiguration configuration = new DefaultOfficeManagerConfiguration();
|
||||
configuration.setOfficeHome(officeHome);
|
||||
String []portsString = serverPorts.split(",");
|
||||
String[] portsString = serverPorts.split(",");
|
||||
|
||||
int[] ports = Arrays.stream(portsString).mapToInt(Integer::parseInt).toArray();
|
||||
|
||||
@@ -86,8 +86,8 @@ public class OfficePluginManager {
|
||||
return converter;
|
||||
}
|
||||
|
||||
private Map<String,?> getLoadProperties() {
|
||||
Map<String,Object> loadProperties = new HashMap<>(10);
|
||||
private Map<String, ?> getLoadProperties() {
|
||||
Map<String, Object> loadProperties = new HashMap<>(10);
|
||||
loadProperties.put("Hidden", true);
|
||||
loadProperties.put("ReadOnly", true);
|
||||
loadProperties.put("UpdateDocMode", UpdateDocMode.QUIET_UPDATE);
|
||||
@@ -97,9 +97,8 @@ public class OfficePluginManager {
|
||||
|
||||
private boolean killProcess() {
|
||||
boolean flag = false;
|
||||
Properties props = System.getProperties();
|
||||
try {
|
||||
if (props.getProperty("os.name").toLowerCase().contains("windows")) {
|
||||
if (PlatformUtils.isWindows()) {
|
||||
Process p = Runtime.getRuntime().exec("cmd /c tasklist ");
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
InputStream os = p.getInputStream();
|
||||
@@ -112,8 +111,22 @@ public class OfficePluginManager {
|
||||
Runtime.getRuntime().exec("taskkill /im " + "soffice.bin" + " /f");
|
||||
flag = true;
|
||||
}
|
||||
} else if (PlatformUtils.isLinux()) {
|
||||
Process p = Runtime.getRuntime().exec(new String[]{"sh", "-c", "ps -ef | grep " + "soffice.bin" + " |grep -v grep | wc -l"});
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
InputStream os = p.getInputStream();
|
||||
byte[] b = new byte[256];
|
||||
while (os.read(b) > 0) {
|
||||
baos.write(b);
|
||||
}
|
||||
String s = baos.toString();
|
||||
if (!"0".equals(s)) {
|
||||
String[] cmd = {"sh", "-c", "ps -ef | grep soffice.bin | grep -v grep | awk '{print \"kill -9 \"$2}' | sh"};
|
||||
Runtime.getRuntime().exec(cmd);
|
||||
flag = true;
|
||||
}
|
||||
} else {
|
||||
Process p = Runtime.getRuntime().exec(new String[]{"sh","-c","ps -ef | grep " + "soffice.bin"});
|
||||
Process p = Runtime.getRuntime().exec(new String[]{"sh", "-c", "ps -ef | grep " + "soffice.bin"});
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
InputStream os = p.getInputStream();
|
||||
byte[] b = new byte[256];
|
||||
@@ -122,7 +135,7 @@ public class OfficePluginManager {
|
||||
}
|
||||
String s = baos.toString();
|
||||
if (StringUtils.ordinalIndexOf(s, "soffice.bin", 3) > 0) {
|
||||
String[] cmd ={"sh","-c","kill -15 `ps -ef|grep " + "soffice.bin" + "|awk 'NR==1{print $2}'`"};
|
||||
String[] cmd = {"sh", "-c", "kill -15 `ps -ef|grep " + "soffice.bin" + "|awk 'NR==1{print $2}'`"};
|
||||
Runtime.getRuntime().exec(cmd);
|
||||
flag = true;
|
||||
}
|
||||
@@ -134,7 +147,7 @@ public class OfficePluginManager {
|
||||
}
|
||||
|
||||
@PreDestroy
|
||||
public void destroyOfficeManager(){
|
||||
public void destroyOfficeManager() {
|
||||
if (null != officeManager && officeManager.isRunning()) {
|
||||
logger.info("Shutting down office process");
|
||||
officeManager.stop();
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package cn.keking.service;
|
||||
|
||||
import cn.keking.model.FileAttribute;
|
||||
import org.artofsolving.jodconverter.OfficeDocumentConverter;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -20,22 +21,23 @@ public class OfficeToPdfService {
|
||||
this.officePluginManager = officePluginManager;
|
||||
}
|
||||
|
||||
public void openOfficeToPDF(String inputFilePath, String outputFilePath) {
|
||||
office2pdf(inputFilePath, outputFilePath);
|
||||
public void openOfficeToPDF(String inputFilePath, String outputFilePath, FileAttribute fileAttribute) {
|
||||
office2pdf(inputFilePath, outputFilePath, fileAttribute);
|
||||
}
|
||||
|
||||
|
||||
public static void converterFile(File inputFile, String outputFilePath_end, OfficeDocumentConverter converter) {
|
||||
public static void converterFile(File inputFile, String outputFilePath_end, OfficeDocumentConverter converter, FileAttribute fileAttribute) {
|
||||
File outputFile = new File(outputFilePath_end);
|
||||
// 假如目标路径不存在,则新建该路径
|
||||
if (!outputFile.getParentFile().exists() && !outputFile.getParentFile().mkdirs()) {
|
||||
logger.error("创建目录【{}】失败,请检查目录权限!",outputFilePath_end);
|
||||
}
|
||||
converter.convert(inputFile, outputFile);
|
||||
|
||||
converter.convert(inputFile, outputFile, fileAttribute.toFileProperties());
|
||||
}
|
||||
|
||||
|
||||
public void office2pdf(String inputFilePath, String outputFilePath) {
|
||||
public void office2pdf(String inputFilePath, String outputFilePath, FileAttribute fileAttribute) {
|
||||
OfficeDocumentConverter converter = officePluginManager.getDocumentConverter();
|
||||
if (null != inputFilePath) {
|
||||
File inputFile = new File(inputFilePath);
|
||||
@@ -45,12 +47,12 @@ public class OfficeToPdfService {
|
||||
String outputFilePath_end = getOutputFilePath(inputFilePath);
|
||||
if (inputFile.exists()) {
|
||||
// 找不到源文件, 则返回
|
||||
converterFile(inputFile, outputFilePath_end,converter);
|
||||
converterFile(inputFile, outputFilePath_end, converter, fileAttribute);
|
||||
}
|
||||
} else {
|
||||
if (inputFile.exists()) {
|
||||
// 找不到源文件, 则返回
|
||||
converterFile(inputFile, outputFilePath, converter);
|
||||
converterFile(inputFile, outputFilePath, converter, fileAttribute);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,11 +3,13 @@ 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;
|
||||
import cn.keking.utils.DownloadUtils;
|
||||
import cn.keking.service.FileHandlerService;
|
||||
import cn.keking.service.FilePreview;
|
||||
import cn.keking.service.OfficeToPdfService;
|
||||
import cn.keking.utils.DownloadUtils;
|
||||
import cn.keking.utils.OfficeUtils;
|
||||
import cn.keking.web.filter.BaseUrlFilter;
|
||||
import org.artofsolving.jodconverter.office.OfficeException;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.util.StringUtils;
|
||||
@@ -42,33 +44,83 @@ public class OfficeFilePreviewImpl implements FilePreview {
|
||||
String baseUrl = BaseUrlFilter.getBaseUrl();
|
||||
String suffix = fileAttribute.getSuffix();
|
||||
String fileName = fileAttribute.getName();
|
||||
String filePassword = fileAttribute.getFilePassword();
|
||||
String userToken = fileAttribute.getUserToken();
|
||||
boolean isHtml = suffix.equalsIgnoreCase("xls") || suffix.equalsIgnoreCase("xlsx");
|
||||
String pdfName = fileName.substring(0, fileName.lastIndexOf(".") + 1) + (isHtml ? "html" : "pdf");
|
||||
String outFilePath = FILE_DIR + pdfName;
|
||||
// 判断之前是否已转换过,如果转换过,直接返回,否则执行转换
|
||||
if (!fileHandlerService.listConvertedFiles().containsKey(pdfName) || !ConfigConstants.isCacheEnabled()) {
|
||||
String filePath;
|
||||
ReturnResponse<String> response = DownloadUtils.downLoad(fileAttribute, null);
|
||||
if (response.isFailure()) {
|
||||
return otherFilePreview.notSupportedFile(model, fileAttribute, response.getMsg());
|
||||
String cacheFileName = userToken == null ? pdfName : userToken + "_" + pdfName;
|
||||
String outFilePath = FILE_DIR + cacheFileName;
|
||||
|
||||
// 下载远程文件到本地,如果文件在本地已存在不会重复下载
|
||||
ReturnResponse<String> response = DownloadUtils.downLoad(fileAttribute, fileName);
|
||||
if (response.isFailure()) {
|
||||
return otherFilePreview.notSupportedFile(model, fileAttribute, response.getMsg());
|
||||
}
|
||||
String filePath = response.getContent();
|
||||
|
||||
/*
|
||||
* 1. 缓存判断-如果文件已经进行转换过,就直接返回,否则执行转换
|
||||
* 2. 缓存判断-加密文件基于userToken进行缓存,如果没有就不缓存
|
||||
*/
|
||||
boolean isCached = false;
|
||||
boolean isUseCached = false;
|
||||
boolean isPwdProtectedOffice = false;
|
||||
if (ConfigConstants.isCacheEnabled()) {
|
||||
// 全局开启缓存
|
||||
isUseCached = true;
|
||||
if (fileHandlerService.listConvertedFiles().containsKey(cacheFileName)) {
|
||||
// 存在缓存
|
||||
isCached = true;
|
||||
}
|
||||
filePath = response.getContent();
|
||||
if (StringUtils.hasText(outFilePath)) {
|
||||
officeToPdfService.openOfficeToPDF(filePath, outFilePath);
|
||||
if (isHtml) {
|
||||
// 对转换后的文件进行操作(改变编码方式)
|
||||
fileHandlerService.doActionConvertedFile(outFilePath);
|
||||
if (OfficeUtils.isPwdProtected(filePath)) {
|
||||
isPwdProtectedOffice = true;
|
||||
if (!StringUtils.hasLength(userToken)) {
|
||||
// 不缓存没有userToken的加密文件
|
||||
isUseCached = false;
|
||||
}
|
||||
if (ConfigConstants.isCacheEnabled()) {
|
||||
// 加入缓存
|
||||
fileHandlerService.addConvertedFile(pdfName, fileHandlerService.getRelativePath(outFilePath));
|
||||
}
|
||||
} else {
|
||||
isPwdProtectedOffice = OfficeUtils.isPwdProtected(filePath);
|
||||
}
|
||||
|
||||
if (isCached == false) {
|
||||
// 没有缓存执行转换逻辑
|
||||
if (isPwdProtectedOffice && !StringUtils.hasLength(filePassword)) {
|
||||
// 加密文件需要密码
|
||||
model.addAttribute("needFilePassword", true);
|
||||
return EXEL_FILE_PREVIEW_PAGE;
|
||||
} else {
|
||||
if (StringUtils.hasText(outFilePath)) {
|
||||
try {
|
||||
officeToPdfService.openOfficeToPDF(filePath, outFilePath, fileAttribute);
|
||||
} catch (OfficeException e) {
|
||||
if (isPwdProtectedOffice && OfficeUtils.isCompatible(filePath, filePassword) == false) {
|
||||
// 加密文件密码错误,提示重新输入
|
||||
model.addAttribute("needFilePassword", true);
|
||||
model.addAttribute("filePasswordError", true);
|
||||
return EXEL_FILE_PREVIEW_PAGE;
|
||||
}
|
||||
|
||||
return otherFilePreview.notSupportedFile(model, fileAttribute, "抱歉,该文件版本不兼容,文件版本错误。");
|
||||
}
|
||||
|
||||
if (isHtml) {
|
||||
// 对转换后的文件进行操作(改变编码方式)
|
||||
fileHandlerService.doActionConvertedFile(outFilePath);
|
||||
}
|
||||
if (isUseCached) {
|
||||
// 加入缓存
|
||||
fileHandlerService.addConvertedFile(cacheFileName, fileHandlerService.getRelativePath(outFilePath));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!isHtml && baseUrl != null && (OFFICE_PREVIEW_TYPE_IMAGE.equals(officePreviewType) || OFFICE_PREVIEW_TYPE_ALL_IMAGES.equals(officePreviewType))) {
|
||||
return getPreviewType(model, fileAttribute, officePreviewType, baseUrl, pdfName, outFilePath, fileHandlerService, OFFICE_PREVIEW_TYPE_IMAGE, otherFilePreview);
|
||||
return getPreviewType(model, fileAttribute, officePreviewType, baseUrl, cacheFileName, outFilePath, fileHandlerService, OFFICE_PREVIEW_TYPE_IMAGE, otherFilePreview);
|
||||
}
|
||||
model.addAttribute("pdfUrl", pdfName);
|
||||
|
||||
model.addAttribute("pdfUrl", cacheFileName);
|
||||
return isHtml ? EXEL_FILE_PREVIEW_PAGE : PDF_FILE_PREVIEW_PAGE;
|
||||
}
|
||||
|
||||
@@ -88,4 +140,5 @@ public class OfficeFilePreviewImpl implements FilePreview {
|
||||
return PICTURE_FILE_PREVIEW_PAGE;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -48,8 +48,7 @@ public class SimTextFilePreviewImpl implements FilePreview {
|
||||
private String textData(String baseUrll) throws IOException {
|
||||
File file = new File(baseUrll);
|
||||
if(!file.exists() || file.length() == 0) {
|
||||
String line="";
|
||||
return line;
|
||||
return "";
|
||||
}else {
|
||||
String charset = EncodingDetects.getJavaEncode(baseUrll);
|
||||
System.out.println(charset);
|
||||
|
||||
@@ -8,6 +8,8 @@ import cn.keking.utils.ConvertPicUtil;
|
||||
import cn.keking.utils.DownloadUtils;
|
||||
import cn.keking.utils.WebUtils;
|
||||
import cn.keking.web.filter.BaseUrlFilter;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.util.StringUtils;
|
||||
@@ -18,12 +20,15 @@ import java.util.List;
|
||||
|
||||
/**
|
||||
* tiff 图片文件处理
|
||||
*
|
||||
* @author kl (http://kailing.pub)
|
||||
* @since 2021/2/8
|
||||
*/
|
||||
@Service
|
||||
public class TiffFilePreviewImpl implements FilePreview {
|
||||
|
||||
private final static Logger logger = LoggerFactory.getLogger(TiffFilePreviewImpl.class);
|
||||
|
||||
private final PictureFilePreviewImpl pictureFilePreview;
|
||||
private static final String INITIALIZE_MEMORY_SIZE = "initializeMemorySize";
|
||||
//默认初始化 50MB 内存
|
||||
@@ -43,25 +48,25 @@ public class TiffFilePreviewImpl implements FilePreview {
|
||||
tifPreviewType = tifOnLinePreviewType;
|
||||
}
|
||||
|
||||
if("tif".equalsIgnoreCase(tifPreviewType)){
|
||||
if ("tif".equalsIgnoreCase(tifPreviewType)) {
|
||||
|
||||
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));
|
||||
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;
|
||||
|
||||
}else if("jpg".equalsIgnoreCase(tifPreviewType) || "pdf".equalsIgnoreCase(tifPreviewType)){
|
||||
} else if ("jpg".equalsIgnoreCase(tifPreviewType) || "pdf".equalsIgnoreCase(tifPreviewType)) {
|
||||
String inputFileName = url.substring(url.lastIndexOf("/") + 1);
|
||||
String inputFileNamePrefix = inputFileName.substring(0, inputFileName.lastIndexOf("."));
|
||||
|
||||
String strLocalTif = fileDir + inputFileName;
|
||||
File fileTiff = new File(strLocalTif);
|
||||
// 如果本地不存在这个tif文件,则下载
|
||||
if(!fileTiff.exists()){
|
||||
if (!fileTiff.exists()) {
|
||||
ReturnResponse<String> response = DownloadUtils.downLoad(fileAttribute, inputFileName);
|
||||
if (response.isFailure()) {
|
||||
return NOT_SUPPORTED_FILE_PAGE;
|
||||
@@ -69,22 +74,23 @@ public class TiffFilePreviewImpl implements FilePreview {
|
||||
}
|
||||
|
||||
String baseUrl = BaseUrlFilter.getBaseUrl();
|
||||
if("pdf".equalsIgnoreCase(tifPreviewType)){
|
||||
if ("pdf".equalsIgnoreCase(tifPreviewType)) {
|
||||
// 以PDF模式预览的过程
|
||||
File filePdf = new File(fileDir + inputFileNamePrefix + ".pdf");
|
||||
// 如果本地不存在对应的pdf,则调用转换过程。否则直接用现有的pdf文件
|
||||
if(!filePdf.exists()){
|
||||
if (!filePdf.exists()) {
|
||||
filePdf = ConvertPicUtil.convertTif2Pdf(strLocalTif, fileDir + inputFileNamePrefix + ".pdf");
|
||||
}
|
||||
|
||||
// 如果pdf已经存在,则将url路径加入到对象中,返回给页面
|
||||
if(filePdf.exists()){
|
||||
assert filePdf != null;
|
||||
if (filePdf.exists()) {
|
||||
String pdfUrl = baseUrl + inputFileNamePrefix + ".pdf";
|
||||
model.addAttribute("pdfUrl", pdfUrl);
|
||||
|
||||
return PDF_FILE_PREVIEW_PAGE;
|
||||
}
|
||||
}else{
|
||||
} else {
|
||||
// 以JPG模式预览的过程
|
||||
String strJpgFilePathName = fileDir + inputFileNamePrefix + ".jpg";
|
||||
// 将tif转换为jpg,返回转换后的文件路径、文件名的list
|
||||
@@ -92,7 +98,7 @@ public class TiffFilePreviewImpl implements FilePreview {
|
||||
// 将返回页面的图片url的list对象
|
||||
List<String> listImageUrls = new ArrayList<>();
|
||||
// 循环,拼装url的list对象
|
||||
for(String strJpg : listPic2Jpg){
|
||||
for (String strJpg : listPic2Jpg) {
|
||||
listImageUrls.add(baseUrl + strJpg);
|
||||
}
|
||||
|
||||
@@ -101,8 +107,8 @@ public class TiffFilePreviewImpl implements FilePreview {
|
||||
}
|
||||
|
||||
// 转换后的tif没用了,可以删掉了
|
||||
if(fileTiff.exists()){
|
||||
fileTiff.delete();
|
||||
if (fileTiff.exists() && !fileTiff.delete()) {
|
||||
logger.error("{} 清理失败", strLocalTif);
|
||||
}
|
||||
|
||||
return PICTURE_FILE_PREVIEW_PAGE;
|
||||
|
||||
@@ -27,6 +27,7 @@ public class ConvertPicUtil {
|
||||
|
||||
/**
|
||||
* Tif 转 JPG。
|
||||
*
|
||||
* @param strInputFile 输入文件的路径和文件名
|
||||
* @param strOutputFile 输出文件的路径和文件名
|
||||
* @return boolean 是否转换成功
|
||||
@@ -60,8 +61,8 @@ public class ConvertPicUtil {
|
||||
int intTifCount = imageDecoder.getNumPages();
|
||||
logger.info("该tif文件共有【" + intTifCount + "】页");
|
||||
|
||||
String strJpgPath = "";
|
||||
String strJpgUrl = "";
|
||||
String strJpgPath;
|
||||
String strJpgUrl;
|
||||
if (intTifCount == 1) {
|
||||
// 如果是单页tif文件,则转换的目标文件夹就在指定的位置
|
||||
strJpgPath = strOutputFile.substring(0, strOutputFile.lastIndexOf("/"));
|
||||
@@ -72,17 +73,17 @@ public class ConvertPicUtil {
|
||||
|
||||
// 处理目标文件夹,如果不存在则自动创建
|
||||
File fileJpgPath = new File(strJpgPath);
|
||||
if (!fileJpgPath.exists()) {
|
||||
fileJpgPath.mkdirs();
|
||||
if (!fileJpgPath.exists() && !fileJpgPath.mkdirs()) {
|
||||
logger.error("{} 创建失败", strJpgPath);
|
||||
}
|
||||
|
||||
// 循环,处理每页tif文件,转换为jpg
|
||||
for (int i = 0; i < intTifCount; i++) {
|
||||
String strJpg = "";
|
||||
if(intTifCount == 1){
|
||||
String strJpg;
|
||||
if (intTifCount == 1) {
|
||||
strJpg = strJpgPath + "/" + strFilePrefix + ".jpg";
|
||||
strJpgUrl = strFilePrefix + ".jpg";
|
||||
}else{
|
||||
} else {
|
||||
strJpg = strJpgPath + "/" + i + ".jpg";
|
||||
strJpgUrl = strFilePrefix + "/" + i + ".jpg";
|
||||
}
|
||||
@@ -90,7 +91,7 @@ public class ConvertPicUtil {
|
||||
File fileJpg = new File(strJpg);
|
||||
|
||||
// 如果文件不存在,则生成
|
||||
if(!fileJpg.exists()){
|
||||
if (!fileJpg.exists()) {
|
||||
RenderedImage renderedImage = imageDecoder.decodeAsRenderedImage(i);
|
||||
ParameterBlock pb = new ParameterBlock();
|
||||
pb.addSource(renderedImage);
|
||||
@@ -102,7 +103,7 @@ public class ConvertPicUtil {
|
||||
renderedOp.dispose();
|
||||
|
||||
logger.info("每页分别保存至: " + fileJpg.getCanonicalPath());
|
||||
}else{
|
||||
} else {
|
||||
logger.info("JPG文件已存在: " + fileJpg.getCanonicalPath());
|
||||
}
|
||||
|
||||
@@ -118,21 +119,19 @@ public class ConvertPicUtil {
|
||||
try {
|
||||
fileSeekStream.close();
|
||||
} catch (IOException e) {
|
||||
logger.error(e.getMessage(), e);
|
||||
}
|
||||
fileSeekStream = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 将Jpg图片转换为Pdf文件
|
||||
*
|
||||
* @param strJpgFile 输入的jpg的路径和文件名
|
||||
* @param strPdfFile 输出的pdf的路径和文件名
|
||||
* @return
|
||||
*/
|
||||
public static File convertJpg2Pdf(String strJpgFile, String strPdfFile) {
|
||||
public static void convertJpg2Pdf(String strJpgFile, String strPdfFile) {
|
||||
Document document = new Document();
|
||||
// 设置文档页边距
|
||||
document.setMargins(0, 0, 0, 0);
|
||||
@@ -157,23 +156,18 @@ public class ConvertPicUtil {
|
||||
document.add(image);
|
||||
} catch (Exception ioe) {
|
||||
ioe.printStackTrace();
|
||||
return null;
|
||||
} finally {
|
||||
//关闭文档
|
||||
document.close();
|
||||
try {
|
||||
assert fos != null;
|
||||
fos.flush();
|
||||
fos.close();
|
||||
|
||||
File filePDF = new File(strPdfFile);
|
||||
return filePDF;
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -182,7 +176,7 @@ public class ConvertPicUtil {
|
||||
*
|
||||
* @param strTifFile 输入的tif的路径和文件名
|
||||
* @param strPdfFile 输出的pdf的路径和文件名
|
||||
* @return
|
||||
* @return File
|
||||
*/
|
||||
public static File convertTif2Pdf(String strTifFile, String strPdfFile) {
|
||||
try {
|
||||
@@ -198,16 +192,16 @@ public class ConvertPicUtil {
|
||||
Image image;
|
||||
File filePDF;
|
||||
|
||||
if(intPages == 1){
|
||||
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()){
|
||||
filePDF = convertJpg2Pdf(strJpg, strPdfFile);
|
||||
if (listPic2Jpg != null && fileJpg.exists()) {
|
||||
convertJpg2Pdf(strJpg, strPdfFile);
|
||||
}
|
||||
|
||||
}else{
|
||||
} else {
|
||||
for (int i = 1; i <= intPages; i++) {
|
||||
image = TiffImage.getTiffImage(rafa, i);
|
||||
// 设置页面宽高与图片一致
|
||||
@@ -229,7 +223,7 @@ public class ConvertPicUtil {
|
||||
|
||||
return filePDF;
|
||||
} catch (Exception e) {
|
||||
System.out.println(e.toString());
|
||||
logger.error(e.getMessage(), e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -87,6 +87,13 @@ public class DownloadUtils {
|
||||
if (!dirFile.exists() && !dirFile.mkdirs()) {
|
||||
logger.error("创建目录【{}】失败,可能是权限不够,请检查", fileDir);
|
||||
}
|
||||
|
||||
// 文件已在本地存在,跳过文件下载
|
||||
File realFile = new File(realPath);
|
||||
if (realFile.exists()) {
|
||||
fileAttribute.setSkipDownLoad(true);
|
||||
}
|
||||
|
||||
return realPath;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,8 @@ import org.slf4j.LoggerFactory;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public class KkFileUtils {
|
||||
@@ -15,6 +17,33 @@ public class KkFileUtils {
|
||||
|
||||
public static final String DEFAULT_FILE_ENCODING = "UTF-8";
|
||||
|
||||
private static final List<String> illegalFileStrList = new ArrayList<>();
|
||||
|
||||
static {
|
||||
illegalFileStrList.add("../");
|
||||
illegalFileStrList.add("./");
|
||||
illegalFileStrList.add("..\\");
|
||||
illegalFileStrList.add(".\\");
|
||||
illegalFileStrList.add("\\..");
|
||||
illegalFileStrList.add("\\.");
|
||||
illegalFileStrList.add("..");
|
||||
illegalFileStrList.add("...");
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查文件名是否合规
|
||||
* @param fileName 文件名
|
||||
* @return 合规结果,true:不合规,false:合规
|
||||
*/
|
||||
public static boolean isIllegalFileName(String fileName){
|
||||
for (String str: illegalFileStrList){
|
||||
if(fileName.contains(str)){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断url是否是http资源
|
||||
*
|
||||
|
||||
62
server/src/main/java/cn/keking/utils/OfficeUtils.java
Normal file
62
server/src/main/java/cn/keking/utils/OfficeUtils.java
Normal file
@@ -0,0 +1,62 @@
|
||||
package cn.keking.utils;
|
||||
|
||||
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||
import org.apache.poi.EncryptedDocumentException;
|
||||
import org.apache.poi.extractor.ExtractorFactory;
|
||||
import org.apache.poi.hssf.record.crypto.Biff8EncryptionKey;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
|
||||
/**
|
||||
* Office工具类
|
||||
*
|
||||
* @author ylyue
|
||||
* @since 2022/7/5
|
||||
*/
|
||||
public class OfficeUtils {
|
||||
|
||||
/**
|
||||
* 判断office(word,excel,ppt)文件是否受密码保护
|
||||
*
|
||||
* @param path office文件路径
|
||||
* @return 是否受密码保护
|
||||
*/
|
||||
public static boolean isPwdProtected(String path) {
|
||||
try {
|
||||
ExtractorFactory.createExtractor(new FileInputStream(path));
|
||||
} catch (EncryptedDocumentException e) {
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
Throwable[] throwables = ExceptionUtils.getThrowables(e);
|
||||
for (Throwable throwable : throwables) {
|
||||
if (throwable instanceof EncryptedDocumentException) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断office文件是否可打开(兼容)
|
||||
*
|
||||
* @param path office文件路径
|
||||
* @param password 文件密码
|
||||
* @return 是否可打开(兼容)
|
||||
*/
|
||||
public static synchronized boolean isCompatible(String path, @Nullable String password) {
|
||||
try {
|
||||
Biff8EncryptionKey.setCurrentUserPassword(password);
|
||||
ExtractorFactory.createExtractor(new FileInputStream(path));
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
} finally {
|
||||
Biff8EncryptionKey.setCurrentUserPassword(null);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -9,6 +9,7 @@ import java.io.UnsupportedEncodingException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@@ -156,22 +157,48 @@ public class WebUtils {
|
||||
String currentUrl = request.getParameter("currentUrl");
|
||||
String urlPath = request.getParameter("urlPath");
|
||||
if (StringUtils.isNotBlank(url)) {
|
||||
return new String(Base64Utils.decodeFromString(url), StandardCharsets.UTF_8);
|
||||
return decodeBase64String(url);
|
||||
}
|
||||
if (StringUtils.isNotBlank(currentUrl)) {
|
||||
return new String(Base64Utils.decodeFromString(currentUrl), StandardCharsets.UTF_8);
|
||||
return decodeBase64String(currentUrl);
|
||||
}
|
||||
if (StringUtils.isNotBlank(urlPath)) {
|
||||
return new String(Base64Utils.decodeFromString(urlPath), StandardCharsets.UTF_8);
|
||||
return decodeBase64String(urlPath);
|
||||
}
|
||||
if (StringUtils.isNotBlank(urls)) {
|
||||
urls = new String(Base64Utils.decodeFromString(urls), StandardCharsets.UTF_8);
|
||||
urls = decodeBase64String(urls);
|
||||
String[] images = urls.split("\\|");
|
||||
return images[0];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将 Base64 字符串解码,默认使用 UTF-8
|
||||
* @param source 原始 Base64 字符串
|
||||
* @return decoded string
|
||||
*/
|
||||
public static String decodeBase64String(String source) {
|
||||
return decodeBase64String(source, StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将 Base64 字符串使用指定字符集解码
|
||||
* @param source 原始 Base64 字符串
|
||||
* @param charsets 字符集
|
||||
* @return decoded string
|
||||
*/
|
||||
public static String decodeBase64String(String source, Charset charsets) {
|
||||
/*
|
||||
* url 传入的参数里加号会被替换成空格,导致解析出错,这里需要把空格替换回加号
|
||||
* 有些 Base64 实现可能每 76 个字符插入换行符,也一并去掉
|
||||
* https://github.com/kekingcn/kkFileView/pull/340
|
||||
*/
|
||||
return new String(Base64Utils.decodeFromString(
|
||||
source.replaceAll(" ", "+").replaceAll("\n", "")
|
||||
), charsets);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 url 的 host
|
||||
* @param urlStr url
|
||||
|
||||
@@ -1,26 +1,33 @@
|
||||
package cn.keking.web.controller;
|
||||
|
||||
import cn.keking.config.ConfigConstants;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
import cn.keking.model.ReturnResponse;
|
||||
import cn.keking.utils.KkFileUtils;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.util.StreamUtils;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.*;
|
||||
import org.springframework.web.util.HtmlUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author yudian-it
|
||||
* @date 2017/12/1
|
||||
*/
|
||||
@@ -33,16 +40,17 @@ public class FileController {
|
||||
private final String demoDir = "demo";
|
||||
private final String demoPath = demoDir + File.separator;
|
||||
|
||||
@RequestMapping(value = "fileUpload", method = RequestMethod.POST)
|
||||
public String fileUpload(@RequestParam("file") MultipartFile file) throws JsonProcessingException {
|
||||
@PostMapping("/fileUpload")
|
||||
public ReturnResponse<Object> fileUpload(@RequestParam("file") MultipartFile file) throws JsonProcessingException {
|
||||
if (ConfigConstants.getFileUploadDisable()) {
|
||||
return new ObjectMapper().writeValueAsString(ReturnResponse.failure("文件传接口已禁用"));
|
||||
return ReturnResponse.failure("文件传接口已禁用");
|
||||
}
|
||||
// 获取文件名
|
||||
String fileName = file.getOriginalFilename();
|
||||
//判断是否为IE浏览器的文件名,IE浏览器下文件名会带有盘符信息
|
||||
|
||||
|
||||
// escaping dangerous characters to prevent XSS
|
||||
assert fileName != null;
|
||||
fileName = HtmlUtils.htmlEscape(fileName, StandardCharsets.UTF_8.name());
|
||||
|
||||
// Check for Unix-style path
|
||||
@@ -51,42 +59,47 @@ public class FileController {
|
||||
int winSep = fileName.lastIndexOf('\\');
|
||||
// Cut off at latest possible point
|
||||
int pos = (Math.max(winSep, unixSep));
|
||||
if (pos != -1) {
|
||||
if (pos != -1) {
|
||||
fileName = fileName.substring(pos + 1);
|
||||
}
|
||||
// 判断是否存在同名文件
|
||||
if (existsFile(fileName)) {
|
||||
return new ObjectMapper().writeValueAsString(ReturnResponse.failure("存在同名文件,请先删除原有文件再次上传"));
|
||||
return ReturnResponse.failure("存在同名文件,请先删除原有文件再次上传");
|
||||
}
|
||||
File outFile = new File(fileDir + demoPath);
|
||||
if (!outFile.exists() && !outFile.mkdirs()) {
|
||||
logger.error("创建文件夹【{}】失败,请检查目录权限!",fileDir + demoPath);
|
||||
logger.error("创建文件夹【{}】失败,请检查目录权限!", fileDir + demoPath);
|
||||
}
|
||||
logger.info("上传文件:{}", fileDir + demoPath + fileName);
|
||||
try(InputStream in = file.getInputStream(); OutputStream out = new FileOutputStream(fileDir + demoPath + fileName)) {
|
||||
try (InputStream in = file.getInputStream(); OutputStream out = new FileOutputStream(fileDir + demoPath + fileName)) {
|
||||
StreamUtils.copy(in, out);
|
||||
return new ObjectMapper().writeValueAsString(ReturnResponse.success(null));
|
||||
return ReturnResponse.success(null);
|
||||
} catch (IOException e) {
|
||||
logger.error("文件上传失败", e);
|
||||
return new ObjectMapper().writeValueAsString(ReturnResponse.failure());
|
||||
return ReturnResponse.failure();
|
||||
}
|
||||
}
|
||||
|
||||
@RequestMapping(value = "deleteFile", method = RequestMethod.GET)
|
||||
public String deleteFile(String fileName) throws JsonProcessingException {
|
||||
@GetMapping("/deleteFile")
|
||||
public ReturnResponse<Object> deleteFile(String fileName) throws JsonProcessingException {
|
||||
if (fileName.contains("/")) {
|
||||
fileName = fileName.substring(fileName.lastIndexOf("/") + 1);
|
||||
}
|
||||
if (KkFileUtils.isIllegalFileName(fileName)) {
|
||||
return ReturnResponse.failure("非法文件名,删除失败!");
|
||||
}
|
||||
File file = new File(fileDir + demoPath + fileName);
|
||||
logger.info("删除文件:{}", file.getAbsolutePath());
|
||||
if (file.exists() && !file.delete()) {
|
||||
logger.error("删除文件【{}】失败,请检查目录权限!",file.getPath());
|
||||
String msg = String.format("删除文件【%s】失败,请检查目录权限!", file.getPath());
|
||||
logger.error(msg);
|
||||
return ReturnResponse.failure(msg);
|
||||
}
|
||||
return new ObjectMapper().writeValueAsString(ReturnResponse.success());
|
||||
return ReturnResponse.success();
|
||||
}
|
||||
|
||||
@RequestMapping(value = "listFiles", method = RequestMethod.GET)
|
||||
public String getFiles() throws JsonProcessingException {
|
||||
@GetMapping("/listFiles")
|
||||
public List<Map<String, String>> getFiles() throws JsonProcessingException {
|
||||
List<Map<String, String>> list = new ArrayList<>();
|
||||
File file = new File(fileDir + demoPath);
|
||||
if (file.exists()) {
|
||||
@@ -96,7 +109,7 @@ public class FileController {
|
||||
list.add(fileName);
|
||||
});
|
||||
}
|
||||
return new ObjectMapper().writeValueAsString(list);
|
||||
return list;
|
||||
}
|
||||
|
||||
private boolean existsFile(String fileName) {
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
package cn.keking.web.controller;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
|
||||
/**
|
||||
* 页面跳转
|
||||
@@ -12,12 +11,12 @@ import org.springframework.web.bind.annotation.RequestMethod;
|
||||
@Controller
|
||||
public class IndexController {
|
||||
|
||||
@RequestMapping(value = "/index", method = RequestMethod.GET)
|
||||
@GetMapping( "/index")
|
||||
public String go2Index(){
|
||||
return "index";
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/", method = RequestMethod.GET)
|
||||
@GetMapping( "/")
|
||||
public String root() {
|
||||
return "redirect:/index";
|
||||
}
|
||||
|
||||
@@ -16,9 +16,9 @@ import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.util.HtmlUtils;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
@@ -52,11 +52,11 @@ public class OnlinePreviewController {
|
||||
this.otherFilePreview = otherFilePreview;
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/onlinePreview")
|
||||
@GetMapping( "/onlinePreview")
|
||||
public String onlinePreview(String url, Model model, HttpServletRequest req) {
|
||||
String fileUrl;
|
||||
try {
|
||||
fileUrl = new String(Base64.decodeBase64(url), StandardCharsets.UTF_8);
|
||||
fileUrl = WebUtils.decodeBase64String(url);
|
||||
} catch (Exception ex) {
|
||||
String errorMsg = String.format(BASE64_DECODE_ERROR_MSG, "url");
|
||||
return otherFilePreview.notSupportedFile(model, errorMsg);
|
||||
@@ -68,15 +68,18 @@ public class OnlinePreviewController {
|
||||
return filePreview.filePreviewHandle(fileUrl, model, fileAttribute);
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/picturesPreview")
|
||||
@GetMapping( "/picturesPreview")
|
||||
public String picturesPreview(String urls, Model model, HttpServletRequest req) throws UnsupportedEncodingException {
|
||||
String fileUrls;
|
||||
try {
|
||||
fileUrls = new String(Base64.decodeBase64(urls));
|
||||
fileUrls = WebUtils.decodeBase64String(urls);
|
||||
// 防止XSS攻击
|
||||
fileUrls = HtmlUtils.htmlEscape(fileUrls);
|
||||
} catch (Exception ex) {
|
||||
String errorMsg = String.format(BASE64_DECODE_ERROR_MSG, "urls");
|
||||
return otherFilePreview.notSupportedFile(model, errorMsg);
|
||||
}
|
||||
|
||||
logger.info("预览文件url:{},urls:{}", fileUrls, urls);
|
||||
// 抽取文件并返回文件列表
|
||||
String[] images = fileUrls.split("\\|");
|
||||
@@ -100,8 +103,20 @@ public class OnlinePreviewController {
|
||||
* @param urlPath url
|
||||
* @param response response
|
||||
*/
|
||||
@RequestMapping(value = "/getCorsFile", method = RequestMethod.GET)
|
||||
@GetMapping("/getCorsFile")
|
||||
public void getCorsFile(String urlPath, HttpServletResponse response) {
|
||||
try {
|
||||
urlPath = WebUtils.decodeBase64String(urlPath);
|
||||
} catch (Exception ex) {
|
||||
logger.error(String.format(BASE64_DECODE_ERROR_MSG, urlPath),ex);
|
||||
return;
|
||||
}
|
||||
if (urlPath.toLowerCase().startsWith("file:") || urlPath.toLowerCase().startsWith("file%3")
|
||||
|| !urlPath.toLowerCase().startsWith("http")) {
|
||||
logger.info("读取跨域文件异常,可能存在非法访问,urlPath:{}", urlPath);
|
||||
return;
|
||||
}
|
||||
|
||||
logger.info("下载跨域pdf文件url:{}", urlPath);
|
||||
try {
|
||||
URL url = WebUtils.normalizedURL(urlPath);
|
||||
@@ -117,7 +132,7 @@ public class OnlinePreviewController {
|
||||
*
|
||||
* @param url 请编码后在入队
|
||||
*/
|
||||
@RequestMapping("/addTask")
|
||||
@GetMapping("/addTask")
|
||||
@ResponseBody
|
||||
public String addQueueTask(String url) {
|
||||
logger.info("添加转码队列url:{}", url);
|
||||
@@ -125,6 +140,4 @@ public class OnlinePreviewController {
|
||||
return "success";
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -48,15 +48,24 @@ public class AttributeSetFilter implements Filter {
|
||||
private void setWatermarkAttribute(ServletRequest request) {
|
||||
String watermarkTxt = request.getParameter("watermarkTxt");
|
||||
request.setAttribute("watermarkTxt", watermarkTxt != null ? watermarkTxt : WatermarkConfigConstants.getWatermarkTxt());
|
||||
request.setAttribute("watermarkXSpace", WatermarkConfigConstants.getWatermarkXSpace());
|
||||
request.setAttribute("watermarkYSpace", WatermarkConfigConstants.getWatermarkYSpace());
|
||||
request.setAttribute("watermarkFont", WatermarkConfigConstants.getWatermarkFont());
|
||||
request.setAttribute("watermarkFontsize", WatermarkConfigConstants.getWatermarkFontsize());
|
||||
request.setAttribute("watermarkColor", WatermarkConfigConstants.getWatermarkColor());
|
||||
request.setAttribute("watermarkAlpha", WatermarkConfigConstants.getWatermarkAlpha());
|
||||
request.setAttribute("watermarkWidth", WatermarkConfigConstants.getWatermarkWidth());
|
||||
request.setAttribute("watermarkHeight", WatermarkConfigConstants.getWatermarkHeight());
|
||||
request.setAttribute("watermarkAngle", WatermarkConfigConstants.getWatermarkAngle());
|
||||
String watermarkXSpace = request.getParameter("watermarkXSpace");
|
||||
request.setAttribute("watermarkXSpace", watermarkXSpace != null ? watermarkXSpace : WatermarkConfigConstants.getWatermarkXSpace());
|
||||
String watermarkYSpace = request.getParameter("watermarkYSpace");
|
||||
request.setAttribute("watermarkYSpace", watermarkYSpace != null ? watermarkYSpace : WatermarkConfigConstants.getWatermarkYSpace());
|
||||
String watermarkFont = request.getParameter("watermarkFont");
|
||||
request.setAttribute("watermarkFont", watermarkFont != null ? watermarkFont : WatermarkConfigConstants.getWatermarkFont());
|
||||
String watermarkFontsize = request.getParameter("watermarkFontsize");
|
||||
request.setAttribute("watermarkFontsize", watermarkFontsize != null ? watermarkFontsize : WatermarkConfigConstants.getWatermarkFontsize());
|
||||
String watermarkColor = request.getParameter("watermarkColor");
|
||||
request.setAttribute("watermarkColor", watermarkColor != null ? watermarkColor : WatermarkConfigConstants.getWatermarkColor());
|
||||
String watermarkAlpha = request.getParameter("watermarkAlpha");
|
||||
request.setAttribute("watermarkAlpha", watermarkAlpha != null ? watermarkAlpha : WatermarkConfigConstants.getWatermarkAlpha());
|
||||
String watermarkWidth = request.getParameter("watermarkWidth");
|
||||
request.setAttribute("watermarkWidth", watermarkWidth != null ? watermarkWidth : WatermarkConfigConstants.getWatermarkWidth());
|
||||
String watermarkHeight = request.getParameter("watermarkHeight");
|
||||
request.setAttribute("watermarkHeight", watermarkHeight != null ? watermarkHeight : WatermarkConfigConstants.getWatermarkHeight());
|
||||
String watermarkAngle = request.getParameter("watermarkAngle");
|
||||
request.setAttribute("watermarkAngle", watermarkAngle != null ? watermarkAngle : WatermarkConfigConstants.getWatermarkAngle());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package cn.keking.web.filter;
|
||||
|
||||
import cn.keking.config.ConfigConstants;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
|
||||
import javax.servlet.*;
|
||||
@@ -18,7 +19,7 @@ public class BaseUrlFilter implements Filter {
|
||||
public static String getBaseUrl() {
|
||||
String baseUrl;
|
||||
try {
|
||||
baseUrl = (String) RequestContextHolder.currentRequestAttributes().getAttribute("baseUrl",0);
|
||||
baseUrl = (String) RequestContextHolder.currentRequestAttributes().getAttribute("baseUrl", 0);
|
||||
} catch (Exception e) {
|
||||
baseUrl = BASE_URL;
|
||||
}
|
||||
@@ -33,19 +34,28 @@ public class BaseUrlFilter implements Filter {
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
|
||||
|
||||
String baseUrl;
|
||||
StringBuilder pathBuilder = new StringBuilder();
|
||||
pathBuilder.append(request.getScheme()).append("://").append(request.getServerName()).append(":")
|
||||
.append(request.getServerPort()).append(((HttpServletRequest) request).getContextPath()).append("/");
|
||||
String baseUrlTmp = ConfigConstants.getBaseUrl();
|
||||
if (baseUrlTmp != null && !ConfigConstants.DEFAULT_BASE_URL.equalsIgnoreCase(baseUrlTmp)) {
|
||||
if (!baseUrlTmp.endsWith("/")) {
|
||||
baseUrlTmp = baseUrlTmp.concat("/");
|
||||
}
|
||||
baseUrl = baseUrlTmp;
|
||||
String configBaseUrl = ConfigConstants.getBaseUrl();
|
||||
|
||||
final HttpServletRequest servletRequest = (HttpServletRequest) request;
|
||||
//1、支持通过 http header 中 X-Base-Url 来动态设置 baseUrl 以支持多个域名/项目的共享使用
|
||||
final String urlInHeader = servletRequest.getHeader("X-Base-Url");
|
||||
if (StringUtils.isNotEmpty(urlInHeader)) {
|
||||
baseUrl = urlInHeader;
|
||||
} else if (configBaseUrl != null && !ConfigConstants.DEFAULT_BASE_URL.equalsIgnoreCase(configBaseUrl)) {
|
||||
//2、如果配置文件中配置了 baseUrl 且不为 default 则以配置文件为准
|
||||
baseUrl = configBaseUrl;
|
||||
} else {
|
||||
baseUrl = pathBuilder.toString();
|
||||
//3、默认动态拼接 baseUrl
|
||||
baseUrl = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()
|
||||
+ servletRequest.getContextPath() + "/";
|
||||
}
|
||||
|
||||
if (!baseUrl.endsWith("/")) {
|
||||
baseUrl = baseUrl.concat("/");
|
||||
}
|
||||
|
||||
BASE_URL = baseUrl;
|
||||
request.setAttribute("baseUrl", baseUrl);
|
||||
filterChain.doFilter(request, response);
|
||||
|
||||
@@ -2,16 +2,16 @@ package cn.keking.web.filter;
|
||||
|
||||
import cn.keking.config.ConfigConstants;
|
||||
import cn.keking.utils.WebUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.util.Base64Utils;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
|
||||
import javax.servlet.*;
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import javax.servlet.Filter;
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.FilterConfig;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
|
||||
/**
|
||||
* @author chenjh
|
||||
|
||||
0
server/src/main/resources/static/favicon.ico
Normal file
0
server/src/main/resources/static/favicon.ico
Normal file
6
server/src/main/resources/static/js/bootbox.min.js
vendored
Normal file
6
server/src/main/resources/static/js/bootbox.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@@ -2,7 +2,6 @@
|
||||
* Copyright 2013 I Doc View
|
||||
* @author Godwin <I Doc View>
|
||||
*/
|
||||
|
||||
var ratio = 0.75;
|
||||
var pages;
|
||||
var slideUrls = new Array();
|
||||
@@ -11,247 +10,248 @@ var curSlide = 1;
|
||||
var totalSize = 1; // PPT当前获取到的总页数
|
||||
var slideCount = 1; // PPT文件总页数
|
||||
var size = (!!$.url().param('size') ? $.url().param('size') : 0);
|
||||
$(document).ready(function() {
|
||||
|
||||
// async method:
|
||||
$.get('onlinePreview?' , params, function(data, status) {
|
||||
var data = JSON.parse(data);
|
||||
var code = data.code;
|
||||
if (1 == code) {
|
||||
uuid = data.uuid;
|
||||
pages = data.data;
|
||||
totalSize = pages.length;
|
||||
slideCount = data.totalSize;
|
||||
|
||||
// title
|
||||
$('.container-fluid:first .btn:first').after('<a class="brand lnk-file-title" style="text-decoration: none;" href="' + contextPath + '/doc/download/' + uuid + (!!queryStr ? '?' + queryStr : '') + '" title="' + data.name + '">' + data.name + '</a>');
|
||||
document.title = data.name;
|
||||
|
||||
// set ratio
|
||||
ratio = pages[0].ratio;
|
||||
|
||||
// reset all content
|
||||
resetContent();
|
||||
|
||||
afterLoad();
|
||||
} else {
|
||||
$('.container-fluid .row-fluid').html('<section><div class="alert alert-error">' + data.desc + '</div></section>');
|
||||
}
|
||||
$(document).ready(function () {
|
||||
var data = resultData
|
||||
var code = data.code;
|
||||
if (1 == code) {
|
||||
uuid = data.uuid;
|
||||
pages = data.data;
|
||||
totalSize = pages.length;
|
||||
slideCount = data.totalSize;
|
||||
|
||||
clearProgress();
|
||||
});
|
||||
// title
|
||||
$('.container-fluid:first .btn:first').after('<a class="brand lnk-file-title" style="text-decoration: none;">' + data.name + '</a>');
|
||||
document.title = data.name;
|
||||
|
||||
// 是否显示全屏按钮
|
||||
$('.fullscreen-link').toggle(screenfull.enabled);
|
||||
// 全屏事件
|
||||
$('.fullscreen-link').click(function(){
|
||||
if (screenfull.enabled) {
|
||||
screenfull.toggle($('.slide-img-container')[0]);
|
||||
}
|
||||
});
|
||||
$(document).bind("fullscreenchange", function() {
|
||||
if (screenfull.isFullscreen) {
|
||||
$('.slide-img-container').css('background-color', 'black');
|
||||
$('.slide-img-container').contextMenu(true);
|
||||
} else {
|
||||
$('.slide-img-container').css('background-color', '');
|
||||
$('.slide-img-container').contextMenu(false);
|
||||
}
|
||||
});
|
||||
|
||||
$('.select-page-selector').change(function() {
|
||||
var selectNum = $(".select-page-selector option:selected").text();
|
||||
gotoSlide(selectNum);
|
||||
});
|
||||
$('.slide-img-container .ppt-turn-left-mask').click(function () {
|
||||
preSlide();
|
||||
});
|
||||
$('.slide-img-container .ppt-turn-right-mask').click(function () {
|
||||
nextSlide();
|
||||
});
|
||||
// set ratio
|
||||
ratio = pages[0].ratio;
|
||||
|
||||
// Right click (NOT supported in SOUGOU browser)
|
||||
/*
|
||||
$.contextMenu({
|
||||
// reset all content
|
||||
resetContent();
|
||||
|
||||
afterLoad();
|
||||
} else {
|
||||
$('.container-fluid .row-fluid').html('<section><div class="alert alert-error">' + data.desc + '</div></section>');
|
||||
}
|
||||
clearProgress();
|
||||
|
||||
// 是否显示全屏按钮
|
||||
$('.fullscreen-link').toggle(screenfull.enabled);
|
||||
// 全屏事件
|
||||
$('.fullscreen-link').click(function () {
|
||||
if (screenfull.enabled) {
|
||||
screenfull.toggle($('.slide-img-container')[0]);
|
||||
}
|
||||
});
|
||||
$(document).bind("fullscreenchange", function () {
|
||||
if (screenfull.isFullscreen) {
|
||||
$('.slide-img-container').css('background-color', 'black');
|
||||
$('.slide-img-container').contextMenu(true);
|
||||
} else {
|
||||
$('.slide-img-container').css('background-color', '');
|
||||
$('.slide-img-container').contextMenu(false);
|
||||
}
|
||||
});
|
||||
|
||||
$('.select-page-selector').change(function () {
|
||||
var selectNum = $(".select-page-selector option:selected").text();
|
||||
gotoSlide(selectNum);
|
||||
});
|
||||
$('.slide-img-container .ppt-turn-left-mask').click(function () {
|
||||
preSlide();
|
||||
});
|
||||
$('.slide-img-container .ppt-turn-right-mask').click(function () {
|
||||
nextSlide();
|
||||
});
|
||||
|
||||
// Right click (NOT supported in SOUGOU browser)
|
||||
/*
|
||||
$.contextMenu({
|
||||
selector: '.slide-img-container',
|
||||
items: {
|
||||
"next": {
|
||||
"next": {
|
||||
name: "下一张",
|
||||
callback: function(key, options) {
|
||||
nextSlide();
|
||||
nextSlide();
|
||||
}
|
||||
},
|
||||
"previous": {
|
||||
name: "上一张",
|
||||
callback: function(key, options) {
|
||||
preSlide();
|
||||
preSlide();
|
||||
}
|
||||
},
|
||||
"sep1": "---------",
|
||||
"exit": {
|
||||
name: "结束放映",
|
||||
callback: function(key, options) {
|
||||
$('.slide-img-container').fullScreen(false);
|
||||
$('.slide-img-container').fullScreen(false);
|
||||
}
|
||||
},
|
||||
}
|
||||
});
|
||||
*/
|
||||
$('.slide-img-container').contextMenu(false);
|
||||
|
||||
// Swipe method is NOT supported in IE6, so it should be the last one.
|
||||
try {
|
||||
$('.slide-img-container').swipeleft(function() { nextSlide(); });
|
||||
$('.slide-img-container').swiperight(function() { preSlide(); });
|
||||
} catch (err) {
|
||||
$('.slide-img-container').contextMenu(false);
|
||||
|
||||
}
|
||||
// Swipe method is NOT supported in IE6, so it should be the last one.
|
||||
try {
|
||||
$('.slide-img-container').swipeleft(function () {
|
||||
nextSlide();
|
||||
});
|
||||
$('.slide-img-container').swiperight(function () {
|
||||
preSlide();
|
||||
});
|
||||
} catch (err) {
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
var remainContentInterval;
|
||||
function checkRemainContent () {
|
||||
clearInterval(remainContentInterval);
|
||||
if (slideCount == totalSize) {
|
||||
return;
|
||||
}
|
||||
|
||||
function checkRemainContent() {
|
||||
clearInterval(remainContentInterval);
|
||||
if (slideCount == totalSize) {
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function resetContent() {
|
||||
remainContentInterval = setInterval(checkRemainContent, 8000);
|
||||
remainContentInterval = setInterval(checkRemainContent, 8000);
|
||||
|
||||
// clear all content
|
||||
$('.row-fluid .span2').empty();
|
||||
$('.select-page-selector').empty();
|
||||
$('.select-page-selector-sync').empty();
|
||||
$('.slide-img-container img').remove();
|
||||
// clear all content
|
||||
$('.row-fluid .span2').empty();
|
||||
$('.select-page-selector').empty();
|
||||
$('.select-page-selector-sync').empty();
|
||||
$('.slide-img-container img').remove();
|
||||
|
||||
// 限制预览页数开始
|
||||
var viewCheck = authMap.view;
|
||||
if (!!viewCheck && (viewCheck > 1) && (pages.length > viewCheck)) {
|
||||
$('.navbar').after('<div class="alert alert-info" style="text-align: center; color: red;">试读结束,支付后阅读全文!</div>');
|
||||
totalSize = viewCheck;
|
||||
clearInterval(remainContentInterval);
|
||||
}
|
||||
// 限制预览页数结束
|
||||
// 限制预览页数开始
|
||||
var viewCheck = authMap.view;
|
||||
if (!!viewCheck && (viewCheck > 1) && (pages.length > viewCheck)) {
|
||||
$('.navbar').after('<div class="alert alert-info" style="text-align: center; color: red;">试读结束,支付后阅读全文!</div>');
|
||||
totalSize = viewCheck;
|
||||
clearInterval(remainContentInterval);
|
||||
}
|
||||
// 限制预览页数结束
|
||||
|
||||
// pages
|
||||
for (i = 0; i < totalSize; i++) {
|
||||
var page = pages[i];
|
||||
slideUrls[i] = page.url;
|
||||
slideThumbUrls[i] = page.thumbUrl;
|
||||
$('.row-fluid .span2').append('<div class="thumbnail" page="' + (i + 1) + '"><img src="' + page.thumbUrl + '"></div><div class="thumb-page-number-container">' + (i + 1) + '/' + slideCount + '</div>');
|
||||
$('.select-page-selector').append('<option>' + (i + 1) + '</option>');
|
||||
$('.select-page-selector-sync').append('<option>' + (i + 1) + '</option>');
|
||||
}
|
||||
// pages
|
||||
for (i = 0; i < totalSize; i++) {
|
||||
var page = pages[i];
|
||||
slideUrls[i] = page.url;
|
||||
slideThumbUrls[i] = page.thumbUrl;
|
||||
$('.row-fluid .span2').append('<div class="thumbnail" page="' + (i + 1) + '"><img src="' + page.thumbUrl + '"></div><div class="thumb-page-number-container">' + (i + 1) + '/' + slideCount + '</div>');
|
||||
$('.select-page-selector').append('<option>' + (i + 1) + '</option>');
|
||||
$('.select-page-selector-sync').append('<option>' + (i + 1) + '</option>');
|
||||
}
|
||||
|
||||
// 未转换完成提示信息
|
||||
if (totalSize < slideCount) {
|
||||
$('.row-fluid .span2').prepend('<div style="color: red;">转换中(' + Math.floor((totalSize / slideCount) * 100) + '%),请稍候……</div>');
|
||||
}
|
||||
// 未转换完成提示信息
|
||||
if (totalSize < slideCount) {
|
||||
$('.row-fluid .span2').prepend('<div style="color: red;">转换中(' + Math.floor((totalSize / slideCount) * 100) + '%),请稍候……</div>');
|
||||
}
|
||||
|
||||
$('.slide-img-container').append('<img src="' + slideUrls[curSlide - 1] + '" class="img-polaroid" style="height: 100%;">');
|
||||
var thumbnailWidth = $('.thumbnail:first').width();
|
||||
var thumbnailHeight = thumbnailWidth * ratio;
|
||||
$('.thumbnail').height(thumbnailHeight);
|
||||
$('.thumbnail>img').width(thumbnailWidth).height(thumbnailHeight);
|
||||
$('.slide-img-container').append('<img src="' + slideUrls[curSlide - 1] + '" class="img-polaroid" style="height: 100%;">');
|
||||
var thumbnailWidth = $('.thumbnail:first').width();
|
||||
var thumbnailHeight = thumbnailWidth * ratio;
|
||||
$('.thumbnail').height(thumbnailHeight);
|
||||
$('.thumbnail>img').width(thumbnailWidth).height(thumbnailHeight);
|
||||
|
||||
var slideImgContainerWidth = $('.slide-img-container:first').width();
|
||||
var slideImgContainerHeight = slideImgContainerWidth * ratio;
|
||||
$('.slide-img-container').height(slideImgContainerHeight);
|
||||
var slideImgContainerWidth = $('.slide-img-container:first').width();
|
||||
var slideImgContainerHeight = slideImgContainerWidth * ratio;
|
||||
$('.slide-img-container').height(slideImgContainerHeight);
|
||||
|
||||
resetImgSize();
|
||||
resetImgSize();
|
||||
|
||||
var percent = Math.ceil((curSlide / slideUrls.length) * 100);
|
||||
$('.thumbnail[page="' + curSlide + '"]').addClass('ppt-thumb-border');
|
||||
var percent = Math.ceil((curSlide / slideUrls.length) * 100);
|
||||
$('.thumbnail[page="' + curSlide + '"]').addClass('ppt-thumb-border');
|
||||
|
||||
// $('.thumbnail[page="' + curSlide + '"]').animate({scrollTop:($(window).height()/2)}, 'slow');
|
||||
// $('.thumbnail[page="' + curSlide + '"]').animate({scrollTop:($(window).height()/2)}, 'slow');
|
||||
|
||||
$('.select-page-selector').val(curSlide);
|
||||
$('.bottom-paging-progress .bar').width('' + percent + '%');
|
||||
$('.select-page-selector').val(curSlide);
|
||||
$('.bottom-paging-progress .bar').width('' + percent + '%');
|
||||
|
||||
$('.thumbnail').click(function () {
|
||||
var page_num = $(this).attr('page');
|
||||
gotoSlide(page_num);
|
||||
});
|
||||
$('.thumbnail').click(function () {
|
||||
var page_num = $(this).attr('page');
|
||||
gotoSlide(page_num);
|
||||
});
|
||||
}
|
||||
|
||||
$(window).resize(function() {
|
||||
resetImgSize();
|
||||
$(window).resize(function () {
|
||||
resetImgSize();
|
||||
});
|
||||
|
||||
function resetImgSize() {
|
||||
var leftW = $('.row-fluid .span2').width() + 40;
|
||||
var windowW = $(window).width();
|
||||
if (windowW < 768) {
|
||||
leftW = -40;
|
||||
$('.hidden-phone').css('display', 'none');
|
||||
$('.span9').removeClass('offset2');
|
||||
} else {
|
||||
$('.hidden-phone').css('display', 'block');
|
||||
$('.span9').addClass('offset2');
|
||||
}
|
||||
var ww = $(window).width() - 120 - leftW;
|
||||
var wh = $(window).height() - 90;
|
||||
if (screenfull.isFullscreen) {
|
||||
ww = ww + 90 + leftW;
|
||||
wh = wh + 80;
|
||||
}
|
||||
if (wh / ww < ratio) {
|
||||
$('.slide-img-container').height(wh);
|
||||
$('.slide-img-container').width(wh / ratio);
|
||||
} else {
|
||||
$('.slide-img-container').width(ww);
|
||||
$('.slide-img-container').height(ww * ratio);
|
||||
}
|
||||
var leftW = $('.row-fluid .span2').width() + 40;
|
||||
var windowW = $(window).width();
|
||||
if (windowW < 768) {
|
||||
leftW = -40;
|
||||
$('.hidden-phone').css('display', 'none');
|
||||
$('.span9').removeClass('offset2');
|
||||
} else {
|
||||
$('.hidden-phone').css('display', 'block');
|
||||
$('.span9').addClass('offset2');
|
||||
}
|
||||
var ww = $(window).width() - 120 - leftW;
|
||||
var wh = $(window).height() - 90;
|
||||
if (screenfull.isFullscreen) {
|
||||
ww = ww + 90 + leftW;
|
||||
wh = wh + 80;
|
||||
}
|
||||
if (wh / ww < ratio) {
|
||||
$('.slide-img-container').height(wh);
|
||||
$('.slide-img-container').width(wh / ratio);
|
||||
} else {
|
||||
$('.slide-img-container').width(ww);
|
||||
$('.slide-img-container').height(ww * ratio);
|
||||
}
|
||||
}
|
||||
|
||||
$(document).keydown(function(event){
|
||||
if (event.keyCode == 37 || event.keyCode == 38 || event.keyCode == 33) { // 37 left, 38 up, 33 pageUp
|
||||
preSlide();
|
||||
} else if (event.keyCode == 39 || event.keyCode == 40 || event.keyCode == 32 || event.keyCode == 34){ // 39 right, 40 down, 32 space, 34 pageDown
|
||||
nextSlide();
|
||||
} else if (event.keyCode == 13) {
|
||||
screenfull.toggle($('.slide-img-container')[0]);
|
||||
}
|
||||
$(document).keydown(function (event) {
|
||||
if (event.keyCode == 37 || event.keyCode == 38 || event.keyCode == 33) { // 37 left, 38 up, 33 pageUp
|
||||
preSlide();
|
||||
} else if (event.keyCode == 39 || event.keyCode == 40 || event.keyCode == 32 || event.keyCode == 34) { // 39 right, 40 down, 32 space, 34 pageDown
|
||||
nextSlide();
|
||||
} else if (event.keyCode == 13) {
|
||||
screenfull.toggle($('.slide-img-container')[0]);
|
||||
}
|
||||
});
|
||||
|
||||
function getCurSlide() {
|
||||
return curSlide;
|
||||
return curSlide;
|
||||
}
|
||||
|
||||
function preSlide() {
|
||||
var preSlide = eval(Number(getCurSlide()) - 1);
|
||||
gotoSlide(preSlide);
|
||||
var preSlide = eval(Number(getCurSlide()) - 1);
|
||||
gotoSlide(preSlide);
|
||||
}
|
||||
|
||||
function nextSlide() {
|
||||
var nextSlide = eval(Number(getCurSlide()) + 1);
|
||||
gotoSlide(nextSlide);
|
||||
var nextSlide = eval(Number(getCurSlide()) + 1);
|
||||
gotoSlide(nextSlide);
|
||||
}
|
||||
|
||||
function gotoSlide(slide) {
|
||||
var slideSum = slideUrls.length;
|
||||
if (slide <= 0) {
|
||||
slide = 1;
|
||||
} else if (slideSum < slide) {
|
||||
slide = slideSum;
|
||||
}
|
||||
curSlide = slide;
|
||||
/*
|
||||
$(".slide-img-container img").fadeOut(function() {
|
||||
$(this).attr("src", slideUrls[slide - 1]).fadeIn();
|
||||
});
|
||||
*/
|
||||
$(".slide-img-container img").attr("src", slideUrls[slide - 1]);
|
||||
var percent = Math.ceil((curSlide / slideUrls.length) * 100);
|
||||
$('.thumbnail').removeClass('ppt-thumb-border');
|
||||
$('.thumbnail[page="' + slide + '"]').addClass('ppt-thumb-border');
|
||||
var thumbTop = slide * ($('.thumbnail[page="' + 1 + '"]').height() + 10 + $('.thumb-page-number-container').height()) - ($(document).height() / 2);
|
||||
$('.span2 ').animate({scrollTop:(thumbTop)}, 'slow');
|
||||
$('.select-page-selector').val(slide);
|
||||
$('.select-page-selector-sync').val(slide);
|
||||
$('.bottom-paging-progress .bar').width('' + percent + '%');
|
||||
var slideSum = slideUrls.length;
|
||||
if (slide <= 0) {
|
||||
slide = 1;
|
||||
} else if (slideSum < slide) {
|
||||
slide = slideSum;
|
||||
}
|
||||
curSlide = slide;
|
||||
/*
|
||||
$(".slide-img-container img").fadeOut(function() {
|
||||
$(this).attr("src", slideUrls[slide - 1]).fadeIn();
|
||||
});
|
||||
*/
|
||||
$(".slide-img-container img").attr("src", slideUrls[slide - 1]);
|
||||
var percent = Math.ceil((curSlide / slideUrls.length) * 100);
|
||||
$('.thumbnail').removeClass('ppt-thumb-border');
|
||||
$('.thumbnail[page="' + slide + '"]').addClass('ppt-thumb-border');
|
||||
var thumbTop = slide * ($('.thumbnail[page="' + 1 + '"]').height() + 10 + $('.thumb-page-number-container').height()) - ($(document).height() / 2);
|
||||
$('.span2 ').animate({scrollTop: (thumbTop)}, 'slow');
|
||||
$('.select-page-selector').val(slide);
|
||||
$('.select-page-selector-sync').val(slide);
|
||||
$('.bottom-paging-progress .bar').width('' + percent + '%');
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
|
||||
|
||||
<#setting classic_compatible=true>
|
||||
<link rel="icon" href="./favicon.ico" type="image/x-icon">
|
||||
<link rel="stylesheet" href="bootstrap/css/bootstrap.min.css"/>
|
||||
<script src="js/jquery-3.0.0.min.js" type="text/javascript"></script>
|
||||
<script src="js/jquery.form.min.js" type="text/javascript"></script>
|
||||
<script src="bootstrap/js/bootstrap.min.js" type="text/javascript"></script>
|
||||
<script src="js/bootbox.min.js" type="text/javascript"></script>
|
||||
<script src="js/watermark.js" type="text/javascript"></script>
|
||||
<script src="js/base64.min.js" type="text/javascript"></script>
|
||||
|
||||
@@ -33,7 +34,52 @@
|
||||
}
|
||||
}
|
||||
|
||||
// 中文环境
|
||||
var locale_zh_CN = {
|
||||
OK: '确定',
|
||||
CONFIRM: '确认',
|
||||
CANCEL: '取消'
|
||||
};
|
||||
bootbox.addLocale('locale_zh_CN', locale_zh_CN);
|
||||
|
||||
/**
|
||||
* 需要文件密码
|
||||
*/
|
||||
function needFilePassword() {
|
||||
if ('${needFilePassword}' == 'true') {
|
||||
let promptTitle = "你正在预览加密文件,请输入文件密码。";
|
||||
if ('${filePasswordError}' == 'true') {
|
||||
promptTitle = "密码错误,请重新输入密码。";
|
||||
}
|
||||
|
||||
bootbox.prompt({
|
||||
title: promptTitle,
|
||||
inputType: 'password',
|
||||
centerVertical: true,
|
||||
locale: 'locale_zh_CN',
|
||||
callback: function (filePassword) {
|
||||
if (filePassword != null) {
|
||||
const locationHref = window.location.href;
|
||||
const isInclude = locationHref.includes("filePassword=");
|
||||
let redirectUrl = null;
|
||||
if (isInclude) {
|
||||
const url = new URL(locationHref);
|
||||
url.searchParams.set("filePassword", filePassword);
|
||||
redirectUrl = url.href;
|
||||
} else {
|
||||
redirectUrl = locationHref + '&filePassword=' + filePassword;
|
||||
}
|
||||
|
||||
window.location.replace(redirectUrl);
|
||||
} else {
|
||||
location.reload();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
@@ -44,6 +90,4 @@
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
|
||||
@@ -1,42 +1,46 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta charset="utf-8"/>
|
||||
<style type="text/css">
|
||||
body{
|
||||
body {
|
||||
margin: 0 auto;
|
||||
width:900px;
|
||||
width: 900px;
|
||||
background-color: #CCB;
|
||||
}
|
||||
.container{
|
||||
|
||||
.container {
|
||||
width: 700px;
|
||||
height: 700px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
img{
|
||||
width:auto;
|
||||
height:auto;
|
||||
max-width:100%;
|
||||
max-height:100%;
|
||||
|
||||
img {
|
||||
width: auto;
|
||||
height: auto;
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
padding-bottom: 36px;
|
||||
}
|
||||
span{
|
||||
|
||||
span {
|
||||
display: block;
|
||||
font-size:20px;
|
||||
color:blue;
|
||||
font-size: 20px;
|
||||
color: blue;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="container">
|
||||
<img src="images/sorry.jpg" />
|
||||
<img src="images/sorry.jpg"/>
|
||||
<span>
|
||||
该文件类型(${fileType})系统暂时不支持在线预览,<b>说明</b>:
|
||||
该(${fileType})文件,系统暂不支持在线预览,具体原因如下:
|
||||
<p style="color: red;">${msg}</p>
|
||||
有任何疑问,请加 <a href="https://jq.qq.com/?_wv=1027&k=5c0UAtu">官方QQ群:613025121</a> 咨询
|
||||
</span>
|
||||
</div>
|
||||
<script>
|
||||
console.log(`有任何疑问,请加:<a href="https://jq.qq.com/?_wv=1027&k=5c0UAtu">官方QQ群:613025121</a> 咨询`);
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -2,25 +2,31 @@
|
||||
|
||||
<html lang="en">
|
||||
<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">
|
||||
</head>
|
||||
<body>
|
||||
<iframe src="${pdfUrl}" width="100%" frameborder="0"></iframe>
|
||||
<iframe src="${pdfUrl}" width="100%" frameborder="0"></iframe>
|
||||
</body>
|
||||
|
||||
<script type="text/javascript">
|
||||
document.getElementsByTagName('iframe')[0].height = document.documentElement.clientHeight-10;
|
||||
needFilePassword();
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
document.getElementsByTagName('iframe')[0].height = document.documentElement.clientHeight - 10;
|
||||
/**
|
||||
* 页面变化调整高度
|
||||
*/
|
||||
window.onresize = function(){
|
||||
window.onresize = function () {
|
||||
var fm = document.getElementsByTagName("iframe")[0];
|
||||
fm.height = window.document.documentElement.clientHeight-10;
|
||||
fm.height = window.document.documentElement.clientHeight - 10;
|
||||
}
|
||||
/*初始化水印*/
|
||||
window.onload = function() {
|
||||
initWaterMark();
|
||||
window.onload = function () {
|
||||
initWaterMark();
|
||||
}
|
||||
</script>
|
||||
</html>
|
||||
</html>
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
<meta charset="utf-8"/>
|
||||
<meta name="viewport" content="width=device-width, user-scalable=yes, initial-scale=1.0"/>
|
||||
<title>kkFileView演示首页</title>
|
||||
<link rel="icon" href="./favicon.ico" type="image/x-icon">
|
||||
<link rel="stylesheet" href="css/viewer.min.css"/>
|
||||
<link rel="stylesheet" href="css/loading.css"/>
|
||||
<link rel="stylesheet" href="bootstrap/css/bootstrap.min.css"/>
|
||||
@@ -262,13 +263,14 @@
|
||||
}, {
|
||||
field: 'action',
|
||||
title: '操作'
|
||||
},]
|
||||
}]
|
||||
}).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(Base64.encode('${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) {
|
||||
return data;
|
||||
@@ -281,7 +283,6 @@
|
||||
urlField.val(b64Encoded);
|
||||
});
|
||||
|
||||
|
||||
function showLoadingDiv() {
|
||||
var height = window.document.documentElement.clientHeight - 1;
|
||||
$(".loading_container").css("height", height).show();
|
||||
@@ -307,6 +308,7 @@
|
||||
dataType: "json" /*设置返回值类型为文本*/
|
||||
});
|
||||
});
|
||||
|
||||
var gitalk = new Gitalk({
|
||||
clientID: '525d7f16e17aab08cef5',
|
||||
clientSecret: 'd1154e3aee5c8f1cbdc918b5c97a4f4157e0bfd9',
|
||||
@@ -321,4 +323,4 @@
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
@@ -7,6 +6,7 @@
|
||||
<title>PDF预览</title>
|
||||
<#include "*/commonHeader.ftl">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<#if pdfUrl?contains("http://") || pdfUrl?contains("https://")>
|
||||
<#assign finalUrl="${pdfUrl}">
|
||||
@@ -20,11 +20,12 @@
|
||||
onclick="goForImage()"/>
|
||||
</#if>
|
||||
</body>
|
||||
|
||||
<script type="text/javascript">
|
||||
var url = '${finalUrl}';
|
||||
var baseUrl = '${baseUrl}'.endsWith('/') ? '${baseUrl}' : '${baseUrl}' + '/';
|
||||
if (!url.startsWith(baseUrl)) {
|
||||
url = baseUrl + 'getCorsFile?urlPath=' + encodeURIComponent(url);
|
||||
url = baseUrl + 'getCorsFile?urlPath=' + encodeURIComponent(Base64.encode(url));
|
||||
}
|
||||
document.getElementsByTagName('iframe')[0].src = "${baseUrl}pdfjs/web/viewer.html?file=" + encodeURIComponent(url) + "&disablepresentationmode=${pdfPresentationModeDisable}&disableopenfile=${pdfOpenFileDisable}&disableprint=${pdfPrintDisable}&disabledownload=${pdfDownloadDisable}&disablebookmark=${pdfBookmarkDisable}";
|
||||
document.getElementsByTagName('iframe')[0].height = document.documentElement.clientHeight - 10;
|
||||
@@ -51,4 +52,4 @@
|
||||
initWaterMark();
|
||||
}
|
||||
</script>
|
||||
</html>
|
||||
</html>
|
||||
|
||||
@@ -1,149 +1,136 @@
|
||||
<#if RequestParameters['name']??>
|
||||
{
|
||||
"code": 1,
|
||||
"name": "PPT预览",
|
||||
"totalSize": ${imgurls?size},
|
||||
"curPage": 1,
|
||||
"totalPage": 1,
|
||||
"pageSize": 10,
|
||||
"titles": null,
|
||||
"data": [
|
||||
<#assign index = 0>
|
||||
<#list imgurls as img>
|
||||
<#if index != 0>,</#if>{
|
||||
"uuid": null,
|
||||
"title": null,
|
||||
"content": null,
|
||||
"text": null,
|
||||
"url": "${img}",
|
||||
"destFile": null,
|
||||
"viewCount": 0,
|
||||
"downloadCount": 0,
|
||||
"ctime": null,
|
||||
"thumbUrl": "${img}",
|
||||
"largeUrl": null,
|
||||
"ratio": 0.5625,
|
||||
"note": null
|
||||
}<#assign index = index + 1>
|
||||
</#list>],
|
||||
"desc": "Success"
|
||||
}
|
||||
|
||||
<#else>
|
||||
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<link href="pptx/bootstrap/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link href="pptx/idocv/idocv_common.min.css" rel="stylesheet">
|
||||
<link href="pptx/jquery.contextMenu.css" rel="stylesheet">
|
||||
|
||||
<!-- BOOTSTRAP STYLE start -->
|
||||
<!-- Le styles -->
|
||||
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<link href="pptx/bootstrap/css/bootstrap.min.css" rel="stylesheet">
|
||||
|
||||
<link href="pptx/idocv/idocv_common.min.css" rel="stylesheet">
|
||||
|
||||
<link href="pptx/jquery.contextMenu.css" rel="stylesheet">
|
||||
|
||||
<!-- BOOTSTRAP STYLE end -->
|
||||
|
||||
<#-- 手机端预览兼容 -->
|
||||
<script type="text/javascript">
|
||||
var windowWidth = document.documentElement.clientWidth;
|
||||
var searchStr = window.location.search.substr(1);
|
||||
if ((windowWidth < 768 || (/micromessenger/.test(navigator.userAgent.toLowerCase()))) && (!searchStr || searchStr.indexOf('type=') < 0)) {
|
||||
var redirectUrl = window.location.pathname + '?type=mobile' + (!!searchStr ? ('&' + searchStr) : '');
|
||||
window.location.replace(redirectUrl);
|
||||
}
|
||||
var windowWidth = document.documentElement.clientWidth;
|
||||
var searchStr = window.location.search.substr(1);
|
||||
if ((windowWidth < 768 || (/micromessenger/.test(navigator.userAgent.toLowerCase()))) && (!searchStr || searchStr.indexOf('type=') < 0)) {
|
||||
var redirectUrl = window.location.pathname + '?type=mobile' + (!!searchStr ? ('&' + searchStr) : '');
|
||||
window.location.replace(redirectUrl);
|
||||
}
|
||||
</script>
|
||||
|
||||
<style type="text/css">
|
||||
.thumbnail{
|
||||
/*
|
||||
max-width: 200px;
|
||||
*/
|
||||
cursor: pointer;
|
||||
}
|
||||
.thumbnail {
|
||||
/*
|
||||
max-width: 200px;
|
||||
*/
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
<!--[if lt IE 9]>
|
||||
<script src="/static/bootstrap/js/html5shiv.js"></script>
|
||||
<script src="/static/bootstrap/js/html5shiv.js"></script>
|
||||
<![endif]-->
|
||||
</head>
|
||||
|
||||
</head>
|
||||
|
||||
<body onload="resetImgSize();" class="ppt-body">
|
||||
<body onload="resetImgSize();" class="ppt-body">
|
||||
|
||||
<div class="loading-mask" style="display: block;">
|
||||
<div class="loading-zone">
|
||||
<div class="text"><img src="pptx/img/loader_indicator_lite.gif">加载中...</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
<div class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
<div class="container-fluid">
|
||||
<button type="button" class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<!-- FILE NAME HERE -->
|
||||
<!-- SIGN UP & SIGN IN -->
|
||||
|
||||
<div class="nav-collapse collapse">
|
||||
<p class="navbar-text pull-right">
|
||||
<a href="#" title="全屏" class="fullscreen-link"><i class="icon-fullscreen icon-white"></i></a>
|
||||
</p>
|
||||
</div><!--/.nav-collapse -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button type="button" class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<!-- FILE NAME HERE -->
|
||||
<!-- SIGN UP & SIGN IN -->
|
||||
|
||||
<div class="container-fluid" style="max-height: 100%;">
|
||||
<div class="row-fluid">
|
||||
<div class="span2 hidden-phone" style="position: fixed; top: 60px; left: 20px; bottom: 20px; padding-right: 10px; border-right: 3px solid #c8c8c8; max-height: 100%; overflow: auto; text-align: center;">
|
||||
<!--Sidebar content-->
|
||||
<!--
|
||||
<div class="thumbnail">
|
||||
<img src="">
|
||||
</div>
|
||||
1/20<br />
|
||||
-->
|
||||
<div class="nav-collapse collapse">
|
||||
<p class="navbar-text pull-right">
|
||||
<a href="#" title="全屏" class="fullscreen-link"><i class="icon-fullscreen icon-white"></i></a>
|
||||
</p>
|
||||
</div><!--/.nav-collapse -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container-fluid" style="max-height: 100%;">
|
||||
<div class="row-fluid">
|
||||
<div class="span2 hidden-phone"
|
||||
style="position: fixed; top: 60px; left: 20px; bottom: 20px; padding-right: 10px; border-right: 3px solid #c8c8c8; max-height: 100%; overflow: auto; text-align: center;">
|
||||
<!--Sidebar content-->
|
||||
<!--
|
||||
<div class="thumbnail">
|
||||
<img src="">
|
||||
</div>
|
||||
1/20<br />
|
||||
-->
|
||||
</div>
|
||||
<div class="span9 offset2">
|
||||
<div class="slide-img-container">
|
||||
<div class="ppt-turn-left-mask"></div>
|
||||
<div class="ppt-turn-right-mask"></div>
|
||||
<!--
|
||||
<img src="" class="img-polaroid" style="max-height: 100%;">
|
||||
-->
|
||||
</div>
|
||||
<!-- ONLY AVAILABLE ON MOBILE -->
|
||||
<div class="span12 visible-phone text-center" style="position: fixed; bottom: 10px; left: 0px; z-index: 1000;">
|
||||
<select class="select-page-selector span1" style="width: 80px; margin-top: 10px;">
|
||||
<!-- PAGE NUMBERS HERE -->
|
||||
</select>
|
||||
</div>
|
||||
<div class="slide-img-container">
|
||||
<div class="ppt-turn-left-mask"></div>
|
||||
<div class="ppt-turn-right-mask"></div>
|
||||
<!--
|
||||
<img src="" class="img-polaroid" style="max-height: 100%;">
|
||||
-->
|
||||
</div>
|
||||
<!-- ONLY AVAILABLE ON MOBILE -->
|
||||
<div class="span12 visible-phone text-center"
|
||||
style="position: fixed; bottom: 10px; left: 0px; z-index: 1000;">
|
||||
<select class="select-page-selector span1" style="width: 80px; margin-top: 10px;">
|
||||
<!-- PAGE NUMBERS HERE -->
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="progress progress-striped active bottom-paging-progress">
|
||||
<div class="bar" style="width: 0%;"></div>
|
||||
</div>
|
||||
<!-- JavaSript
|
||||
================================================== -->
|
||||
|
||||
</div>
|
||||
|
||||
<div class="progress progress-striped active bottom-paging-progress">
|
||||
<div class="bar" style="width: 0%;"></div>
|
||||
</div>
|
||||
|
||||
<!-- JavaSript ================================================== -->
|
||||
<script src="pptx/jquery-3.5.1.min.js"></script>
|
||||
<script src="pptx/jquery.contextMenu.js?v=11.2.5_20210128"></script>
|
||||
<script src="pptx/idocv/idocv_common.min.js"></script>
|
||||
|
||||
<script>
|
||||
var resultData = {
|
||||
"code": 1,
|
||||
"name": "PPT预览",
|
||||
"totalSize": ${imgurls?size},
|
||||
"curPage": 1,
|
||||
"totalPage": 1,
|
||||
"pageSize": 10,
|
||||
"titles": null,
|
||||
"data": [
|
||||
<#assign index = 0>
|
||||
<#list imgurls as img>
|
||||
<#if index != 0>, </#if>{
|
||||
"uuid": null,
|
||||
"title": null,
|
||||
"content": null,
|
||||
"text": null,
|
||||
"url": "${img}",
|
||||
"destFile": null,
|
||||
"viewCount": 0,
|
||||
"downloadCount": 0,
|
||||
"ctime": null,
|
||||
"thumbUrl": "${img}",
|
||||
"largeUrl": null,
|
||||
"ratio": 0.5625,
|
||||
"note": null
|
||||
}<#assign index = index + 1>
|
||||
</#list>],
|
||||
"desc": "Success"
|
||||
}
|
||||
|
||||
var contextPath = '';
|
||||
var version = '12';
|
||||
// var urlObj = $.url($.url().attr('source').replace(contextPath, ''));
|
||||
@@ -166,10 +153,7 @@
|
||||
}
|
||||
</script>
|
||||
<!-- 客户自定义JS -->
|
||||
<script src="pptx/jquery.mobile-events.min.js"></script>
|
||||
<script src="pptx/ppt.js"></script>
|
||||
<script src="pptx/jquery.mobile-events.min.js"></script>
|
||||
<script src="pptx/ppt.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
</body>
|
||||
</html>
|
||||
</#if>
|
||||
|
||||
Reference in New Issue
Block a user