mirror of
https://github.com/kekingcn/kkFileView.git
synced 2026-03-30 13:22:33 +00:00
Compare commits
24 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
05464bbf1c | ||
|
|
cbe22c259f | ||
|
|
976a071089 | ||
|
|
bb7407542f | ||
|
|
2f86701eea | ||
|
|
5b5388e51f | ||
|
|
02957d98fc | ||
|
|
e3126f3711 | ||
|
|
a04e68c1af | ||
|
|
d4515dfadd | ||
|
|
78de36964d | ||
|
|
dcf37b94db | ||
|
|
73764b027b | ||
|
|
6d621dc05f | ||
|
|
4d6c5501ae | ||
|
|
cd8d1e2ba8 | ||
|
|
4731772d38 | ||
|
|
bc9bb6862b | ||
|
|
4462bab4fa | ||
|
|
6d98c972d1 | ||
|
|
852abadf8f | ||
|
|
2a93f80827 | ||
|
|
a8aef1b97b | ||
|
|
3e5ba7d3ba |
90
README.en.md
Normal file
90
README.en.md
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
# file-online-preview
|
||||||
|
This kekingcn kkFileView software is intended to be a solution for previewing documents online. There are some similar paid products in the industry, at present.
|
||||||
|
Such as 【[永中office](http://dcs.yozosoft.com/)】,【[office365](http://www.officeweb365.com/)】,【[idocv](https://www.idocv.com/)】, etc..
|
||||||
|
The kekingcn kkFileView software is an open source implementation and released under the Apache License version 2. It's aimed to feedback the community after obtaining the consent of company executives,
|
||||||
|
special thanks to the supports of @唐老大 and the contributions of @端木详笑.
|
||||||
|
|
||||||
|
### Advantages
|
||||||
|
* build with the popular frame spring boot,
|
||||||
|
* easy to deploy and deploy,
|
||||||
|
* basically support online preview of mainstream office documents, such as Doc, docx, Excel, PDF, TXT, zip, rar, pictures, etc.
|
||||||
|
|
||||||
|
### The demo online
|
||||||
|
> Please treat public service kindly, or this would stop at any time.
|
||||||
|
|
||||||
|
URL:http://file.keking.cn/
|
||||||
|
|
||||||
|
### Project documentation
|
||||||
|
1. 中文文档:https://gitee.com/kekingcn/file-online-preview/blob/master/README.md
|
||||||
|
1. English document:https://github.com/kekingcn/kkFileView/blob/master/README.en.md
|
||||||
|
|
||||||
|
### Contact us && Join us
|
||||||
|
> We will answer everyone's questions which are found when using this project patiently.
|
||||||
|
And please Google or Baidu first before asking a question, so that we can solve then efficiently.
|
||||||
|
Cherish life away from ineffective communication.
|
||||||
|
|
||||||
|

|
||||||
|
QQ group:613025121
|
||||||
|
|
||||||
|
### Pictures for some samples
|
||||||
|
> Excel
|
||||||
|
|
||||||
|

|
||||||
|
> doc
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
> zip,rar
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
> png,jpeg,jpg,etc., support for zooming with mouse scroll, rotation, inversion,etc.
|
||||||
|
|
||||||
|

|
||||||
|
Considering space issues, the pictures of other types of documents will not be shown here.You can deploy it by yourself if you are interested in our project.The way to deploy is as below.
|
||||||
|
|
||||||
|
### Quick Start
|
||||||
|
> Technologies in this project
|
||||||
|
- spring boot: [spring boot Development Reference Guide](http://www.kailing.pub/PdfReader/web/viewer.html?file=springboot)
|
||||||
|
- freemarker
|
||||||
|
- redisson
|
||||||
|
- jodconverter
|
||||||
|
> Dependent External Environment
|
||||||
|
- redis
|
||||||
|
- OpenOffice or LibreOffice
|
||||||
|
|
||||||
|
1. First step:pull https://github.com/kekingcn/file-online-preview.git
|
||||||
|
|
||||||
|
2. Second step:configure redis address and OpenOffice directory,such as
|
||||||
|
```
|
||||||
|
#=============================================#Spring Redisson Configuration#===================================#
|
||||||
|
spring.redisson.address = 192.168.1.204:6379
|
||||||
|
##The folder for files which are uploaded to the server(Because of running as jar)
|
||||||
|
file.dir = C:\\Users\\yudian\\Desktop\\dev\\
|
||||||
|
## openoffice configuration
|
||||||
|
office.home = C:\\Program Files (x86)\\OpenOffice 4
|
||||||
|
|
||||||
|
```
|
||||||
|
'file.dir' is the real storage address of the converted files, please end with '/'.
|
||||||
|
|
||||||
|
3. Third step:Run the main method of FilePreviewApplication.java.After starting,visit 'http://localhost:8012/'.
|
||||||
|
If everything is ok,you will see the picture below.
|
||||||
|

|
||||||
|
|
||||||
|
### System Update History
|
||||||
|
|
||||||
|
> January 12th 2018 :
|
||||||
|
|
||||||
|
1. Support for multiple images preview
|
||||||
|
1. Support for images rotation preview in rar/zip
|
||||||
|
|
||||||
|
> January 2nd 2018 :
|
||||||
|
|
||||||
|
1. fixed gibberish issue when preview a txt document caused by the file encoding problem
|
||||||
|
1. fixed the issue that some module dependencies can not be found
|
||||||
|
1. add a spring boot profile, and support for Multi-environment configuration
|
||||||
|
1. add 'pdf.js' to preview the documents such as doc,etc.,support for generating doc headlines as pdf menu,support for mobile preview
|
||||||
|
|
||||||
|
### Register Usage
|
||||||
|
If this project is helpful for you, please register on 'https://gitee.com/kekingcn/file-online-preview/issues/IGSBV',
|
||||||
|
If this project helps you to economize the service charge for preview of documents, as well as you are willing to support us, click 【donate】 below to donate a cup of coffee, we would appreciate it.
|
||||||
39
README.md
39
README.md
@@ -1,9 +1,24 @@
|
|||||||
# file-online-preview
|
# file-online-preview
|
||||||
此项目为文件文档在线预览项目解决方案,对标业内付费产品有【[永中office](http://dcs.yozosoft.com/)】【[office365](http://www.officeweb365.com/)】【[idocv](https://www.idocv.com/)】等,在取得公司高层同意后以Apache协议开源出来反哺社区,在此特别感谢@唐老大的支持以及@端木详笑的贡献。该项目使用流行的spring boot搭建,易上手和部署,基本支持主流办公文档的在线预览,如doc,docx,Excel,pdf,txt,zip,rar,图片等等
|
此项目为文件文档在线预览项目解决方案,对标业内付费产品有【[永中office](http://dcs.yozosoft.com/)】【[office365](http://www.officeweb365.com/)】【[idocv](https://www.idocv.com/)】等,在取得公司高层同意后以Apache协议开源出来反哺社区,在此特别感谢@唐老大的支持以及@端木详笑的贡献。该项目使用流行的spring boot搭建,易上手和部署,基本支持主流办公文档的在线预览,如doc,docx,Excel,pdf,txt,zip,rar,图片等等
|
||||||
|
### 项目特性
|
||||||
|
|
||||||
|
1. 支持office,pdf等办公文档
|
||||||
|
1. 支持txt,java,php,py,md,js,css等所有纯文本
|
||||||
|
1. 支持zip,rar,jar,tar,gzip等压缩包
|
||||||
|
1. 支持jpg,jpeg,png,gif等图片预览(翻转,缩放,镜像)
|
||||||
|
1. 使用spring boot开发,预览服务搭建部署非常简便
|
||||||
|
1. rest接口提供服务,应用接入简单方便
|
||||||
|
1. 抽象预览服务接口,方便二次开发,非常方便添加其他类型文件预览支持
|
||||||
|
1. 最最重要Apache协议开源,代码pull下来想干嘛就干嘛
|
||||||
|
|
||||||
### 在线体验
|
### 在线体验
|
||||||
> 请善待公共服务,会不定时停用
|
> 请善待公共服务,会不定时停用
|
||||||
|
|
||||||
地址:http://58.246.254.194:8012/
|
地址:http://file.keking.cn/
|
||||||
|
|
||||||
|
### 项目文档(Project documentation)
|
||||||
|
1. 中文文档:https://gitee.com/kekingcn/file-online-preview/blob/master/README.md
|
||||||
|
1. English document:https://github.com/kekingcn/kkFileView/blob/master/README.en.md
|
||||||
|
|
||||||
### 联系我们,加入组织
|
### 联系我们,加入组织
|
||||||
> 我们会用心回答解决大家在项目使用中的问题,也请大家在提问前至少Google或baidu过,珍爱生命远离无效的交流沟通
|
> 我们会用心回答解决大家在项目使用中的问题,也请大家在提问前至少Google或baidu过,珍爱生命远离无效的交流沟通
|
||||||
@@ -55,6 +70,28 @@ file.dir为转换文件实际存储地址,注意要以/结尾
|
|||||||
3. 第三步:运行FilePreviewApplication的main方法,服务启动后,访问http://localhost:8012/
|
3. 第三步:运行FilePreviewApplication的main方法,服务启动后,访问http://localhost:8012/
|
||||||
会看到如下界面,代表服务启动成功
|
会看到如下界面,代表服务启动成功
|
||||||

|

|
||||||
|
|
||||||
|
### 历史更新记录
|
||||||
|
|
||||||
|
> 2018年01月17日 :
|
||||||
|
|
||||||
|
1. 优化项目结构,抽象文件预览接口,更方便的加入更多的文件类型预览支持,方便二次开发
|
||||||
|
1. 新增英文文档说明(@幻幻Fate,@汝辉)贡献
|
||||||
|
1. 新增图片预览文件支持类型
|
||||||
|
1. 修复压缩包内轮播图片总是从第一张开始的问题
|
||||||
|
|
||||||
|
> 2018年01月12日 :
|
||||||
|
|
||||||
|
1. 新增多图片同时预览
|
||||||
|
1. 支持压缩包内图片轮番预览
|
||||||
|
|
||||||
|
> 2018年01月02日 :
|
||||||
|
|
||||||
|
1. 修复txt等文本编码问题导致预览乱码
|
||||||
|
1. 修复项目模块依赖引入不到的问题
|
||||||
|
1. 新增spring boot profile,支持多环境配置
|
||||||
|
1. 引入pdf.js预览doc等文件,支持doc标题生成pdf预览菜单,支持手机端预览
|
||||||
|
|
||||||
### 使用登记
|
### 使用登记
|
||||||
如果这个项目解决了你的实际问题,可在https://gitee.com/kekingcn/file-online-preview/issues/IGSBV
|
如果这个项目解决了你的实际问题,可在https://gitee.com/kekingcn/file-online-preview/issues/IGSBV
|
||||||
登记下,如果节省了你的三方预览服务费用,也愿意支持下的话,可点击下方【捐助】请作者喝杯咖啡,也是非常感谢
|
登记下,如果节省了你的三方预览服务费用,也愿意支持下的话,可点击下方【捐助】请作者喝杯咖啡,也是非常感谢
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
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">
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>com.yudianbank</groupId>
|
<groupId>cn.keking</groupId>
|
||||||
<artifactId>jodconverter-core</artifactId>
|
<artifactId>jodconverter-core</artifactId>
|
||||||
<version>1.0-SNAPSHOT</version>
|
<version>1.0-SNAPSHOT</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|||||||
@@ -48,7 +48,7 @@
|
|||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.yudianbank</groupId>
|
<groupId>cn.keking</groupId>
|
||||||
<artifactId>jodconverter-core</artifactId>
|
<artifactId>jodconverter-core</artifactId>
|
||||||
<version>1.0-SNAPSHOT</version>
|
<version>1.0-SNAPSHOT</version>
|
||||||
<exclusions>
|
<exclusions>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.yudianbank;
|
package cn.keking;
|
||||||
|
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
@@ -8,7 +8,7 @@ import java.util.Properties;
|
|||||||
|
|
||||||
@SpringBootApplication
|
@SpringBootApplication
|
||||||
@EnableScheduling
|
@EnableScheduling
|
||||||
@ComponentScan(value = "com.yudianbank.*")
|
@ComponentScan(value = "cn.keking.*")
|
||||||
public class FilePreviewApplication {
|
public class FilePreviewApplication {
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
Properties properties = System.getProperties();
|
Properties properties = System.getProperties();
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.yudianbank.config;
|
package cn.keking.config;
|
||||||
|
|
||||||
import io.netty.channel.nio.NioEventLoopGroup;
|
import io.netty.channel.nio.NioEventLoopGroup;
|
||||||
import org.redisson.Redisson;
|
import org.redisson.Redisson;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.yudianbank.extend;
|
package cn.keking.extend;
|
||||||
|
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
import com.sun.star.beans.PropertyValue;
|
import com.sun.star.beans.PropertyValue;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.yudianbank.filters;
|
package cn.keking.filters;
|
||||||
|
|
||||||
import javax.servlet.*;
|
import javax.servlet.*;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.yudianbank.filters;
|
package cn.keking.filters;
|
||||||
|
|
||||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
package cn.keking.model;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by kl on 2018/1/17.
|
||||||
|
* Content :
|
||||||
|
*/
|
||||||
|
public class FileAttribute {
|
||||||
|
|
||||||
|
private FileType type;
|
||||||
|
|
||||||
|
private String suffix;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
private String url;
|
||||||
|
|
||||||
|
private String decodedUrl;
|
||||||
|
|
||||||
|
public FileAttribute() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public FileAttribute(FileType type, String suffix, String name, String url, String decodedUrl) {
|
||||||
|
this.type = type;
|
||||||
|
this.suffix = suffix;
|
||||||
|
this.name = name;
|
||||||
|
this.url = url;
|
||||||
|
this.decodedUrl = decodedUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FileType getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setType(FileType type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSuffix() {
|
||||||
|
return suffix;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSuffix(String suffix) {
|
||||||
|
this.suffix = suffix;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUrl() {
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUrl(String url) {
|
||||||
|
this.url = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDecodedUrl() {
|
||||||
|
return decodedUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDecodedUrl(String decodedUrl) {
|
||||||
|
this.decodedUrl = decodedUrl;
|
||||||
|
}
|
||||||
|
}
|
||||||
27
jodconverter-web/src/main/java/cn/keking/model/FileType.java
Normal file
27
jodconverter-web/src/main/java/cn/keking/model/FileType.java
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
package cn.keking.model;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by kl on 2018/1/17.
|
||||||
|
* Content :文件类型,文本,office,压缩包等等
|
||||||
|
*/
|
||||||
|
public enum FileType {
|
||||||
|
picture("pictureFilePreviewImpl"),
|
||||||
|
compress("compressFilePreviewImpl"),
|
||||||
|
office("officeFilePreviewImpl"),
|
||||||
|
simText("simTextFilePreviewImpl"),
|
||||||
|
pdf("pdfFilePreviewImpl"),
|
||||||
|
other("otherFilePreviewImpl");
|
||||||
|
|
||||||
|
private String instanceName;
|
||||||
|
FileType(String instanceName){
|
||||||
|
this.instanceName=instanceName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getInstanceName() {
|
||||||
|
return instanceName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInstanceName(String instanceName) {
|
||||||
|
this.instanceName = instanceName;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.yudianbank.param;
|
package cn.keking.param;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package cn.keking.service;
|
||||||
|
|
||||||
|
import org.springframework.ui.Model;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by kl on 2018/1/17.
|
||||||
|
* Content :
|
||||||
|
*/
|
||||||
|
public interface FilePreview {
|
||||||
|
String filePreviewHandle(String url, Model model);
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package cn.keking.service;
|
||||||
|
|
||||||
|
import cn.keking.model.FileAttribute;
|
||||||
|
import cn.keking.utils.FileUtils;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.ui.Model;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by kl on 2018/1/17.
|
||||||
|
* Content :
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class FilePreviewFactory {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
FileUtils fileUtils;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
ApplicationContext context;
|
||||||
|
|
||||||
|
public FilePreview get(String url) {
|
||||||
|
Map<String, FilePreview> filePreviewMap = context.getBeansOfType(FilePreview.class);
|
||||||
|
FileAttribute fileAttribute = fileUtils.getFileAttribute(url);
|
||||||
|
return filePreviewMap.get(fileAttribute.getType().getInstanceName());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
package cn.keking.service.impl;
|
||||||
|
|
||||||
|
import cn.keking.model.FileAttribute;
|
||||||
|
import cn.keking.param.ReturnResponse;
|
||||||
|
import cn.keking.service.FilePreview;
|
||||||
|
import cn.keking.utils.DownloadUtils;
|
||||||
|
import cn.keking.utils.FileUtils;
|
||||||
|
import cn.keking.utils.ZipReader;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.ui.Model;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by kl on 2018/1/17.
|
||||||
|
* Content :处理压缩包文件
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class CompressFilePreviewImpl implements FilePreview{
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
FileUtils fileUtils;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
DownloadUtils downloadUtils;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
ZipReader zipReader;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String filePreviewHandle(String url, Model model) {
|
||||||
|
FileAttribute fileAttribute=fileUtils.getFileAttribute(url);
|
||||||
|
String fileName=fileAttribute.getName();
|
||||||
|
String decodedUrl=fileAttribute.getDecodedUrl();
|
||||||
|
String suffix=fileAttribute.getSuffix();
|
||||||
|
String fileTree = null;
|
||||||
|
// 判断文件名是否存在(redis缓存读取)
|
||||||
|
if (!StringUtils.hasText(fileUtils.getConvertedFile(fileName))) {
|
||||||
|
ReturnResponse<String> response = downloadUtils.downLoad(decodedUrl, suffix, fileName);
|
||||||
|
if (0 != response.getCode()) {
|
||||||
|
model.addAttribute("msg", response.getMsg());
|
||||||
|
return "fileNotSupported";
|
||||||
|
}
|
||||||
|
String filePath = response.getContent();
|
||||||
|
if ("zip".equalsIgnoreCase(suffix) || "jar".equalsIgnoreCase(suffix) || "gzip".equalsIgnoreCase(suffix)) {
|
||||||
|
fileTree = zipReader.readZipFile(filePath, fileName);
|
||||||
|
} else if ("rar".equalsIgnoreCase(suffix)) {
|
||||||
|
fileTree = zipReader.unRar(filePath, fileName);
|
||||||
|
}
|
||||||
|
fileUtils.addConvertedFile(fileName, fileTree);
|
||||||
|
} else {
|
||||||
|
fileTree = fileUtils.getConvertedFile(fileName);
|
||||||
|
}
|
||||||
|
if (null != fileTree) {
|
||||||
|
model.addAttribute("fileTree", fileTree);
|
||||||
|
return "compress";
|
||||||
|
} else {
|
||||||
|
model.addAttribute("msg", "压缩文件类型不受支持,尝试在压缩的时候选择RAR4格式");
|
||||||
|
return "fileNotSupported";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
package cn.keking.service.impl;
|
||||||
|
|
||||||
|
import cn.keking.model.FileAttribute;
|
||||||
|
import cn.keking.param.ReturnResponse;
|
||||||
|
import cn.keking.service.FilePreview;
|
||||||
|
import cn.keking.utils.DownloadUtils;
|
||||||
|
import cn.keking.utils.FileUtils;
|
||||||
|
import cn.keking.utils.OfficeToPdf;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.ui.Model;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by kl on 2018/1/17.
|
||||||
|
* Content :处理office文件
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class OfficeFilePreviewImpl implements FilePreview {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
FileUtils fileUtils;
|
||||||
|
|
||||||
|
@Value("${file.dir}")
|
||||||
|
String fileDir;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
DownloadUtils downloadUtils;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private OfficeToPdf officeToPdf;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String filePreviewHandle(String url, Model model) {
|
||||||
|
FileAttribute fileAttribute=fileUtils.getFileAttribute(url);
|
||||||
|
String suffix=fileAttribute.getSuffix();
|
||||||
|
String fileName=fileAttribute.getName();
|
||||||
|
String decodedUrl=fileAttribute.getDecodedUrl();
|
||||||
|
boolean isHtml = suffix.equalsIgnoreCase("xls") || suffix.equalsIgnoreCase("xlsx");
|
||||||
|
String pdfName = fileName.substring(0, fileName.lastIndexOf(".") + 1) + (isHtml ? "html" : "pdf");
|
||||||
|
// 判断之前是否已转换过,如果转换过,直接返回,否则执行转换
|
||||||
|
if (!fileUtils.listConvertedFiles().containsKey(pdfName)) {
|
||||||
|
String filePath = fileDir + fileName;
|
||||||
|
if (!new File(filePath).exists()) {
|
||||||
|
ReturnResponse<String> response = downloadUtils.downLoad(decodedUrl, suffix, null);
|
||||||
|
if (0 != response.getCode()) {
|
||||||
|
model.addAttribute("msg", response.getMsg());
|
||||||
|
return "fileNotSupported";
|
||||||
|
}
|
||||||
|
filePath = response.getContent();
|
||||||
|
}
|
||||||
|
String outFilePath = fileDir + pdfName;
|
||||||
|
if (StringUtils.hasText(outFilePath)) {
|
||||||
|
officeToPdf.openOfficeToPDF(filePath, outFilePath);
|
||||||
|
File f = new File(filePath);
|
||||||
|
if (f.exists()) {
|
||||||
|
f.delete();
|
||||||
|
}
|
||||||
|
if (isHtml) {
|
||||||
|
// 对转换后的文件进行操作(改变编码方式)
|
||||||
|
fileUtils.doActionConvertedFile(outFilePath);
|
||||||
|
}
|
||||||
|
// 加入缓存
|
||||||
|
fileUtils.addConvertedFile(pdfName, fileUtils.getRelativePath(outFilePath));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
model.addAttribute("pdfUrl", pdfName);
|
||||||
|
return isHtml ? "html" : "pdf";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package cn.keking.service.impl;
|
||||||
|
|
||||||
|
import cn.keking.service.FilePreview;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.ui.Model;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by kl on 2018/1/17.
|
||||||
|
* Content :其他文件
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class OtherFilePreviewImpl implements FilePreview {
|
||||||
|
@Override
|
||||||
|
public String filePreviewHandle(String url, Model model) {
|
||||||
|
model.addAttribute("msg", "系统还不支持该格式文件的在线预览," +
|
||||||
|
"如有需要请按下方显示的邮箱地址联系系统维护人员");
|
||||||
|
return "fileNotSupported";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package cn.keking.service.impl;
|
||||||
|
|
||||||
|
import cn.keking.service.FilePreview;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.ui.Model;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by kl on 2018/1/17.
|
||||||
|
* Content :处理pdf文件
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class PdfFilePreviewImpl implements FilePreview{
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String filePreviewHandle(String url, Model model) {
|
||||||
|
model.addAttribute("pdfUrl", url);
|
||||||
|
return "pdf";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
package cn.keking.service.impl;
|
||||||
|
|
||||||
|
import cn.keking.service.FilePreview;
|
||||||
|
import cn.keking.utils.FileUtils;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.ui.Model;
|
||||||
|
import org.springframework.web.context.request.RequestContextHolder;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by kl on 2018/1/17.
|
||||||
|
* Content :图片文件处理
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class PictureFilePreviewImpl implements FilePreview {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
FileUtils fileUtils;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String filePreviewHandle(String url, Model model) {
|
||||||
|
String fileKey=(String) RequestContextHolder.currentRequestAttributes().getAttribute("fileKey",0);
|
||||||
|
List imgUrls = Lists.newArrayList(url);
|
||||||
|
try{
|
||||||
|
imgUrls.clear();
|
||||||
|
imgUrls.addAll(fileUtils.getRedisImgUrls(fileKey));
|
||||||
|
}catch (Exception e){
|
||||||
|
imgUrls = Lists.newArrayList(url);
|
||||||
|
}
|
||||||
|
model.addAttribute("imgurls", imgUrls);
|
||||||
|
model.addAttribute("currentUrl",url);
|
||||||
|
return "picture";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
package cn.keking.service.impl;
|
||||||
|
|
||||||
|
import cn.keking.model.FileAttribute;
|
||||||
|
import cn.keking.model.FileType;
|
||||||
|
import cn.keking.param.ReturnResponse;
|
||||||
|
import cn.keking.service.FilePreview;
|
||||||
|
import cn.keking.utils.FileUtils;
|
||||||
|
import cn.keking.utils.SimTextUtil;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.ui.Model;
|
||||||
|
|
||||||
|
import java.net.URLDecoder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by kl on 2018/1/17.
|
||||||
|
* Content :处理文本文件
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class SimTextFilePreviewImpl implements FilePreview{
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
SimTextUtil simTextUtil;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
FileUtils fileUtils;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String filePreviewHandle(String url, Model model){
|
||||||
|
FileAttribute fileAttribute=fileUtils.getFileAttribute(url);
|
||||||
|
String decodedUrl=fileAttribute.getDecodedUrl();
|
||||||
|
String fileName=fileAttribute.getName();
|
||||||
|
ReturnResponse<String> response = simTextUtil.readSimText(decodedUrl, fileName);
|
||||||
|
if (0 != response.getCode()) {
|
||||||
|
model.addAttribute("msg", response.getMsg());
|
||||||
|
return "fileNotSupported";
|
||||||
|
}
|
||||||
|
model.addAttribute("ordinaryUrl", response.getMsg());
|
||||||
|
return "txt";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
package com.yudianbank.utils;
|
package cn.keking.utils;
|
||||||
|
|
||||||
import com.sun.star.document.UpdateDocMode;
|
import com.sun.star.document.UpdateDocMode;
|
||||||
import com.yudianbank.extend.ControlDocumentFormatRegistry;
|
import cn.keking.extend.ControlDocumentFormatRegistry;
|
||||||
import org.artofsolving.jodconverter.OfficeDocumentConverter;
|
import org.artofsolving.jodconverter.OfficeDocumentConverter;
|
||||||
import org.artofsolving.jodconverter.office.DefaultOfficeManagerConfiguration;
|
import org.artofsolving.jodconverter.office.DefaultOfficeManagerConfiguration;
|
||||||
import org.artofsolving.jodconverter.office.OfficeManager;
|
import org.artofsolving.jodconverter.office.OfficeManager;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.yudianbank.utils;
|
package cn.keking.utils;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
package com.yudianbank.utils;
|
package cn.keking.utils;
|
||||||
|
|
||||||
import com.yudianbank.param.ReturnResponse;
|
import cn.keking.param.ReturnResponse;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
@@ -1,157 +1,157 @@
|
|||||||
package com.yudianbank.utils;
|
package cn.keking.utils;
|
||||||
|
|
||||||
import java.io.BufferedInputStream;
|
import java.io.BufferedInputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import org.mozilla.intl.chardet.nsDetector;
|
import org.mozilla.intl.chardet.nsDetector;
|
||||||
import org.mozilla.intl.chardet.nsICharsetDetectionObserver;
|
import org.mozilla.intl.chardet.nsICharsetDetectionObserver;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 文本文件编码探测工具类
|
* 文本文件编码探测工具类
|
||||||
*
|
*
|
||||||
* @author HWliao
|
* @author HWliao
|
||||||
* @date 2017-12-24
|
* @date 2017-12-24
|
||||||
*/
|
*/
|
||||||
public class FileCharsetDetector {
|
public class FileCharsetDetector {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 传入一个文件(File)对象,检查文件编码
|
* 传入一个文件(File)对象,检查文件编码
|
||||||
*
|
*
|
||||||
* @param file File对象实例
|
* @param file File对象实例
|
||||||
* @return 文件编码,若无,则返回null
|
* @return 文件编码,若无,则返回null
|
||||||
* @throws FileNotFoundException
|
* @throws FileNotFoundException
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
public static Observer guessFileEncoding(File file)
|
public static Observer guessFileEncoding(File file)
|
||||||
throws FileNotFoundException, IOException {
|
throws FileNotFoundException, IOException {
|
||||||
return guessFileEncoding(file, new nsDetector());
|
return guessFileEncoding(file, new nsDetector());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <pre>
|
* <pre>
|
||||||
* 获取文件的编码
|
* 获取文件的编码
|
||||||
* @param file
|
* @param file
|
||||||
* File对象实例
|
* File对象实例
|
||||||
* @param languageHint
|
* @param languageHint
|
||||||
* 语言提示区域代码 @see #nsPSMDetector ,取值如下:
|
* 语言提示区域代码 @see #nsPSMDetector ,取值如下:
|
||||||
* 1 : Japanese
|
* 1 : Japanese
|
||||||
* 2 : Chinese
|
* 2 : Chinese
|
||||||
* 3 : Simplified Chinese
|
* 3 : Simplified Chinese
|
||||||
* 4 : Traditional Chinese
|
* 4 : Traditional Chinese
|
||||||
* 5 : Korean
|
* 5 : Korean
|
||||||
* 6 : Dont know(default)
|
* 6 : Dont know(default)
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @return 文件编码,eg:UTF-8,GBK,GB2312形式(不确定的时候,返回可能的字符编码序列);若无,则返回null
|
* @return 文件编码,eg:UTF-8,GBK,GB2312形式(不确定的时候,返回可能的字符编码序列);若无,则返回null
|
||||||
* @throws FileNotFoundException
|
* @throws FileNotFoundException
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
public static Observer guessFileEncoding(File file, int languageHint)
|
public static Observer guessFileEncoding(File file, int languageHint)
|
||||||
throws FileNotFoundException, IOException {
|
throws FileNotFoundException, IOException {
|
||||||
return guessFileEncoding(file, new nsDetector(languageHint));
|
return guessFileEncoding(file, new nsDetector(languageHint));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取文件的编码
|
* 获取文件的编码
|
||||||
*
|
*
|
||||||
* @param file
|
* @param file
|
||||||
* @param det
|
* @param det
|
||||||
* @return
|
* @return
|
||||||
* @throws FileNotFoundException
|
* @throws FileNotFoundException
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
private static Observer guessFileEncoding(File file, nsDetector det)
|
private static Observer guessFileEncoding(File file, nsDetector det)
|
||||||
throws FileNotFoundException, IOException {
|
throws FileNotFoundException, IOException {
|
||||||
// new Observer
|
// new Observer
|
||||||
Observer observer = new Observer();
|
Observer observer = new Observer();
|
||||||
// set Observer
|
// set Observer
|
||||||
// The Notify() will be called when a matching charset is found.
|
// The Notify() will be called when a matching charset is found.
|
||||||
det.Init(observer);
|
det.Init(observer);
|
||||||
|
|
||||||
BufferedInputStream imp = new BufferedInputStream(new FileInputStream(
|
BufferedInputStream imp = new BufferedInputStream(new FileInputStream(
|
||||||
file));
|
file));
|
||||||
byte[] buf = new byte[1024];
|
byte[] buf = new byte[1024];
|
||||||
int len;
|
int len;
|
||||||
boolean done = false;
|
boolean done = false;
|
||||||
boolean isAscii = false;
|
boolean isAscii = false;
|
||||||
|
|
||||||
while ((len = imp.read(buf, 0, buf.length)) != -1) {
|
while ((len = imp.read(buf, 0, buf.length)) != -1) {
|
||||||
// Check if the stream is only ascii.
|
// Check if the stream is only ascii.
|
||||||
isAscii = det.isAscii(buf, len);
|
isAscii = det.isAscii(buf, len);
|
||||||
if (isAscii) {
|
if (isAscii) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// DoIt if non-ascii and not done yet.
|
// DoIt if non-ascii and not done yet.
|
||||||
done = det.DoIt(buf, len, false);
|
done = det.DoIt(buf, len, false);
|
||||||
if (done) {
|
if (done) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
imp.close();
|
imp.close();
|
||||||
det.DataEnd();
|
det.DataEnd();
|
||||||
|
|
||||||
if (isAscii) {
|
if (isAscii) {
|
||||||
observer.encoding = "ASCII";
|
observer.encoding = "ASCII";
|
||||||
observer.found = true;
|
observer.found = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!observer.isFound()) {
|
if (!observer.isFound()) {
|
||||||
String[] prob = det.getProbableCharsets();
|
String[] prob = det.getProbableCharsets();
|
||||||
// // 这里将可能的字符集组合起来返回
|
// // 这里将可能的字符集组合起来返回
|
||||||
// for (int i = 0; i < prob.length; i++) {
|
// for (int i = 0; i < prob.length; i++) {
|
||||||
// if (i == 0) {
|
// if (i == 0) {
|
||||||
// encoding = prob[i];
|
// encoding = prob[i];
|
||||||
// } else {
|
// } else {
|
||||||
// encoding += "," + prob[i];
|
// encoding += "," + prob[i];
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
if (prob.length > 0) {
|
if (prob.length > 0) {
|
||||||
// 在没有发现情况下,去第一个可能的编码
|
// 在没有发现情况下,去第一个可能的编码
|
||||||
observer.encoding = prob[0];
|
observer.encoding = prob[0];
|
||||||
} else {
|
} else {
|
||||||
observer.encoding = null;
|
observer.encoding = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return observer;
|
return observer;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author liaohongwei
|
* @author liaohongwei
|
||||||
* @Description: 文件字符编码观察者, 但判断出字符编码时候调用
|
* @Description: 文件字符编码观察者, 但判断出字符编码时候调用
|
||||||
* @date 2016年6月20日 下午2:27:06
|
* @date 2016年6月20日 下午2:27:06
|
||||||
*/
|
*/
|
||||||
public static class Observer implements nsICharsetDetectionObserver {
|
public static class Observer implements nsICharsetDetectionObserver {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Fields encoding : 字符编码
|
* @Fields encoding : 字符编码
|
||||||
*/
|
*/
|
||||||
private String encoding = null;
|
private String encoding = null;
|
||||||
/**
|
/**
|
||||||
* @Fields found : 是否找到字符集
|
* @Fields found : 是否找到字符集
|
||||||
*/
|
*/
|
||||||
private boolean found = false;
|
private boolean found = false;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void Notify(String charset) {
|
public void Notify(String charset) {
|
||||||
this.encoding = charset;
|
this.encoding = charset;
|
||||||
this.found = true;
|
this.found = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getEncoding() {
|
public String getEncoding() {
|
||||||
return encoding;
|
return encoding;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isFound() {
|
public boolean isFound() {
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "Observer [encoding=" + encoding + ", found=" + found + "]";
|
return "Observer [encoding=" + encoding + ", found=" + found + "]";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,14 +1,20 @@
|
|||||||
package com.yudianbank.utils;
|
package cn.keking.utils;
|
||||||
|
|
||||||
|
import cn.keking.model.FileAttribute;
|
||||||
|
import cn.keking.model.FileType;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import org.redisson.api.RMapCache;
|
import org.redisson.api.RMapCache;
|
||||||
import org.redisson.api.RedissonClient;
|
import org.redisson.api.RedissonClient;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
|
import java.net.URLDecoder;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@@ -19,9 +25,11 @@ import java.util.Map;
|
|||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
public class FileUtils {
|
public class FileUtils {
|
||||||
|
Logger log= LoggerFactory.getLogger(getClass());
|
||||||
|
|
||||||
|
|
||||||
final String REDIS_FILE_PREVIEW_PDF_KEY = "converted-preview-pdf-file";
|
final String REDIS_FILE_PREVIEW_PDF_KEY = "converted-preview-pdf-file";
|
||||||
|
final String REDIS_FILE_PREVIEW_IMGS_KEY = "converted-preview-imgs-file";//压缩包内图片文件集合
|
||||||
@Autowired
|
@Autowired
|
||||||
RedissonClient redissonClient;
|
RedissonClient redissonClient;
|
||||||
@Value("${file.dir}")
|
@Value("${file.dir}")
|
||||||
@@ -30,6 +38,8 @@ public class FileUtils {
|
|||||||
@Value("${converted.file.charset}")
|
@Value("${converted.file.charset}")
|
||||||
String charset;
|
String charset;
|
||||||
|
|
||||||
|
@Value("${simText}")
|
||||||
|
String[] simText;
|
||||||
/**
|
/**
|
||||||
* 已转换过的文件集合(redis缓存)
|
* 已转换过的文件集合(redis缓存)
|
||||||
* @return
|
* @return
|
||||||
@@ -48,6 +58,33 @@ public class FileUtils {
|
|||||||
return convertedList.get(key);
|
return convertedList.get(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查看文件类型(防止参数中存在.点号或者其他特殊字符,所以先抽取文件名,然后再获取文件类型)
|
||||||
|
*
|
||||||
|
* @param url
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public FileType typeFromUrl(String url) {
|
||||||
|
String nonPramStr = url.substring(0, url.indexOf("?") != -1 ? url.indexOf("?") : url.length());
|
||||||
|
String fileName = nonPramStr.substring(nonPramStr.lastIndexOf("/") + 1);
|
||||||
|
String fileType = fileName.substring(fileName.lastIndexOf(".") + 1);
|
||||||
|
if (listPictureTypes().contains(fileType.toLowerCase())) {
|
||||||
|
return FileType.picture;
|
||||||
|
}
|
||||||
|
if (listArchiveTypes().contains(fileType.toLowerCase())) {
|
||||||
|
return FileType.compress;
|
||||||
|
}
|
||||||
|
if (listOfficeTypes().contains(fileType.toLowerCase())) {
|
||||||
|
return FileType.office;
|
||||||
|
}
|
||||||
|
if (Arrays.asList(simText).contains(fileType.toLowerCase())) {
|
||||||
|
return FileType.simText;
|
||||||
|
}
|
||||||
|
if("pdf".equalsIgnoreCase(fileType)){
|
||||||
|
return FileType.pdf;
|
||||||
|
}
|
||||||
|
return FileType.other;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* 从url中剥离出文件名
|
* 从url中剥离出文件名
|
||||||
* @param url
|
* @param url
|
||||||
@@ -89,6 +126,8 @@ public class FileUtils {
|
|||||||
list.add("png");
|
list.add("png");
|
||||||
list.add("gif");
|
list.add("gif");
|
||||||
list.add("bmp");
|
list.add("bmp");
|
||||||
|
list.add("ico");
|
||||||
|
list.add("RAW");
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,6 +168,25 @@ public class FileUtils {
|
|||||||
convertedList.fastPut(fileName, value);
|
convertedList.fastPut(fileName, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取redis中压缩包内图片文件
|
||||||
|
* @param fileKey
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public List getRedisImgUrls(String fileKey){
|
||||||
|
RMapCache<String, List> convertedList = redissonClient.getMapCache(REDIS_FILE_PREVIEW_IMGS_KEY);
|
||||||
|
return convertedList.get(fileKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置redis中压缩包内图片文件
|
||||||
|
* @param fileKey
|
||||||
|
* @param imgs
|
||||||
|
*/
|
||||||
|
public void setRedisImgUrls(String fileKey,List imgs){
|
||||||
|
RMapCache<String, List> convertedList = redissonClient.getMapCache(REDIS_FILE_PREVIEW_IMGS_KEY);
|
||||||
|
convertedList.fastPut(fileKey,imgs);
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* 判断文件编码格式
|
* 判断文件编码格式
|
||||||
* @param path
|
* @param path
|
||||||
@@ -189,4 +247,30 @@ public class FileUtils {
|
|||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* 获取文件后缀
|
||||||
|
* @param url
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private String suffixFromUrl(String url) {
|
||||||
|
String nonPramStr = url.substring(0, url.indexOf("?") != -1 ? url.indexOf("?") : url.length());
|
||||||
|
String fileName = nonPramStr.substring(nonPramStr.lastIndexOf("/") + 1);
|
||||||
|
String fileType = fileName.substring(fileName.lastIndexOf(".") + 1);
|
||||||
|
return fileType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FileAttribute getFileAttribute(String url) {
|
||||||
|
String decodedUrl=null;
|
||||||
|
try {
|
||||||
|
decodedUrl = URLDecoder.decode(url, "utf-8");
|
||||||
|
}catch (UnsupportedEncodingException e){
|
||||||
|
log.debug("url解码失败");
|
||||||
|
}
|
||||||
|
// 路径转码
|
||||||
|
FileType type = typeFromUrl(url);
|
||||||
|
String suffix = suffixFromUrl(url);
|
||||||
|
// 抽取文件并返回文件列表
|
||||||
|
String fileName = getFileNameFromURL(decodedUrl);
|
||||||
|
return new FileAttribute(type,suffix,fileName,url,decodedUrl);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.yudianbank.utils;
|
package cn.keking.utils;
|
||||||
import org.artofsolving.jodconverter.OfficeDocumentConverter;
|
import org.artofsolving.jodconverter.OfficeDocumentConverter;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.yudianbank.utils;
|
package cn.keking.utils;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
package com.yudianbank.utils;
|
package cn.keking.utils;
|
||||||
|
|
||||||
import com.yudianbank.param.ReturnResponse;
|
import cn.keking.param.ReturnResponse;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.yudianbank.utils;
|
package cn.keking.utils;
|
||||||
|
|
||||||
|
import cn.keking.model.FileType;
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.github.junrar.Archive;
|
import com.github.junrar.Archive;
|
||||||
@@ -12,11 +13,17 @@ import org.apache.commons.compress.archivers.zip.ZipFile;
|
|||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.web.context.request.RequestContextHolder;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.text.CollationKey;
|
||||||
|
import java.text.Collator;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@@ -25,6 +32,7 @@ import java.util.concurrent.Executors;
|
|||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
public class ZipReader {
|
public class ZipReader {
|
||||||
|
static Pattern pattern = Pattern.compile("^\\d+");
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
FileUtils fileUtils;
|
FileUtils fileUtils;
|
||||||
@@ -49,9 +57,11 @@ public class ZipReader {
|
|||||||
* </p>
|
* </p>
|
||||||
* @param filePath
|
* @param filePath
|
||||||
*/
|
*/
|
||||||
public String readZipFile(String filePath) {
|
public String readZipFile(String filePath,String fileKey) {
|
||||||
String archiveSeparator = "/";
|
String archiveSeparator = "/";
|
||||||
Map<String, FileNode> appender = Maps.newHashMap();
|
Map<String, FileNode> appender = Maps.newHashMap();
|
||||||
|
List imgUrls=Lists.newArrayList();
|
||||||
|
String baseUrl= (String) RequestContextHolder.currentRequestAttributes().getAttribute("baseUrl",0);
|
||||||
String archiveFileName = fileUtils.getFileNameFromPath(filePath);
|
String archiveFileName = fileUtils.getFileNameFromPath(filePath);
|
||||||
try {
|
try {
|
||||||
ZipFile zipFile = new ZipFile(filePath, fileUtils.getFileEncodeUTFGBK(filePath));
|
ZipFile zipFile = new ZipFile(filePath, fileUtils.getFileEncodeUTFGBK(filePath));
|
||||||
@@ -73,12 +83,17 @@ public class ZipReader {
|
|||||||
}
|
}
|
||||||
String parentName = getLast2FileName(fullName, archiveSeparator, archiveFileName);
|
String parentName = getLast2FileName(fullName, archiveSeparator, archiveFileName);
|
||||||
parentName = (level-1) + "_" + parentName;
|
parentName = (level-1) + "_" + parentName;
|
||||||
FileNode node = new FileNode(originName, childName, parentName, new ArrayList<>(), directory);
|
FileType type=fileUtils.typeFromUrl(childName);
|
||||||
|
if (type.equals(FileType.picture)){//添加图片文件到图片列表
|
||||||
|
imgUrls.add(baseUrl+childName);
|
||||||
|
}
|
||||||
|
FileNode node = new FileNode(originName, childName, parentName, new ArrayList<>(), directory,fileKey);
|
||||||
addNodes(appender, parentName, node);
|
addNodes(appender, parentName, node);
|
||||||
appender.put(childName, node);
|
appender.put(childName, node);
|
||||||
}
|
}
|
||||||
// 开启新的线程处理文件解压
|
// 开启新的线程处理文件解压
|
||||||
executors.submit(new ZipExtractorWorker(entriesToBeExtracted, zipFile, filePath));
|
executors.submit(new ZipExtractorWorker(entriesToBeExtracted, zipFile, filePath));
|
||||||
|
fileUtils.setRedisImgUrls(fileKey,imgUrls);
|
||||||
return new ObjectMapper().writeValueAsString(appender.get(""));
|
return new ObjectMapper().writeValueAsString(appender.get(""));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
@@ -86,6 +101,8 @@ public class ZipReader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 排序zipEntries(对原来列表倒序)
|
* 排序zipEntries(对原来列表倒序)
|
||||||
* @param entries
|
* @param entries
|
||||||
@@ -99,8 +116,10 @@ public class ZipReader {
|
|||||||
return Collections.enumeration(sortedEntries);
|
return Collections.enumeration(sortedEntries);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String unRar(String filePath){
|
public String unRar(String filePath,String fileKey){
|
||||||
Map<String, FileNode> appender = Maps.newHashMap();
|
Map<String, FileNode> appender = Maps.newHashMap();
|
||||||
|
List imgUrls=Lists.newArrayList();
|
||||||
|
String baseUrl= (String) RequestContextHolder.currentRequestAttributes().getAttribute("baseUrl",0);
|
||||||
try {
|
try {
|
||||||
Archive archive = new Archive(new File(filePath));
|
Archive archive = new Archive(new File(filePath));
|
||||||
List<FileHeader> headers = archive.getFileHeaders();
|
List<FileHeader> headers = archive.getFileHeaders();
|
||||||
@@ -123,11 +142,16 @@ public class ZipReader {
|
|||||||
headersToBeExtracted.add(Collections.singletonMap(childName, header));
|
headersToBeExtracted.add(Collections.singletonMap(childName, header));
|
||||||
}
|
}
|
||||||
String parentName = getLast2FileName(fullName, "\\", archiveFileName);
|
String parentName = getLast2FileName(fullName, "\\", archiveFileName);
|
||||||
FileNode node = new FileNode(originName, childName, parentName, new ArrayList<>(), directory);
|
FileType type=fileUtils.typeFromUrl(childName);
|
||||||
|
if (type.equals(FileType.picture)){//添加图片文件到图片列表
|
||||||
|
imgUrls.add(baseUrl+childName);
|
||||||
|
}
|
||||||
|
FileNode node = new FileNode(originName, childName, parentName, new ArrayList<>(), directory,fileKey);
|
||||||
addNodes(appender, parentName, node);
|
addNodes(appender, parentName, node);
|
||||||
appender.put(childName, node);
|
appender.put(childName, node);
|
||||||
}
|
}
|
||||||
executors.submit(new RarExtractorWorker(headersToBeExtracted, archive, filePath));
|
executors.submit(new RarExtractorWorker(headersToBeExtracted, archive, filePath));
|
||||||
|
fileUtils.setRedisImgUrls(fileKey,imgUrls);
|
||||||
return new ObjectMapper().writeValueAsString(appender.get(""));
|
return new ObjectMapper().writeValueAsString(appender.get(""));
|
||||||
} catch (RarException e) {
|
} catch (RarException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
@@ -140,6 +164,8 @@ public class ZipReader {
|
|||||||
private void addNodes(Map<String, FileNode> appender, String parentName, FileNode node) {
|
private void addNodes(Map<String, FileNode> appender, String parentName, FileNode node) {
|
||||||
if (appender.containsKey(parentName)) {
|
if (appender.containsKey(parentName)) {
|
||||||
appender.get(parentName).getChildList().add(node);
|
appender.get(parentName).getChildList().add(node);
|
||||||
|
Collections.sort(appender.get(parentName).getChildList(), sortComparator);
|
||||||
|
// appender.get(parentName).getChildList().sort((final FileNode h1, final FileNode h2) -> h1.getOriginName().compareTo(h2.getOriginName()));//排序
|
||||||
}else { // 根节点
|
}else { // 根节点
|
||||||
FileNode nodeRoot = new FileNode(parentName, parentName, "", new ArrayList<>(), true);
|
FileNode nodeRoot = new FileNode(parentName, parentName, "", new ArrayList<>(), true);
|
||||||
nodeRoot.getChildList().add(node);
|
nodeRoot.getChildList().add(node);
|
||||||
@@ -204,6 +230,30 @@ public class ZipReader {
|
|||||||
return newName;
|
return newName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Comparator<FileNode> sortComparator = new Comparator<FileNode>() {
|
||||||
|
Collator cmp = Collator.getInstance(Locale.US);
|
||||||
|
@Override
|
||||||
|
public int compare(FileNode o1, FileNode o2) {
|
||||||
|
// 判断两个对比对象是否是开头包含数字,如果包含数字则获取数字并按数字真正大小进行排序
|
||||||
|
BigDecimal num1,num2;
|
||||||
|
if (null != (num1 = isStartNumber(o1))
|
||||||
|
&& null != (num2 = isStartNumber(o2))) {
|
||||||
|
return num1.subtract(num2).intValue();
|
||||||
|
}
|
||||||
|
CollationKey c1 = cmp.getCollationKey(o1.getOriginName());
|
||||||
|
CollationKey c2 = cmp.getCollationKey(o2.getOriginName());
|
||||||
|
return cmp.compare(c1.getSourceString(), c2.getSourceString());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private static BigDecimal isStartNumber(FileNode src) {
|
||||||
|
Matcher matcher = pattern.matcher(src.getOriginName());
|
||||||
|
if (matcher.find()) {
|
||||||
|
return new BigDecimal(matcher.group());
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 文件节点(区分文件上下级)
|
* 文件节点(区分文件上下级)
|
||||||
*/
|
*/
|
||||||
@@ -213,9 +263,12 @@ public class ZipReader {
|
|||||||
private String fileName;
|
private String fileName;
|
||||||
private String parentFileName;
|
private String parentFileName;
|
||||||
private boolean directory;
|
private boolean directory;
|
||||||
|
private String fileKey;//用于图片预览时寻址
|
||||||
private List<FileNode> childList;
|
private List<FileNode> childList;
|
||||||
|
|
||||||
|
public FileNode() {
|
||||||
|
}
|
||||||
|
|
||||||
public FileNode(String originName, String fileName, String parentFileName, List<FileNode> childList, boolean directory) {
|
public FileNode(String originName, String fileName, String parentFileName, List<FileNode> childList, boolean directory) {
|
||||||
this.originName = originName;
|
this.originName = originName;
|
||||||
this.fileName = fileName;
|
this.fileName = fileName;
|
||||||
@@ -223,6 +276,21 @@ public class ZipReader {
|
|||||||
this.childList = childList;
|
this.childList = childList;
|
||||||
this.directory = directory;
|
this.directory = directory;
|
||||||
}
|
}
|
||||||
|
public FileNode(String originName, String fileName, String parentFileName, List<FileNode> childList, boolean directory,String fileKey) {
|
||||||
|
this.originName = originName;
|
||||||
|
this.fileName = fileName;
|
||||||
|
this.parentFileName = parentFileName;
|
||||||
|
this.childList = childList;
|
||||||
|
this.directory = directory;
|
||||||
|
this.fileKey=fileKey;
|
||||||
|
}
|
||||||
|
public String getFileKey() {
|
||||||
|
return fileKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFileKey(String fileKey) {
|
||||||
|
this.fileKey = fileKey;
|
||||||
|
}
|
||||||
|
|
||||||
public String getFileName() {
|
public String getFileName() {
|
||||||
return fileName;
|
return fileName;
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
package com.yudianbank.web.controller;
|
package cn.keking.web.controller;
|
||||||
|
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.yudianbank.param.ReturnResponse;
|
import cn.keking.param.ReturnResponse;
|
||||||
import com.yudianbank.utils.FileUtils;
|
import cn.keking.utils.FileUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.yudianbank.web.controller;
|
package cn.keking.web.controller;
|
||||||
|
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
@@ -0,0 +1,98 @@
|
|||||||
|
package cn.keking.web.controller;
|
||||||
|
|
||||||
|
import cn.keking.service.FilePreview;
|
||||||
|
import cn.keking.service.FilePreviewFactory;
|
||||||
|
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.ui.Model;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMethod;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.net.HttpURLConnection;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLConnection;
|
||||||
|
import java.net.URLDecoder;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author yudian-it
|
||||||
|
*/
|
||||||
|
@Controller
|
||||||
|
public class OnlinePreviewController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
FilePreviewFactory previewFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param url
|
||||||
|
* @param model
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@RequestMapping(value = "onlinePreview", method = RequestMethod.GET)
|
||||||
|
public String onlinePreview(String url, Model model, HttpServletRequest req) {
|
||||||
|
req.setAttribute("fileKey",req.getParameter("fileKey"));
|
||||||
|
FilePreview filePreview=previewFactory.get(url);
|
||||||
|
return filePreview.filePreviewHandle(url,model);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 多图片切换预览
|
||||||
|
*
|
||||||
|
* @param model
|
||||||
|
* @param req
|
||||||
|
* @return
|
||||||
|
* @throws UnsupportedEncodingException
|
||||||
|
*/
|
||||||
|
@RequestMapping(value = "picturesPreview", method = RequestMethod.GET)
|
||||||
|
public String picturesPreview(String urls, Model model, HttpServletRequest req) throws UnsupportedEncodingException {
|
||||||
|
// 路径转码
|
||||||
|
String decodedUrl = URLDecoder.decode(urls, "utf-8");
|
||||||
|
// 抽取文件并返回文件列表
|
||||||
|
String[] imgs = decodedUrl.split("|");
|
||||||
|
List imgurls = Arrays.asList(imgs);
|
||||||
|
model.addAttribute("imgurls", imgurls);
|
||||||
|
return "picture";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据url获取文件内容
|
||||||
|
* 当pdfjs读取存在跨域问题的文件时将通过此接口读取
|
||||||
|
*
|
||||||
|
* @param urlPath
|
||||||
|
* @param resp
|
||||||
|
*/
|
||||||
|
@RequestMapping(value = "/getCorsFile", method = RequestMethod.GET)
|
||||||
|
public void getCorsFile(String urlPath, HttpServletResponse resp) {
|
||||||
|
InputStream inputStream = null;
|
||||||
|
try {
|
||||||
|
String strUrl = urlPath.trim();
|
||||||
|
URL url = new URL(strUrl);
|
||||||
|
//打开请求连接
|
||||||
|
URLConnection connection = url.openConnection();
|
||||||
|
HttpURLConnection httpURLConnection = (HttpURLConnection) connection;
|
||||||
|
httpURLConnection.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
|
||||||
|
inputStream = httpURLConnection.getInputStream();
|
||||||
|
byte[] bs = new byte[1024];
|
||||||
|
int len;
|
||||||
|
while (-1 != (len = inputStream.read(bs))) {
|
||||||
|
resp.getOutputStream().write(bs, 0, len);
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
if (inputStream != null) {
|
||||||
|
IOUtils.closeQuietly(inputStream);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,194 +0,0 @@
|
|||||||
package com.yudianbank.utils;
|
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.net.HttpURLConnection;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.xml.parsers.DocumentBuilderFactory;
|
|
||||||
import javax.xml.parsers.ParserConfigurationException;
|
|
||||||
import javax.xml.transform.OutputKeys;
|
|
||||||
import javax.xml.transform.Transformer;
|
|
||||||
import javax.xml.transform.TransformerException;
|
|
||||||
import javax.xml.transform.TransformerFactory;
|
|
||||||
import javax.xml.transform.dom.DOMSource;
|
|
||||||
import javax.xml.transform.stream.StreamResult;
|
|
||||||
|
|
||||||
import org.apache.poi.hssf.converter.ExcelToHtmlConverter;
|
|
||||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
|
||||||
import org.apache.poi.hwpf.converter.PicturesManager;
|
|
||||||
import org.apache.poi.hwpf.converter.WordToHtmlConverter;
|
|
||||||
import org.apache.poi.hwpf.usermodel.Picture;
|
|
||||||
import org.apache.poi.hwpf.usermodel.PictureType;
|
|
||||||
import org.apache.poi.ss.usermodel.Cell;
|
|
||||||
import org.apache.poi.ss.usermodel.Row;
|
|
||||||
import org.apache.poi.ss.usermodel.Sheet;
|
|
||||||
import org.apache.poi.ss.usermodel.Workbook;
|
|
||||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
|
||||||
import org.w3c.dom.Document;
|
|
||||||
|
|
||||||
|
|
||||||
public class PoiExcelToHtml {
|
|
||||||
// String path = getClass().getClassLoader().getResource(".").getPath()+File.separator+"static"+File.separator;
|
|
||||||
public static void excelConvert(URL url) {
|
|
||||||
try {
|
|
||||||
String path = "";
|
|
||||||
|
|
||||||
// http://keking.ufile.ucloud.com.cn/20171101152525_左晓晖2017年9.xls?UCloudPublicKey=ucloudtangshd@weifenf.com14355492830001993909323&Expires=&Signature=1n8ASiYMcfiF30YHxwpzwfqmlM0=
|
|
||||||
// URL url = new URL("http://keking.ufile.ucloud.com.cn/20171101150322_运费贷信审资料(给予客户收集版).xlsx?UCloudPublicKey=ucloudtangshd@weifenf.com14355492830001993909323&Expires=&Signature=RRVFIICITMNFed1LQgB10WdKHiE=");
|
|
||||||
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
|
|
||||||
//设置超时间为3秒
|
|
||||||
conn.setConnectTimeout(3*1000);
|
|
||||||
//防止屏蔽程序抓取而返回403错误
|
|
||||||
conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
|
|
||||||
//得到输入流
|
|
||||||
InputStream inputStream = conn.getInputStream();
|
|
||||||
HSSFWorkbook excelBook = new HSSFWorkbook(inputStream);
|
|
||||||
ExcelToHtmlConverter excelToHtmlConverter = new ExcelToHtmlConverter(DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument());
|
|
||||||
excelToHtmlConverter.processWorkbook(excelBook);
|
|
||||||
List pics = excelBook.getAllPictures();
|
|
||||||
if (pics != null) {
|
|
||||||
for (int i = 0; i < pics.size(); i++) {
|
|
||||||
Picture pic = (Picture) pics.get(i);
|
|
||||||
try {
|
|
||||||
pic.writeImageContent(new FileOutputStream(path + pic.suggestFullFileName()));
|
|
||||||
} catch (FileNotFoundException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Document htmlDocument = excelToHtmlConverter.getDocument();
|
|
||||||
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
|
|
||||||
DOMSource domSource = new DOMSource(htmlDocument);
|
|
||||||
StreamResult streamResult = new StreamResult(outStream);
|
|
||||||
TransformerFactory tf = TransformerFactory.newInstance();
|
|
||||||
Transformer serializer = tf.newTransformer();
|
|
||||||
serializer.setOutputProperty(OutputKeys.ENCODING, "utf-8");
|
|
||||||
serializer.setOutputProperty(OutputKeys.INDENT, "yes");
|
|
||||||
serializer.setOutputProperty(OutputKeys.METHOD, "html");
|
|
||||||
serializer.transform(domSource, streamResult);
|
|
||||||
outStream.close();
|
|
||||||
|
|
||||||
String content = new String(outStream.toByteArray());
|
|
||||||
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (ParserConfigurationException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (TransformerException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* excel07转html
|
|
||||||
* filename:要读取的文件所在文件夹
|
|
||||||
* filepath:文件名
|
|
||||||
* htmlname:生成html名称
|
|
||||||
* path:html存放路径
|
|
||||||
* */
|
|
||||||
public static void excelToHtml () throws Exception{
|
|
||||||
String htmlname="exportExcel"+"07Test"+".html";
|
|
||||||
|
|
||||||
|
|
||||||
URL url = new URL("http://keking.ufile.ucloud.com.cn/20171101150322_运费贷信审资料(给予客户收集版).xlsx?UCloudPublicKey=ucloudtangshd@weifenf.com14355492830001993909323&Expires=&Signature=RRVFIICITMNFed1LQgB10WdKHiE=");
|
|
||||||
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
|
|
||||||
//设置超时间为3秒
|
|
||||||
conn.setConnectTimeout(3*1000);
|
|
||||||
//防止屏蔽程序抓取而返回403错误
|
|
||||||
conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
|
|
||||||
//得到输入流
|
|
||||||
InputStream is = conn.getInputStream();
|
|
||||||
|
|
||||||
Workbook workbook = null;
|
|
||||||
// InputStream is = new FileInputStream(filename+"/"+filepath);
|
|
||||||
try {
|
|
||||||
String html="";
|
|
||||||
workbook = new XSSFWorkbook(is);
|
|
||||||
for (int numSheet = 0; numSheet < workbook.getNumberOfSheets(); numSheet++) {
|
|
||||||
Sheet sheet = workbook.getSheetAt(numSheet);
|
|
||||||
if (sheet == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
html+="=======================" + sheet.getSheetName() + "=========================<br><br>";
|
|
||||||
|
|
||||||
int firstRowIndex = sheet.getFirstRowNum();
|
|
||||||
int lastRowIndex = sheet.getLastRowNum();
|
|
||||||
html+="<table border='1' align='left'>";
|
|
||||||
Row firstRow = sheet.getRow(firstRowIndex);
|
|
||||||
for (int i = firstRow.getFirstCellNum(); i <= firstRow.getLastCellNum(); i++) {
|
|
||||||
Cell cell = firstRow.getCell(i);
|
|
||||||
String cellValue = getCellValue(cell, true);
|
|
||||||
html+="<th>" + cellValue + "</th>";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//行
|
|
||||||
for (int rowIndex = firstRowIndex + 1; rowIndex <= lastRowIndex; rowIndex++) {
|
|
||||||
Row currentRow = sheet.getRow(rowIndex);
|
|
||||||
html+="<tr>";
|
|
||||||
if(currentRow!=null){
|
|
||||||
|
|
||||||
int firstColumnIndex = currentRow.getFirstCellNum();
|
|
||||||
int lastColumnIndex = currentRow.getLastCellNum();
|
|
||||||
//列
|
|
||||||
for (int columnIndex = firstColumnIndex; columnIndex <= lastColumnIndex; columnIndex++) {
|
|
||||||
Cell currentCell = currentRow.getCell(columnIndex);
|
|
||||||
String currentCellValue = getCellValue(currentCell, true);
|
|
||||||
html+="<td>"+currentCellValue + "</td>";
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
html+=" ";
|
|
||||||
}
|
|
||||||
html+="</tr>";
|
|
||||||
}
|
|
||||||
html+="</table>";
|
|
||||||
|
|
||||||
|
|
||||||
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
|
|
||||||
DOMSource domSource = new DOMSource ();
|
|
||||||
StreamResult streamResult = new StreamResult (outStream);
|
|
||||||
|
|
||||||
TransformerFactory tf = TransformerFactory.newInstance();
|
|
||||||
Transformer serializer = tf.newTransformer();
|
|
||||||
serializer.setOutputProperty (OutputKeys.ENCODING, "utf-8");
|
|
||||||
serializer.setOutputProperty (OutputKeys.INDENT, "yes");
|
|
||||||
serializer.setOutputProperty (OutputKeys.METHOD, "html");
|
|
||||||
serializer.transform (domSource, streamResult);
|
|
||||||
outStream.close();
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 读取单元格
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
private static String getCellValue(Cell cell, boolean treatAsStr) {
|
|
||||||
if (cell == null) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (treatAsStr) {
|
|
||||||
cell.setCellType(Cell.CELL_TYPE_STRING);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cell.getCellType() == Cell.CELL_TYPE_BOOLEAN) {
|
|
||||||
return String.valueOf(cell.getBooleanCellValue());
|
|
||||||
} else if (cell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
|
|
||||||
return String.valueOf(cell.getNumericCellValue());
|
|
||||||
} else {
|
|
||||||
return String.valueOf(cell.getStringCellValue());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
package com.yudianbank.utils;
|
|
||||||
|
|
||||||
import java.io.*;
|
|
||||||
import java.net.URLDecoder;
|
|
||||||
import java.net.URLEncoder;
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.function.Function;
|
|
||||||
import java.util.function.ToDoubleFunction;
|
|
||||||
import java.util.function.ToIntFunction;
|
|
||||||
import java.util.function.ToLongFunction;
|
|
||||||
|
|
||||||
import com.github.junrar.Archive;
|
|
||||||
import com.github.junrar.exception.RarException;
|
|
||||||
import com.github.junrar.rarfile.FileHeader;
|
|
||||||
import org.apache.commons.compress.archivers.ArchiveException;
|
|
||||||
import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
|
|
||||||
import org.apache.commons.compress.archivers.zip.ZipFile;
|
|
||||||
import org.apache.poi.xwpf.converter.core.FileImageExtractor;
|
|
||||||
import org.apache.poi.xwpf.converter.core.FileURIResolver;
|
|
||||||
import org.apache.poi.xwpf.converter.xhtml.XHTMLConverter;
|
|
||||||
import org.apache.poi.xwpf.converter.xhtml.XHTMLOptions;
|
|
||||||
import org.apache.poi.xwpf.usermodel.XWPFDocument;
|
|
||||||
|
|
||||||
public class WordToHtml {
|
|
||||||
/** 这是2007版本 转html 已测试成功的代码 07和03版要用两种代码转 但因为后面说要用
|
|
||||||
* 38 * 2007版本word转换成html
|
|
||||||
* 39 * @throws IOException
|
|
||||||
* 40
|
|
||||||
*/
|
|
||||||
|
|
||||||
public static String Word2007ToHtml(InputStream inputStream) throws IOException {
|
|
||||||
// 1) 加载word文档生成 XWPFDocument对象
|
|
||||||
XWPFDocument document = new XWPFDocument(inputStream);
|
|
||||||
|
|
||||||
// 2) 解析 XHTML配置 (这里设置IURIResolver来设置图片存放的目录)
|
|
||||||
// File imageFolderFile = new File("/Users/zuoxiaohui/IdeaProjects/yudian-preview-boot/yudian-preview-boot/src/main/resources/picture/");
|
|
||||||
File imageFolderFile = new File("/Users/zuoxiaohui/IdeaProjects/yudian-preview-boot/yudian-preview-boot/src/main/resources/static/");
|
|
||||||
XHTMLOptions options = XHTMLOptions.create().URIResolver(new FileURIResolver(imageFolderFile));
|
|
||||||
options.setExtractor(new FileImageExtractor(imageFolderFile));
|
|
||||||
options.setIgnoreStylesIfUnused(false);
|
|
||||||
options.setFragment(true);
|
|
||||||
|
|
||||||
File file = new File("/Users/zuoxiaohui/Test/" + "test.html");
|
|
||||||
// 3) 将 XWPFDocument转换成XHTML
|
|
||||||
OutputStream out = new FileOutputStream(file);
|
|
||||||
XHTMLConverter.getInstance().convert(document, out, options);
|
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
|
||||||
XHTMLConverter.getInstance().convert(document, baos, options);
|
|
||||||
String content = baos.toString();
|
|
||||||
System.out.println(content);
|
|
||||||
baos.close();
|
|
||||||
return content;
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args) throws IOException, ArchiveException, RarException {
|
|
||||||
System.out.println(URLEncoder.encode(" ", "UTF-8"));
|
|
||||||
System.out.println(URLDecoder.decode(" http://keking.ufile.ucloud.com.cn/20171230213253_2017%E5%B9%B4%20%E5%BA%A6%E7%BB%A9%E6%95%88%E8%80%83%E6%A0%B8%E8%A1%A8%E5%8F%8A%E8%AF%84%E4%BC%98%E6%8E%A8%E8%8D%90%E8%A1%A8.xlsxUCloudPublicKey=ucloudtangshd@weifenf.com14355492830001993909323&Expires=&Signature=Pbi/J6UcOZcvGwhAwExe3SpxrGo=", "UTF-8"));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,205 +0,0 @@
|
|||||||
package com.yudianbank.web.controller;
|
|
||||||
|
|
||||||
import com.yudianbank.param.ReturnResponse;
|
|
||||||
import com.yudianbank.utils.*;
|
|
||||||
import org.apache.commons.io.IOUtils;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
|
||||||
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 javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.UnsupportedEncodingException;
|
|
||||||
import java.net.HttpURLConnection;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.net.URLConnection;
|
|
||||||
import java.net.URLDecoder;
|
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author yudian-it
|
|
||||||
*/
|
|
||||||
@Controller
|
|
||||||
public class OnlinePreviewController {
|
|
||||||
@Autowired
|
|
||||||
private OfficeToPdf officeToPdf;
|
|
||||||
@Autowired
|
|
||||||
FileUtils fileUtils;
|
|
||||||
@Autowired
|
|
||||||
DownloadUtils downloadUtils;
|
|
||||||
@Autowired
|
|
||||||
ZipReader zipReader;
|
|
||||||
@Autowired
|
|
||||||
SimTextUtil simTextUtil;
|
|
||||||
@Value("${simText}")
|
|
||||||
String[] simText;
|
|
||||||
|
|
||||||
@Value("${file.dir}")
|
|
||||||
String fileDir;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param url
|
|
||||||
* @param model
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@RequestMapping(value = "onlinePreview",method = RequestMethod.GET)
|
|
||||||
public String onlinePreview(String url, Model model, HttpServletRequest req) throws UnsupportedEncodingException {
|
|
||||||
// 路径转码
|
|
||||||
String decodedUrl = URLDecoder.decode(url, "utf-8");
|
|
||||||
String type = typeFromUrl(url);
|
|
||||||
String suffix = suffixFromUrl(url);
|
|
||||||
// 抽取文件并返回文件列表
|
|
||||||
String fileName = fileUtils.getFileNameFromURL(decodedUrl);
|
|
||||||
model.addAttribute("fileType", suffix);
|
|
||||||
if (type.equalsIgnoreCase("picture")) {
|
|
||||||
model.addAttribute("imgurl", url);
|
|
||||||
return "picture";
|
|
||||||
} else if (type.equalsIgnoreCase("simText")){
|
|
||||||
ReturnResponse<String> response = simTextUtil.readSimText(decodedUrl, fileName);
|
|
||||||
if (0 != response.getCode()) {
|
|
||||||
model.addAttribute("msg", response.getMsg());
|
|
||||||
return "fileNotSupported";
|
|
||||||
}
|
|
||||||
model.addAttribute("ordinaryUrl", response.getMsg());
|
|
||||||
return "txt";
|
|
||||||
} else if(type.equalsIgnoreCase("pdf")){
|
|
||||||
model.addAttribute("pdfUrl",url);
|
|
||||||
return "pdf";
|
|
||||||
} else if(type.equalsIgnoreCase("compress")){
|
|
||||||
String fileTree = null;
|
|
||||||
// 判断文件名是否存在(redis缓存读取)
|
|
||||||
if (!StringUtils.hasText(fileUtils.getConvertedFile(fileName))) {
|
|
||||||
ReturnResponse<String> response = downloadUtils.downLoad(decodedUrl, suffix, fileName);
|
|
||||||
if (0 != response.getCode()) {
|
|
||||||
model.addAttribute("msg", response.getMsg());
|
|
||||||
return "fileNotSupported";
|
|
||||||
}
|
|
||||||
String filePath = response.getContent();
|
|
||||||
if ("zip".equalsIgnoreCase(suffix)
|
|
||||||
|| "jar".equalsIgnoreCase(suffix)
|
|
||||||
|| "gzip".equalsIgnoreCase(suffix)) {
|
|
||||||
fileTree = zipReader.readZipFile(filePath);
|
|
||||||
} else if ("rar".equalsIgnoreCase(suffix)) {
|
|
||||||
fileTree = zipReader.unRar(filePath);
|
|
||||||
}
|
|
||||||
fileUtils.addConvertedFile(fileName, fileTree);
|
|
||||||
}else {
|
|
||||||
fileTree = fileUtils.getConvertedFile(fileName);
|
|
||||||
}
|
|
||||||
System.out.println("返回文件tree》》》》》》》》》》》》》》》》》》》");
|
|
||||||
if (null != fileTree) {
|
|
||||||
model.addAttribute("fileTree",fileTree);
|
|
||||||
return "compress";
|
|
||||||
}else {
|
|
||||||
model.addAttribute("msg", "压缩文件类型不受支持,尝试在压缩的时候选择RAR4格式");
|
|
||||||
return "fileNotSupported";
|
|
||||||
}
|
|
||||||
} else if ("office".equalsIgnoreCase(type)) {
|
|
||||||
boolean isHtml = suffix.equalsIgnoreCase("xls")
|
|
||||||
|| suffix.equalsIgnoreCase("xlsx");
|
|
||||||
String pdfName = fileName.substring(0, fileName.lastIndexOf(".") + 1) + (isHtml ? "html" : "pdf");
|
|
||||||
// 判断之前是否已转换过,如果转换过,直接返回,否则执行转换
|
|
||||||
if (!fileUtils.listConvertedFiles().containsKey(pdfName)) {
|
|
||||||
String filePath = fileDir + fileName;
|
|
||||||
if (!new File(filePath).exists()) {
|
|
||||||
ReturnResponse<String> response = downloadUtils.downLoad(decodedUrl, suffix, null);
|
|
||||||
if (0 != response.getCode()) {
|
|
||||||
model.addAttribute("msg", response.getMsg());
|
|
||||||
return "fileNotSupported";
|
|
||||||
}
|
|
||||||
filePath = response.getContent();
|
|
||||||
}
|
|
||||||
String outFilePath = fileDir + pdfName;
|
|
||||||
if (StringUtils.hasText(outFilePath)) {
|
|
||||||
officeToPdf.openOfficeToPDF(filePath, outFilePath);
|
|
||||||
File f = new File(filePath);
|
|
||||||
if (f.exists()) {
|
|
||||||
f.delete();
|
|
||||||
}
|
|
||||||
if (isHtml) {
|
|
||||||
// 对转换后的文件进行操作(改变编码方式)
|
|
||||||
fileUtils.doActionConvertedFile(outFilePath);
|
|
||||||
}
|
|
||||||
// 加入缓存
|
|
||||||
fileUtils.addConvertedFile(pdfName, fileUtils.getRelativePath(outFilePath));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
model.addAttribute("pdfUrl", pdfName);
|
|
||||||
return isHtml ? "html" : "pdf";
|
|
||||||
}else {
|
|
||||||
model.addAttribute("msg", "系统还不支持该格式文件的在线预览," +
|
|
||||||
"如有需要请按下方显示的邮箱地址联系系统维护人员");
|
|
||||||
return "fileNotSupported";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String suffixFromUrl(String url) {
|
|
||||||
String nonPramStr = url.substring(0, url.indexOf("?") != -1 ? url.indexOf("?"): url.length());
|
|
||||||
String fileName = nonPramStr.substring(nonPramStr.lastIndexOf("/") + 1);
|
|
||||||
String fileType = fileName.substring(fileName.lastIndexOf(".") + 1);
|
|
||||||
return fileType;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查看文件类型(防止参数中存在.点号或者其他特殊字符,所以先抽取文件名,然后再获取文件类型)
|
|
||||||
* @param url
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
private String typeFromUrl(String url) {
|
|
||||||
String nonPramStr = url.substring(0, url.indexOf("?") != -1 ? url.indexOf("?"): url.length());
|
|
||||||
String fileName = nonPramStr.substring(nonPramStr.lastIndexOf("/") + 1);
|
|
||||||
String fileType = fileName.substring(fileName.lastIndexOf(".") + 1);
|
|
||||||
if (fileUtils.listPictureTypes().contains(fileType.toLowerCase())) {
|
|
||||||
fileType = "picture";
|
|
||||||
}
|
|
||||||
if (fileUtils.listArchiveTypes().contains(fileType.toLowerCase())) {
|
|
||||||
fileType = "compress";
|
|
||||||
}
|
|
||||||
if (fileUtils.listOfficeTypes().contains(fileType.toLowerCase())) {
|
|
||||||
fileType = "office";
|
|
||||||
}
|
|
||||||
if (Arrays.asList(simText).contains(fileType.toLowerCase())) {
|
|
||||||
fileType = "simText";
|
|
||||||
}
|
|
||||||
return fileType;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据url获取文件内容
|
|
||||||
* 当pdfjs读取存在跨域问题的文件时将通过此接口读取
|
|
||||||
* @param urlPath
|
|
||||||
* @param resp
|
|
||||||
*/
|
|
||||||
@RequestMapping(value = "/getCorsFile", method = RequestMethod.GET)
|
|
||||||
public void getCorsFile(String urlPath, HttpServletResponse resp) {
|
|
||||||
InputStream inputStream = null;
|
|
||||||
try {
|
|
||||||
String strUrl = urlPath.trim();
|
|
||||||
URL url=new URL(strUrl);
|
|
||||||
//打开请求连接
|
|
||||||
URLConnection connection = url.openConnection();
|
|
||||||
HttpURLConnection httpURLConnection=(HttpURLConnection) connection;
|
|
||||||
httpURLConnection.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
|
|
||||||
inputStream = httpURLConnection.getInputStream();
|
|
||||||
byte[] bs = new byte[1024];
|
|
||||||
int len;
|
|
||||||
while(-1 != (len = inputStream.read(bs))) {
|
|
||||||
resp.getOutputStream().write(bs, 0, len);
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} finally {
|
|
||||||
if(inputStream != null) {
|
|
||||||
IOUtils.closeQuietly(inputStream);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -9,5 +9,6 @@ server.tomcat.uri-encoding = UTF-8
|
|||||||
converted.file.charset = GBK
|
converted.file.charset = GBK
|
||||||
#======================================#文件上传限制#======================================#
|
#======================================#文件上传限制#======================================#
|
||||||
spring.http.multipart.max-file-size=100MB
|
spring.http.multipart.max-file-size=100MB
|
||||||
|
spring.http.multipart.max-request-size=100MB
|
||||||
## 支持的类文本格式的文件类型
|
## 支持的类文本格式的文件类型
|
||||||
simText = txt,html,xml,java,properties,mp3,mp4,sql
|
simText = txt,html,xml,java,properties,mp3,mp4,sql
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
#=============================================#spring Redisson配置#===================================#
|
||||||
|
spring.redisson.address = 10.19.140.7:6379
|
||||||
|
spring.redisson.database = 0
|
||||||
|
##资源映射路径(因为jar方式运行的原因)
|
||||||
|
file.dir = /data/file-preview/convertedFile/
|
||||||
|
spring.resources.static-locations = classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/,file:${file.dir}
|
||||||
|
## openoffice相关配置
|
||||||
|
office.home = /opt/openoffice4
|
||||||
|
|
||||||
|
## 编码设置
|
||||||
|
server.tomcat.uri-encoding = utf-8
|
||||||
|
converted.file.charset = utf-8
|
||||||
|
## 文件上传最大值
|
||||||
|
spring.http.multipart.max-file-size = 100MB
|
||||||
|
|
||||||
|
## 支持的类文本格式的文件类型
|
||||||
|
simText = txt,html,xml,java,properties,sql,js,md,json,conf,ini,vue,php,py,bat,gitignore,log,htm,mp3,mp4,css,cnf
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
env_base_config = {
|
|
||||||
server_base_url:'http://127.0.0.1:8012/',
|
|
||||||
}
|
|
||||||
env_config = {
|
|
||||||
server_base_url:env_base_config.server_base_url,
|
|
||||||
server_preview_url:env_base_config.server_base_url + 'onlinePreview?url=',
|
|
||||||
server_delete_url:env_base_config.server_base_url + 'deleteFile?fileName=',
|
|
||||||
}
|
|
||||||
@@ -32,7 +32,6 @@
|
|||||||
<ul id="treeDemo" class="ztree"></ul>
|
<ul id="treeDemo" class="ztree"></ul>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
<script type="text/javascript" src="config.js"></script>
|
|
||||||
<script type="text/javascript" src="js/jquery-3.0.0.min.js"></script>
|
<script type="text/javascript" src="js/jquery-3.0.0.min.js"></script>
|
||||||
<script type="text/javascript" src="js/jquery.ztree.core.js"></script>
|
<script type="text/javascript" src="js/jquery.ztree.core.js"></script>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
@@ -69,7 +68,7 @@
|
|||||||
fulls += ",resizable"; // 对于不支持screen属性的浏览器,可以手工进行最大化。 manually
|
fulls += ",resizable"; // 对于不支持screen属性的浏览器,可以手工进行最大化。 manually
|
||||||
}
|
}
|
||||||
window.open("onlinePreview?url="
|
window.open("onlinePreview?url="
|
||||||
+ encodeURIComponent("${baseUrl}" + treeNode.fileName), "_blank",fulls);
|
+ encodeURIComponent("${baseUrl}" + treeNode.fileName)+"&fileKey="+treeNode.fileKey, "_blank",fulls);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
</a>
|
</a>
|
||||||
</h4>
|
</h4>
|
||||||
</div>
|
</div>
|
||||||
<div id="collapseOne" class="panel-collapse collapse in">
|
<div id="collapseOne" class="panel-collapse collapse">
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<div>
|
<div>
|
||||||
如果你的项目需要接入文件预览项目,达到对docx、excel、ppt、jpg等文件的预览效果,那么通过在你的项目中加入下面的代码就可以
|
如果你的项目需要接入文件预览项目,达到对docx、excel、ppt、jpg等文件的预览效果,那么通过在你的项目中加入下面的代码就可以
|
||||||
@@ -37,10 +37,19 @@
|
|||||||
};
|
};
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
新增多图片同时预览功能,接口如下:
|
||||||
|
<pre style="background-color: #2f332a;color: #cccccc">
|
||||||
|
var fileUrl =url1+"|"+"url2";//多文件使用“|”字符隔开
|
||||||
|
var url = "http://localhost:8012/picturesPreview?urls" + encodeURIComponent(fileUrl);
|
||||||
|
var winHeight = window.document.documentElement.clientHeight-10;
|
||||||
|
$window.open(url, "_blank", "height=" + winHeight
|
||||||
|
+ ",top=80,left=80,toolbar=no, menubar=no, scrollbars=yes, resizable=yes");
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<h4 class="panel-title">
|
<h4 class="panel-title">
|
||||||
@@ -65,6 +74,47 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="panel">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<h4 class="panel-title">
|
||||||
|
<a data-toggle="collapse" data-parent="#accordion"
|
||||||
|
href="#collapseThree">
|
||||||
|
更新记录
|
||||||
|
</a>
|
||||||
|
</h4>
|
||||||
|
</div>
|
||||||
|
<div id="collapseThree" class="panel-collapse collapse in">
|
||||||
|
<div class="panel-body">
|
||||||
|
<div>
|
||||||
|
2018年01月15日 :<br>
|
||||||
|
1.首页新增社会化评论框<br><br>
|
||||||
|
|
||||||
|
2018年01月12日 :<br>
|
||||||
|
1.新增多图片同时预览<br>
|
||||||
|
2.支持压缩包内图片轮番预览<br><br>
|
||||||
|
|
||||||
|
2018年01月02日 :<br>
|
||||||
|
1.修复txt等文本编码问题导致预览乱码<br>
|
||||||
|
2.修复项目模块依赖引入不到的问题<br>
|
||||||
|
3.新增spring boot profile,支持多环境配置<br>
|
||||||
|
4.引入pdf.js预览doc等文件,支持doc标题生成pdf预览菜单,支持手机端预览<br><br>
|
||||||
|
|
||||||
|
2017年12月12日:<br>
|
||||||
|
1.项目osc开源:<a href="https://gitee.com/kekingcn/file-online-preview" target="_blank">https://gitee.com/kekingcn/file-online-preview</a><br>
|
||||||
|
2.项目github开源:<a href="https://github.com/kekingcn/kkFileView" target="_blank">https://github.com/kekingcn/kkFileView</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
<div>
|
||||||
|
<!-- UY BEGIN -->
|
||||||
|
<div id="uyan_frame"></div>
|
||||||
|
<script type="text/javascript" src="http://v2.uyan.cc/code/uyan.js?uid=2155152"></script>
|
||||||
|
<!-- UY END -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="loading_container">
|
<div class="loading_container">
|
||||||
@@ -89,7 +139,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script type="text/javascript" src="config.js"></script>
|
|
||||||
<script src="js/jquery-3.0.0.min.js" type="text/javascript"></script>
|
<script src="js/jquery-3.0.0.min.js" type="text/javascript"></script>
|
||||||
<script src="https://cdn.bootcss.com/jquery.form/3.09/jquery.form.min.js" type="text/javascript"></script>
|
<script src="https://cdn.bootcss.com/jquery.form/3.09/jquery.form.min.js" type="text/javascript"></script>
|
||||||
<script src="http://cdn.static.runoob.com/libs/bootstrap/3.3.7/js/bootstrap.min.js"></script>
|
<script src="http://cdn.static.runoob.com/libs/bootstrap/3.3.7/js/bootstrap.min.js"></script>
|
||||||
|
|||||||
@@ -7,30 +7,24 @@
|
|||||||
<style>
|
<style>
|
||||||
* { margin: 0; padding: 0;}
|
* { margin: 0; padding: 0;}
|
||||||
#dowebok { width: 800px; margin: 0 auto; font-size: 0;}
|
#dowebok { width: 800px; margin: 0 auto; font-size: 0;}
|
||||||
#dowebok li { display: inline-block; width: 32%; margin-left: 1%; padding-top: 1%;}
|
#dowebok li { display: inline-block;width: 50px;height: 50px; margin-left: 1%; padding-top: 1%;}
|
||||||
/*#dowebok li img { width: 200%;}*/
|
/*#dowebok li img { width: 200%;}*/
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h1>如果图片质量很好,首次加载图片时间可能会有点长,请耐心等待</h1>
|
|
||||||
|
|
||||||
<ul id="dowebok">
|
<ul id="dowebok">
|
||||||
<#--<li><img id="Imgbox" src="#" width="800px" height="550px"></li>-->
|
<#list imgurls as img>
|
||||||
|
<li><img id="${img}" url="${img}" src="${img}" width="1px" height="1px"></li>
|
||||||
<li><img id="Imgbox" src="#" width="800px" height="auto"></li>
|
</#list>
|
||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
<script src="js/viewer.min.js"></script>
|
<script src="js/viewer.min.js"></script>
|
||||||
<script>
|
<script>
|
||||||
//初始化图片地址
|
var viewer = new Viewer(document.getElementById('dowebok'), {
|
||||||
window.onload = function () {
|
url: 'src',
|
||||||
// document.getElementById("Imgbox").src = getParameter("imgurl");
|
navbar:false
|
||||||
document.getElementById("Imgbox").src =document.getElementById("url").value;
|
});
|
||||||
}
|
document.getElementById("${currentUrl}").click();
|
||||||
var viewer = new Viewer(document.getElementById('dowebok'), {url: 'src'});
|
|
||||||
viewer.show();
|
|
||||||
</script>
|
</script>
|
||||||
<input name="url" value="${imgurl}" type="hidden" id="url" >
|
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.yudianbank;
|
package cn.keking;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
|||||||
2
pom.xml
2
pom.xml
@@ -3,7 +3,7 @@
|
|||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
<groupId>com.yudianbank</groupId>
|
<groupId>cn.keking</groupId>
|
||||||
<artifactId>filepreview</artifactId>
|
<artifactId>filepreview</artifactId>
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
<modules>
|
<modules>
|
||||||
|
|||||||
Reference in New Issue
Block a user