mirror of
https://github.com/kekingcn/kkFileView.git
synced 2026-03-30 11:44:15 +00:00
Compare commits
33 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6f2001b8c9 | ||
|
|
378920b773 | ||
|
|
c78bf0605d | ||
|
|
e8f0efe1ec | ||
|
|
f8ebc4e39b | ||
|
|
3ecea6ee6c | ||
|
|
540e434954 | ||
|
|
6754232a1d | ||
|
|
ad790f4ae9 | ||
|
|
05464bbf1c | ||
|
|
cbe22c259f | ||
|
|
976a071089 | ||
|
|
bb7407542f | ||
|
|
2f86701eea | ||
|
|
5b5388e51f | ||
|
|
02957d98fc | ||
|
|
e3126f3711 | ||
|
|
a04e68c1af | ||
|
|
d4515dfadd | ||
|
|
78de36964d | ||
|
|
dcf37b94db | ||
|
|
73764b027b | ||
|
|
6d621dc05f | ||
|
|
4d6c5501ae | ||
|
|
cd8d1e2ba8 | ||
|
|
4731772d38 | ||
|
|
bc9bb6862b | ||
|
|
4462bab4fa | ||
|
|
6d98c972d1 | ||
|
|
852abadf8f | ||
|
|
2a93f80827 | ||
|
|
a8aef1b97b | ||
|
|
3e5ba7d3ba |
104
README.en.md
Normal file
104
README.en.md
Normal file
@@ -0,0 +1,104 @@
|
||||
# file-online-preview
|
||||
|
||||
[](https://github.com/kekingcn/kkFileView/blob/master/LICENSE)
|
||||
|
||||
### Introduction
|
||||
|
||||
This kekingcn kkFileView project is intended to be a solution for previewing documents online. At present,there are some similar paid products in the industry.
|
||||
Such as 【[永中office](http://dcs.yozosoft.com/)】,【[office365](http://www.officeweb365.com/)】,【[idocv](https://www.idocv.com/)】, etc...
|
||||
It is an open source implementation and released under the Apache License version 2.0. Finally,It is aimed to feedback the community after obtaining the consent of company executives,
|
||||
special thanks to the supports of @唐老大 and the contributions of @端木详笑.
|
||||
|
||||
### Features
|
||||
- Build with the popular frame spring boot
|
||||
- Easy to build and deploy
|
||||
- Basically support online preview of mainstream office documents, such as Doc, docx, Excel, PDF, TXT, zip, rar, pictures, etc
|
||||
- REST API
|
||||
- Abstract file preview interface so that it is easy to extend more file extensions and develop this project on your own
|
||||
|
||||
### Live demo
|
||||
> Please treat public service kindly, or this would stop at any time.
|
||||
|
||||
URL:http://file.keking.cn/
|
||||
|
||||
### 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 in use of this project.
|
||||
And please Google or Baidu first before asking a question, so that we can solve it 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.There is a way to deploy it as below.
|
||||
|
||||
### Quick Start
|
||||
> Technology stack
|
||||
- Spring boot: [spring boot Development Reference Guide](http://www.kailing.pub/PdfReader/web/viewer.html?file=springboot)
|
||||
- Freemarker
|
||||
- Redisson
|
||||
- Jodconverter
|
||||
> Dependencies
|
||||
- Redis
|
||||
- OpenOffice or LibreOffice
|
||||
|
||||
1. First step:`git 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.
|
||||

|
||||
|
||||
### Changelog
|
||||
|
||||
> January 17th 2018
|
||||
|
||||
1. Refined the project directory, abstract file preview interface, Easy to extend more file extensions and depoly this project on your own
|
||||
1. Added English documentation (@幻幻Fate,@汝辉) contribution
|
||||
1. Support for more image file extensions
|
||||
1. Fixed the issue that image carousel in zip file will always start from the first
|
||||
|
||||
> 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.
|
||||
45
README.md
45
README.md
@@ -1,9 +1,24 @@
|
||||
# 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,图片等等
|
||||
### 项目特性
|
||||
|
||||
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接口提供服务,跨平台特性(java,php,python,go,php,....)都支持,应用接入简单方便
|
||||
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过,珍爱生命远离无效的交流沟通
|
||||
@@ -55,6 +70,34 @@ file.dir为转换文件实际存储地址,注意要以/结尾
|
||||
3. 第三步:运行FilePreviewApplication的main方法,服务启动后,访问http://localhost:8012/
|
||||
会看到如下界面,代表服务启动成功
|
||||

|
||||
|
||||
### 历史更新记录
|
||||
|
||||
> 2018年01月19日 :
|
||||
|
||||
1. 大文件入队提前处理
|
||||
1. 新增addTask文件转换入队接口
|
||||
1. 采用redis队列,支持kkFIleView接口和异构系统入队两种方式
|
||||
|
||||
> 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
|
||||
登记下,如果节省了你的三方预览服务费用,也愿意支持下的话,可点击下方【捐助】请作者喝杯咖啡,也是非常感谢
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
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>
|
||||
<groupId>com.yudianbank</groupId>
|
||||
<groupId>cn.keking</groupId>
|
||||
<artifactId>jodconverter-core</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.yudianbank</groupId>
|
||||
<groupId>cn.keking</groupId>
|
||||
<artifactId>jodconverter-core</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<exclusions>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.yudianbank;
|
||||
package cn.keking;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
@@ -8,7 +8,7 @@ import java.util.Properties;
|
||||
|
||||
@SpringBootApplication
|
||||
@EnableScheduling
|
||||
@ComponentScan(value = "com.yudianbank.*")
|
||||
@ComponentScan(value = "cn.keking.*")
|
||||
public class FilePreviewApplication {
|
||||
public static void main(String[] args) {
|
||||
Properties properties = System.getProperties();
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.yudianbank.config;
|
||||
package cn.keking.config;
|
||||
|
||||
import io.netty.channel.nio.NioEventLoopGroup;
|
||||
import org.redisson.Redisson;
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.yudianbank.extend;
|
||||
package cn.keking.extend;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import com.sun.star.beans.PropertyValue;
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.yudianbank.filters;
|
||||
package cn.keking.filters;
|
||||
|
||||
import javax.servlet.*;
|
||||
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.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;
|
||||
}
|
||||
}
|
||||
28
jodconverter-web/src/main/java/cn/keking/model/FileType.java
Normal file
28
jodconverter-web/src/main/java/cn/keking/model/FileType.java
Normal file
@@ -0,0 +1,28 @@
|
||||
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"),
|
||||
media("mediaFilePreviewImpl");
|
||||
|
||||
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.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
package cn.keking.service;
|
||||
|
||||
import cn.keking.model.FileAttribute;
|
||||
import cn.keking.model.FileType;
|
||||
import cn.keking.utils.FileUtils;
|
||||
import org.redisson.api.RBlockingQueue;
|
||||
import org.redisson.api.RedissonClient;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.ui.ExtendedModelMap;
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
/**
|
||||
* Created by kl on 2018/1/19.
|
||||
* Content :消费队列中的转换文件
|
||||
*/
|
||||
@Service
|
||||
public class FileConverQueueTask {
|
||||
|
||||
Logger logger= LoggerFactory.getLogger(getClass());
|
||||
public static final String queueTaskName="FileConverQueueTask";
|
||||
|
||||
@Autowired
|
||||
FilePreviewFactory previewFactory;
|
||||
|
||||
@Autowired
|
||||
RedissonClient redissonClient;
|
||||
|
||||
@Autowired
|
||||
FileUtils fileUtils;
|
||||
|
||||
@PostConstruct
|
||||
public void startTask(){
|
||||
ExecutorService executorService = Executors.newFixedThreadPool(3);
|
||||
executorService.submit(new ConverTask(previewFactory,redissonClient,fileUtils));
|
||||
logger.info("队列处理文件转换任务启动完成 ");
|
||||
}
|
||||
|
||||
class ConverTask implements Runnable{
|
||||
|
||||
FilePreviewFactory previewFactory;
|
||||
|
||||
RedissonClient redissonClient;
|
||||
|
||||
FileUtils fileUtils;
|
||||
|
||||
public ConverTask(FilePreviewFactory previewFactory, RedissonClient redissonClient,FileUtils fileUtils) {
|
||||
this.previewFactory = previewFactory;
|
||||
this.redissonClient = redissonClient;
|
||||
this.fileUtils=fileUtils;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
while (true) {
|
||||
try {
|
||||
final RBlockingQueue<String> queue = redissonClient.getBlockingQueue(FileConverQueueTask.queueTaskName);
|
||||
String url = queue.take();
|
||||
if(url!=null){
|
||||
FileAttribute fileAttribute=fileUtils.getFileAttribute(url);
|
||||
logger.info("正在处理转换任务,文件名称【{}】",fileAttribute.getName());
|
||||
FileType fileType=fileAttribute.getType();
|
||||
if(fileType.equals(FileType.compress) || fileType.equals(FileType.office)){
|
||||
FilePreview filePreview=previewFactory.get(url);
|
||||
filePreview.filePreviewHandle(url,new ExtendedModelMap());
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
try {
|
||||
Thread.sleep(1000*10);
|
||||
}catch (Exception ex){
|
||||
ex.printStackTrace();
|
||||
}
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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.model.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,27 @@
|
||||
package cn.keking.service.impl;
|
||||
|
||||
import cn.keking.service.FilePreview;
|
||||
import cn.keking.utils.FileUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.ui.Model;
|
||||
/**
|
||||
* @author : kl
|
||||
* @authorboke : kailing.pub
|
||||
* @create : 2018-03-25 上午11:58
|
||||
* @description:
|
||||
**/
|
||||
@Service
|
||||
public class MediaFilePreviewImpl implements FilePreview {
|
||||
|
||||
@Autowired
|
||||
FileUtils fileUtils;
|
||||
|
||||
@Override
|
||||
public String filePreviewHandle(String url, Model model) {
|
||||
model.addAttribute("mediaUrl", url);
|
||||
return "media";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package cn.keking.service.impl;
|
||||
|
||||
import cn.keking.model.FileAttribute;
|
||||
import cn.keking.model.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.ExtendedModelMap;
|
||||
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,28 @@
|
||||
package cn.keking.service.impl;
|
||||
|
||||
import cn.keking.model.FileAttribute;
|
||||
import cn.keking.service.FilePreview;
|
||||
import cn.keking.utils.FileUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.ui.Model;
|
||||
|
||||
/**
|
||||
* Created by kl on 2018/1/17.
|
||||
* Content :其他文件
|
||||
*/
|
||||
@Service
|
||||
public class OtherFilePreviewImpl implements FilePreview {
|
||||
@Autowired
|
||||
FileUtils fileUtils;
|
||||
|
||||
@Override
|
||||
public String filePreviewHandle(String url, Model model) {
|
||||
FileAttribute fileAttribute=fileUtils.getFileAttribute(url);
|
||||
|
||||
model.addAttribute("fileType",fileAttribute.getSuffix());
|
||||
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,40 @@
|
||||
package cn.keking.service.impl;
|
||||
|
||||
import cn.keking.model.FileAttribute;
|
||||
import cn.keking.model.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;
|
||||
|
||||
/**
|
||||
* 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());
|
||||
model.addAttribute("fileType",fileAttribute.getSuffix());
|
||||
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.yudianbank.extend.ControlDocumentFormatRegistry;
|
||||
import cn.keking.extend.ControlDocumentFormatRegistry;
|
||||
import org.artofsolving.jodconverter.OfficeDocumentConverter;
|
||||
import org.artofsolving.jodconverter.office.DefaultOfficeManagerConfiguration;
|
||||
import org.artofsolving.jodconverter.office.OfficeManager;
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.yudianbank.utils;
|
||||
package cn.keking.utils;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
package com.yudianbank.utils;
|
||||
package cn.keking.utils;
|
||||
|
||||
import com.yudianbank.param.ReturnResponse;
|
||||
import cn.keking.model.ReturnResponse;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
@@ -1,157 +1,157 @@
|
||||
package com.yudianbank.utils;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.mozilla.intl.chardet.nsDetector;
|
||||
import org.mozilla.intl.chardet.nsICharsetDetectionObserver;
|
||||
|
||||
/**
|
||||
* 文本文件编码探测工具类
|
||||
*
|
||||
* @author HWliao
|
||||
* @date 2017-12-24
|
||||
*/
|
||||
public class FileCharsetDetector {
|
||||
|
||||
/**
|
||||
* 传入一个文件(File)对象,检查文件编码
|
||||
*
|
||||
* @param file File对象实例
|
||||
* @return 文件编码,若无,则返回null
|
||||
* @throws FileNotFoundException
|
||||
* @throws IOException
|
||||
*/
|
||||
public static Observer guessFileEncoding(File file)
|
||||
throws FileNotFoundException, IOException {
|
||||
return guessFileEncoding(file, new nsDetector());
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* 获取文件的编码
|
||||
* @param file
|
||||
* File对象实例
|
||||
* @param languageHint
|
||||
* 语言提示区域代码 @see #nsPSMDetector ,取值如下:
|
||||
* 1 : Japanese
|
||||
* 2 : Chinese
|
||||
* 3 : Simplified Chinese
|
||||
* 4 : Traditional Chinese
|
||||
* 5 : Korean
|
||||
* 6 : Dont know(default)
|
||||
* </pre>
|
||||
*
|
||||
* @return 文件编码,eg:UTF-8,GBK,GB2312形式(不确定的时候,返回可能的字符编码序列);若无,则返回null
|
||||
* @throws FileNotFoundException
|
||||
* @throws IOException
|
||||
*/
|
||||
public static Observer guessFileEncoding(File file, int languageHint)
|
||||
throws FileNotFoundException, IOException {
|
||||
return guessFileEncoding(file, new nsDetector(languageHint));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件的编码
|
||||
*
|
||||
* @param file
|
||||
* @param det
|
||||
* @return
|
||||
* @throws FileNotFoundException
|
||||
* @throws IOException
|
||||
*/
|
||||
private static Observer guessFileEncoding(File file, nsDetector det)
|
||||
throws FileNotFoundException, IOException {
|
||||
// new Observer
|
||||
Observer observer = new Observer();
|
||||
// set Observer
|
||||
// The Notify() will be called when a matching charset is found.
|
||||
det.Init(observer);
|
||||
|
||||
BufferedInputStream imp = new BufferedInputStream(new FileInputStream(
|
||||
file));
|
||||
byte[] buf = new byte[1024];
|
||||
int len;
|
||||
boolean done = false;
|
||||
boolean isAscii = false;
|
||||
|
||||
while ((len = imp.read(buf, 0, buf.length)) != -1) {
|
||||
// Check if the stream is only ascii.
|
||||
isAscii = det.isAscii(buf, len);
|
||||
if (isAscii) {
|
||||
break;
|
||||
}
|
||||
// DoIt if non-ascii and not done yet.
|
||||
done = det.DoIt(buf, len, false);
|
||||
if (done) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
imp.close();
|
||||
det.DataEnd();
|
||||
|
||||
if (isAscii) {
|
||||
observer.encoding = "ASCII";
|
||||
observer.found = true;
|
||||
}
|
||||
|
||||
if (!observer.isFound()) {
|
||||
String[] prob = det.getProbableCharsets();
|
||||
// // 这里将可能的字符集组合起来返回
|
||||
// for (int i = 0; i < prob.length; i++) {
|
||||
// if (i == 0) {
|
||||
// encoding = prob[i];
|
||||
// } else {
|
||||
// encoding += "," + prob[i];
|
||||
// }
|
||||
// }
|
||||
if (prob.length > 0) {
|
||||
// 在没有发现情况下,去第一个可能的编码
|
||||
observer.encoding = prob[0];
|
||||
} else {
|
||||
observer.encoding = null;
|
||||
}
|
||||
}
|
||||
return observer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @author liaohongwei
|
||||
* @Description: 文件字符编码观察者, 但判断出字符编码时候调用
|
||||
* @date 2016年6月20日 下午2:27:06
|
||||
*/
|
||||
public static class Observer implements nsICharsetDetectionObserver {
|
||||
|
||||
/**
|
||||
* @Fields encoding : 字符编码
|
||||
*/
|
||||
private String encoding = null;
|
||||
/**
|
||||
* @Fields found : 是否找到字符集
|
||||
*/
|
||||
private boolean found = false;
|
||||
|
||||
@Override
|
||||
public void Notify(String charset) {
|
||||
this.encoding = charset;
|
||||
this.found = true;
|
||||
}
|
||||
|
||||
public String getEncoding() {
|
||||
return encoding;
|
||||
}
|
||||
|
||||
public boolean isFound() {
|
||||
return found;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Observer [encoding=" + encoding + ", found=" + found + "]";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
package cn.keking.utils;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.mozilla.intl.chardet.nsDetector;
|
||||
import org.mozilla.intl.chardet.nsICharsetDetectionObserver;
|
||||
|
||||
/**
|
||||
* 文本文件编码探测工具类
|
||||
*
|
||||
* @author HWliao
|
||||
* @date 2017-12-24
|
||||
*/
|
||||
public class FileCharsetDetector {
|
||||
|
||||
/**
|
||||
* 传入一个文件(File)对象,检查文件编码
|
||||
*
|
||||
* @param file File对象实例
|
||||
* @return 文件编码,若无,则返回null
|
||||
* @throws FileNotFoundException
|
||||
* @throws IOException
|
||||
*/
|
||||
public static Observer guessFileEncoding(File file)
|
||||
throws FileNotFoundException, IOException {
|
||||
return guessFileEncoding(file, new nsDetector());
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* 获取文件的编码
|
||||
* @param file
|
||||
* File对象实例
|
||||
* @param languageHint
|
||||
* 语言提示区域代码 @see #nsPSMDetector ,取值如下:
|
||||
* 1 : Japanese
|
||||
* 2 : Chinese
|
||||
* 3 : Simplified Chinese
|
||||
* 4 : Traditional Chinese
|
||||
* 5 : Korean
|
||||
* 6 : Dont know(default)
|
||||
* </pre>
|
||||
*
|
||||
* @return 文件编码,eg:UTF-8,GBK,GB2312形式(不确定的时候,返回可能的字符编码序列);若无,则返回null
|
||||
* @throws FileNotFoundException
|
||||
* @throws IOException
|
||||
*/
|
||||
public static Observer guessFileEncoding(File file, int languageHint)
|
||||
throws FileNotFoundException, IOException {
|
||||
return guessFileEncoding(file, new nsDetector(languageHint));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件的编码
|
||||
*
|
||||
* @param file
|
||||
* @param det
|
||||
* @return
|
||||
* @throws FileNotFoundException
|
||||
* @throws IOException
|
||||
*/
|
||||
private static Observer guessFileEncoding(File file, nsDetector det)
|
||||
throws FileNotFoundException, IOException {
|
||||
// new Observer
|
||||
Observer observer = new Observer();
|
||||
// set Observer
|
||||
// The Notify() will be called when a matching charset is found.
|
||||
det.Init(observer);
|
||||
|
||||
BufferedInputStream imp = new BufferedInputStream(new FileInputStream(
|
||||
file));
|
||||
byte[] buf = new byte[1024];
|
||||
int len;
|
||||
boolean done = false;
|
||||
boolean isAscii = false;
|
||||
|
||||
while ((len = imp.read(buf, 0, buf.length)) != -1) {
|
||||
// Check if the stream is only ascii.
|
||||
isAscii = det.isAscii(buf, len);
|
||||
if (isAscii) {
|
||||
break;
|
||||
}
|
||||
// DoIt if non-ascii and not done yet.
|
||||
done = det.DoIt(buf, len, false);
|
||||
if (done) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
imp.close();
|
||||
det.DataEnd();
|
||||
|
||||
if (isAscii) {
|
||||
observer.encoding = "ASCII";
|
||||
observer.found = true;
|
||||
}
|
||||
|
||||
if (!observer.isFound()) {
|
||||
String[] prob = det.getProbableCharsets();
|
||||
// // 这里将可能的字符集组合起来返回
|
||||
// for (int i = 0; i < prob.length; i++) {
|
||||
// if (i == 0) {
|
||||
// encoding = prob[i];
|
||||
// } else {
|
||||
// encoding += "," + prob[i];
|
||||
// }
|
||||
// }
|
||||
if (prob.length > 0) {
|
||||
// 在没有发现情况下,去第一个可能的编码
|
||||
observer.encoding = prob[0];
|
||||
} else {
|
||||
observer.encoding = null;
|
||||
}
|
||||
}
|
||||
return observer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @author liaohongwei
|
||||
* @Description: 文件字符编码观察者, 但判断出字符编码时候调用
|
||||
* @date 2016年6月20日 下午2:27:06
|
||||
*/
|
||||
public static class Observer implements nsICharsetDetectionObserver {
|
||||
|
||||
/**
|
||||
* @Fields encoding : 字符编码
|
||||
*/
|
||||
private String encoding = null;
|
||||
/**
|
||||
* @Fields found : 是否找到字符集
|
||||
*/
|
||||
private boolean found = false;
|
||||
|
||||
@Override
|
||||
public void Notify(String charset) {
|
||||
this.encoding = charset;
|
||||
this.found = true;
|
||||
}
|
||||
|
||||
public String getEncoding() {
|
||||
return encoding;
|
||||
}
|
||||
|
||||
public boolean isFound() {
|
||||
return found;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
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 org.redisson.api.RMapCache;
|
||||
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.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.URLDecoder;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -19,9 +25,11 @@ import java.util.Map;
|
||||
*/
|
||||
@Component
|
||||
public class FileUtils {
|
||||
Logger log= LoggerFactory.getLogger(getClass());
|
||||
|
||||
|
||||
final String REDIS_FILE_PREVIEW_PDF_KEY = "converted-preview-pdf-file";
|
||||
|
||||
final String REDIS_FILE_PREVIEW_IMGS_KEY = "converted-preview-imgs-file";//压缩包内图片文件集合
|
||||
@Autowired
|
||||
RedissonClient redissonClient;
|
||||
@Value("${file.dir}")
|
||||
@@ -30,6 +38,11 @@ public class FileUtils {
|
||||
@Value("${converted.file.charset}")
|
||||
String charset;
|
||||
|
||||
@Value("${simText}")
|
||||
String[] simText;
|
||||
|
||||
@Value("${media}")
|
||||
String[] media;
|
||||
/**
|
||||
* 已转换过的文件集合(redis缓存)
|
||||
* @return
|
||||
@@ -48,6 +61,36 @@ public class FileUtils {
|
||||
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 (Arrays.asList(media).contains(fileType.toLowerCase())) {
|
||||
return FileType.media;
|
||||
}
|
||||
if("pdf".equalsIgnoreCase(fileType)){
|
||||
return FileType.pdf;
|
||||
}
|
||||
return FileType.other;
|
||||
}
|
||||
/**
|
||||
* 从url中剥离出文件名
|
||||
* @param url
|
||||
@@ -89,6 +132,8 @@ public class FileUtils {
|
||||
list.add("png");
|
||||
list.add("gif");
|
||||
list.add("bmp");
|
||||
list.add("ico");
|
||||
list.add("RAW");
|
||||
return list;
|
||||
}
|
||||
|
||||
@@ -129,6 +174,25 @@ public class FileUtils {
|
||||
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
|
||||
@@ -189,4 +253,30 @@ public class FileUtils {
|
||||
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.springframework.beans.factory.annotation.Autowired;
|
||||
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.stereotype.Component;
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.yudianbank.utils;
|
||||
package cn.keking.utils;
|
||||
|
||||
import com.yudianbank.param.ReturnResponse;
|
||||
import cn.keking.model.ReturnResponse;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
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.databind.ObjectMapper;
|
||||
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.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
|
||||
import java.io.*;
|
||||
import java.math.BigDecimal;
|
||||
import java.text.CollationKey;
|
||||
import java.text.Collator;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
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
|
||||
public class ZipReader {
|
||||
static Pattern pattern = Pattern.compile("^\\d+");
|
||||
|
||||
@Autowired
|
||||
FileUtils fileUtils;
|
||||
@@ -49,9 +57,11 @@ public class ZipReader {
|
||||
* </p>
|
||||
* @param filePath
|
||||
*/
|
||||
public String readZipFile(String filePath) {
|
||||
public String readZipFile(String filePath,String fileKey) {
|
||||
String archiveSeparator = "/";
|
||||
Map<String, FileNode> appender = Maps.newHashMap();
|
||||
List imgUrls=Lists.newArrayList();
|
||||
String baseUrl= (String) RequestContextHolder.currentRequestAttributes().getAttribute("baseUrl",0);
|
||||
String archiveFileName = fileUtils.getFileNameFromPath(filePath);
|
||||
try {
|
||||
ZipFile zipFile = new ZipFile(filePath, fileUtils.getFileEncodeUTFGBK(filePath));
|
||||
@@ -73,12 +83,17 @@ public class ZipReader {
|
||||
}
|
||||
String parentName = getLast2FileName(fullName, archiveSeparator, archiveFileName);
|
||||
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);
|
||||
appender.put(childName, node);
|
||||
}
|
||||
// 开启新的线程处理文件解压
|
||||
executors.submit(new ZipExtractorWorker(entriesToBeExtracted, zipFile, filePath));
|
||||
fileUtils.setRedisImgUrls(fileKey,imgUrls);
|
||||
return new ObjectMapper().writeValueAsString(appender.get(""));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
@@ -86,6 +101,8 @@ public class ZipReader {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 排序zipEntries(对原来列表倒序)
|
||||
* @param entries
|
||||
@@ -99,8 +116,10 @@ public class ZipReader {
|
||||
return Collections.enumeration(sortedEntries);
|
||||
}
|
||||
|
||||
public String unRar(String filePath){
|
||||
public String unRar(String filePath,String fileKey){
|
||||
Map<String, FileNode> appender = Maps.newHashMap();
|
||||
List imgUrls=Lists.newArrayList();
|
||||
String baseUrl= (String) RequestContextHolder.currentRequestAttributes().getAttribute("baseUrl",0);
|
||||
try {
|
||||
Archive archive = new Archive(new File(filePath));
|
||||
List<FileHeader> headers = archive.getFileHeaders();
|
||||
@@ -123,11 +142,16 @@ public class ZipReader {
|
||||
headersToBeExtracted.add(Collections.singletonMap(childName, header));
|
||||
}
|
||||
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);
|
||||
appender.put(childName, node);
|
||||
}
|
||||
executors.submit(new RarExtractorWorker(headersToBeExtracted, archive, filePath));
|
||||
fileUtils.setRedisImgUrls(fileKey,imgUrls);
|
||||
return new ObjectMapper().writeValueAsString(appender.get(""));
|
||||
} catch (RarException e) {
|
||||
e.printStackTrace();
|
||||
@@ -140,6 +164,8 @@ public class ZipReader {
|
||||
private void addNodes(Map<String, FileNode> appender, String parentName, FileNode node) {
|
||||
if (appender.containsKey(parentName)) {
|
||||
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 { // 根节点
|
||||
FileNode nodeRoot = new FileNode(parentName, parentName, "", new ArrayList<>(), true);
|
||||
nodeRoot.getChildList().add(node);
|
||||
@@ -204,6 +230,30 @@ public class ZipReader {
|
||||
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 parentFileName;
|
||||
private boolean directory;
|
||||
|
||||
private String fileKey;//用于图片预览时寻址
|
||||
private List<FileNode> childList;
|
||||
|
||||
public FileNode() {
|
||||
}
|
||||
|
||||
public FileNode(String originName, String fileName, String parentFileName, List<FileNode> childList, boolean directory) {
|
||||
this.originName = originName;
|
||||
this.fileName = fileName;
|
||||
@@ -223,6 +276,21 @@ public class ZipReader {
|
||||
this.childList = childList;
|
||||
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() {
|
||||
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.databind.ObjectMapper;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.yudianbank.param.ReturnResponse;
|
||||
import com.yudianbank.utils.FileUtils;
|
||||
import cn.keking.model.ReturnResponse;
|
||||
import cn.keking.utils.FileUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
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.web.bind.annotation.RequestMapping;
|
||||
@@ -0,0 +1,134 @@
|
||||
package cn.keking.web.controller;
|
||||
|
||||
import cn.keking.service.FileConverQueueTask;
|
||||
import cn.keking.service.FilePreview;
|
||||
import cn.keking.service.FilePreviewFactory;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.redisson.api.RBlockingQueue;
|
||||
import org.redisson.api.RedissonClient;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
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;
|
||||
|
||||
@Autowired
|
||||
RedissonClient redissonClient;
|
||||
|
||||
/**
|
||||
* @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, String currentUrl, Model model, HttpServletRequest req) throws UnsupportedEncodingException {
|
||||
// 路径转码
|
||||
String decodedUrl = URLDecoder.decode(urls, "utf-8");
|
||||
String decodedCurrentUrl = URLDecoder.decode(currentUrl, "utf-8");
|
||||
// 抽取文件并返回文件列表
|
||||
String[] imgs = decodedUrl.split("\\|");
|
||||
List imgurls = Arrays.asList(imgs);
|
||||
model.addAttribute("imgurls", imgurls);
|
||||
model.addAttribute("currentUrl",decodedCurrentUrl);
|
||||
return "picture";
|
||||
}
|
||||
|
||||
@RequestMapping(value = "picturesPreview", method = RequestMethod.POST)
|
||||
public String picturesPreview(Model model, HttpServletRequest req) throws UnsupportedEncodingException {
|
||||
String urls = req.getParameter("urls");
|
||||
String currentUrl = req.getParameter("currentUrl");
|
||||
// 路径转码
|
||||
String decodedUrl = URLDecoder.decode(urls, "utf-8");
|
||||
String decodedCurrentUrl = URLDecoder.decode(currentUrl, "utf-8");
|
||||
// 抽取文件并返回文件列表
|
||||
String[] imgs = decodedUrl.split("\\|");
|
||||
List imgurls = Arrays.asList(imgs);
|
||||
model.addAttribute("imgurls", imgurls);
|
||||
model.addAttribute("currentUrl",decodedCurrentUrl);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过api接口入队
|
||||
* @param url 请编码后在入队
|
||||
*/
|
||||
@GetMapping("/addTask")
|
||||
@ResponseBody
|
||||
public String addQueueTask(String url) {
|
||||
final RBlockingQueue<String> queue = redissonClient.getBlockingQueue(FileConverQueueTask.queueTaskName);
|
||||
queue.addAsync(url);
|
||||
return "success";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,13 +1,15 @@
|
||||
#=============================================#spring Redisson配置#===================================#
|
||||
spring.redisson.address = 192.168.1.204:6379
|
||||
##资源映射路径(因为jar方式运行的原因)
|
||||
file.dir = C:\\Users\\yudian\\Desktop\\dev\\
|
||||
#=============================================#spring Redisson<EFBFBD><EFBFBD><EFBFBD><EFBFBD>#===================================#
|
||||
spring.redisson.address = 127.0.0.1:6379
|
||||
##<EFBFBD><EFBFBD>Դӳ<EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>(<28><>Ϊjar<61><72>ʽ<EFBFBD><CABD><EFBFBD>е<EFBFBD>ԭ<EFBFBD><D4AD>)
|
||||
file.dir = /Users/chenkailing/test/
|
||||
spring.resources.static-locations = classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/,file:${file.dir}
|
||||
## openoffice相关配置
|
||||
office.home = C:\\Program Files (x86)\\OpenOffice 4
|
||||
## openoffice<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
office.home = /Applications/LibreOffice.app/Contents
|
||||
server.tomcat.uri-encoding = UTF-8
|
||||
converted.file.charset = GBK
|
||||
#======================================#文件上传限制#======================================#
|
||||
#======================================#<EFBFBD>ļ<EFBFBD><EFBFBD>ϴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>#======================================#
|
||||
spring.http.multipart.max-file-size=100MB
|
||||
## 支持的类文本格式的文件类型
|
||||
simText = txt,html,xml,java,properties,mp3,mp4,sql
|
||||
spring.http.multipart.max-request-size=100MB
|
||||
## ֧<>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD>ı<EFBFBD><C4B1><EFBFBD>ʽ<EFBFBD><CABD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD>
|
||||
simText = txt,html,xml,java,properties,sql
|
||||
media=mp3,mp4,flv,rmvb
|
||||
@@ -0,0 +1,19 @@
|
||||
#=============================================#spring Redisson<6F><6E><EFBFBD><EFBFBD>#===================================#
|
||||
spring.redisson.address = 10.19.140.7:6379
|
||||
spring.redisson.database = 0
|
||||
##<23><>Դӳ<D4B4><D3B3>·<EFBFBD><C2B7>(<28><>Ϊjar<61><72>ʽ<EFBFBD><CABD><EFBFBD>е<EFBFBD>ԭ<EFBFBD><D4AD>)
|
||||
file.dir = /data/file-preview/convertedFile/
|
||||
spring.resources.static-locations = classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/,file:${file.dir}
|
||||
## openoffice<63><65><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
office.home = /opt/openoffice4
|
||||
|
||||
## <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
server.tomcat.uri-encoding = utf-8
|
||||
converted.file.charset = utf-8
|
||||
## <20>ļ<EFBFBD><C4BC>ϴ<EFBFBD><CFB4><EFBFBD><EFBFBD>ֵ
|
||||
spring.http.multipart.max-file-size = 100MB
|
||||
|
||||
## ֧<>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD>ı<EFBFBD><C4B1><EFBFBD>ʽ<EFBFBD><CABD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD>
|
||||
simText = txt,html,xml,java,properties,sql,js,md,json,conf,ini,vue,php,py,bat,gitignore,log,htm,css,cnf
|
||||
|
||||
media=mp3,mp4,flv
|
||||
@@ -1,14 +1,15 @@
|
||||
#=============================================#spring Redisson配置#===================================#
|
||||
#=============================================#spring Redisson<EFBFBD><EFBFBD><EFBFBD><EFBFBD>#===================================#
|
||||
spring.redisson.address = 192.168.1.204:6379
|
||||
spring.redisson.database = 3
|
||||
##资源映射路径(因为jar方式运行的原因)
|
||||
##<EFBFBD><EFBFBD>Դӳ<EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>(<28><>Ϊjar<61><72>ʽ<EFBFBD><CABD><EFBFBD>е<EFBFBD>ԭ<EFBFBD><D4AD>)
|
||||
file.dir = /data/filepreview/
|
||||
spring.resources.static-locations = classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/,file:${file.dir}
|
||||
## openoffice相关配置
|
||||
## openoffice<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
openOfficePath = 123
|
||||
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
|
||||
## ֧<EFBFBD>ֵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ı<EFBFBD><EFBFBD><EFBFBD>ʽ<EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
simText = txt,html,xml,java,properties,sql,js,md,json,conf,ini,vue,php,py,bat,gitignore,log,htm,css,cnf
|
||||
media=mp3,mp4,flv
|
||||
@@ -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=',
|
||||
}
|
||||
1
jodconverter-web/src/main/resources/static/plyr/plyr.css
Executable file
1
jodconverter-web/src/main/resources/static/plyr/plyr.css
Executable file
File diff suppressed because one or more lines are too long
2
jodconverter-web/src/main/resources/static/plyr/plyr.js
Executable file
2
jodconverter-web/src/main/resources/static/plyr/plyr.js
Executable file
File diff suppressed because one or more lines are too long
1
jodconverter-web/src/main/resources/static/plyr/plyr.svg
Executable file
1
jodconverter-web/src/main/resources/static/plyr/plyr.svg
Executable file
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg"><symbol id="plyr-captions-off" viewBox="0 0 18 18"><path d="M1 1c-.6 0-1 .4-1 1v11c0 .6.4 1 1 1h4.6l2.7 2.7c.2.2.4.3.7.3.3 0 .5-.1.7-.3l2.7-2.7H17c.6 0 1-.4 1-1V2c0-.6-.4-1-1-1H1zm4.52 10.15c1.99 0 3.01-1.32 3.28-2.41l-1.29-.39c-.19.66-.78 1.45-1.99 1.45-1.14 0-2.2-.83-2.2-2.34 0-1.61 1.12-2.37 2.18-2.37 1.23 0 1.78.75 1.95 1.43l1.3-.41C8.47 4.96 7.46 3.76 5.5 3.76c-1.9 0-3.61 1.44-3.61 3.7 0 2.26 1.65 3.69 3.63 3.69zm7.57 0c1.99 0 3.01-1.32 3.28-2.41l-1.29-.39c-.19.66-.78 1.45-1.99 1.45-1.14 0-2.2-.83-2.2-2.34 0-1.61 1.12-2.37 2.18-2.37 1.23 0 1.78.75 1.95 1.43l1.3-.41c-.28-1.15-1.29-2.35-3.25-2.35-1.9 0-3.61 1.44-3.61 3.7 0 2.26 1.65 3.69 3.63 3.69z" fill-rule="evenodd" fill-opacity=".5"/></symbol><symbol id="plyr-captions-on" viewBox="0 0 18 18"><path d="M1 1c-.6 0-1 .4-1 1v11c0 .6.4 1 1 1h4.6l2.7 2.7c.2.2.4.3.7.3.3 0 .5-.1.7-.3l2.7-2.7H17c.6 0 1-.4 1-1V2c0-.6-.4-1-1-1H1zm4.52 10.15c1.99 0 3.01-1.32 3.28-2.41l-1.29-.39c-.19.66-.78 1.45-1.99 1.45-1.14 0-2.2-.83-2.2-2.34 0-1.61 1.12-2.37 2.18-2.37 1.23 0 1.78.75 1.95 1.43l1.3-.41C8.47 4.96 7.46 3.76 5.5 3.76c-1.9 0-3.61 1.44-3.61 3.7 0 2.26 1.65 3.69 3.63 3.69zm7.57 0c1.99 0 3.01-1.32 3.28-2.41l-1.29-.39c-.19.66-.78 1.45-1.99 1.45-1.14 0-2.2-.83-2.2-2.34 0-1.61 1.12-2.37 2.18-2.37 1.23 0 1.78.75 1.95 1.43l1.3-.41c-.28-1.15-1.29-2.35-3.25-2.35-1.9 0-3.61 1.44-3.61 3.7 0 2.26 1.65 3.69 3.63 3.69z" fill-rule="evenodd"/></symbol><symbol id="plyr-enter-fullscreen" viewBox="0 0 18 18"><path d="M10 3h3.6l-4 4L11 8.4l4-4V8h2V1h-7zM7 9.6l-4 4V10H1v7h7v-2H4.4l4-4z"/></symbol><symbol id="plyr-exit-fullscreen" viewBox="0 0 18 18"><path d="M1 12h3.6l-4 4L2 17.4l4-4V17h2v-7H1zM16 .6l-4 4V1h-2v7h7V6h-3.6l4-4z"/></symbol><symbol id="plyr-fast-forward" viewBox="0 0 18 18"><path d="M7.875 7.171L0 1v16l7.875-6.171V17L18 9 7.875 1z"/></symbol><symbol id="plyr-muted" viewBox="0 0 18 18"><path d="M12.4 12.5l2.1-2.1 2.1 2.1 1.4-1.4L15.9 9 18 6.9l-1.4-1.4-2.1 2.1-2.1-2.1L11 6.9 13.1 9 11 11.1zM3.786 6.008H.714C.286 6.008 0 6.31 0 6.76v4.512c0 .452.286.752.714.752h3.072l4.071 3.858c.5.3 1.143 0 1.143-.602V2.752c0-.601-.643-.977-1.143-.601L3.786 6.008z"/></symbol><symbol id="plyr-pause" viewBox="0 0 18 18"><path d="M6 1H3c-.6 0-1 .4-1 1v14c0 .6.4 1 1 1h3c.6 0 1-.4 1-1V2c0-.6-.4-1-1-1zM12 1c-.6 0-1 .4-1 1v14c0 .6.4 1 1 1h3c.6 0 1-.4 1-1V2c0-.6-.4-1-1-1h-3z"/></symbol><symbol id="plyr-play" viewBox="0 0 18 18"><path d="M15.562 8.1L3.87.225C3.052-.337 2 .225 2 1.125v15.75c0 .9 1.052 1.462 1.87.9L15.563 9.9c.584-.45.584-1.35 0-1.8z"/></symbol><symbol id="plyr-restart" viewBox="0 0 18 18"><path d="M9.7 1.2l.7 6.4 2.1-2.1c1.9 1.9 1.9 5.1 0 7-.9 1-2.2 1.5-3.5 1.5-1.3 0-2.6-.5-3.5-1.5-1.9-1.9-1.9-5.1 0-7 .6-.6 1.4-1.1 2.3-1.3l-.6-1.9C6 2.6 4.9 3.2 4 4.1 1.3 6.8 1.3 11.2 4 14c1.3 1.3 3.1 2 4.9 2 1.9 0 3.6-.7 4.9-2 2.7-2.7 2.7-7.1 0-9.9L16 1.9l-6.3-.7z"/></symbol><symbol id="plyr-rewind" viewBox="0 0 18 18"><path d="M10.125 1L0 9l10.125 8v-6.171L18 17V1l-7.875 6.171z"/></symbol><symbol id="plyr-volume" viewBox="0 0 18 18"><path d="M15.6 3.3c-.4-.4-1-.4-1.4 0-.4.4-.4 1 0 1.4C15.4 5.9 16 7.4 16 9c0 1.6-.6 3.1-1.8 4.3-.4.4-.4 1 0 1.4.2.2.5.3.7.3.3 0 .5-.1.7-.3C17.1 13.2 18 11.2 18 9s-.9-4.2-2.4-5.7z"/><path d="M11.282 5.282a.909.909 0 0 0 0 1.316c.735.735.995 1.458.995 2.402 0 .936-.425 1.917-.995 2.487a.909.909 0 0 0 0 1.316c.145.145.636.262 1.018.156a.725.725 0 0 0 .298-.156C13.773 11.733 14.13 10.16 14.13 9c0-.17-.002-.34-.011-.51-.053-.992-.319-2.005-1.522-3.208a.909.909 0 0 0-1.316 0zM3.786 6.008H.714C.286 6.008 0 6.31 0 6.76v4.512c0 .452.286.752.714.752h3.072l4.071 3.858c.5.3 1.143 0 1.143-.602V2.752c0-.601-.643-.977-1.143-.601L3.786 6.008z"/></symbol></svg>
|
||||
|
After Width: | Height: | Size: 3.7 KiB |
@@ -32,7 +32,6 @@
|
||||
<ul id="treeDemo" class="ztree"></ul>
|
||||
</div>
|
||||
</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.ztree.core.js"></script>
|
||||
<script type="text/javascript">
|
||||
@@ -69,7 +68,7 @@
|
||||
fulls += ",resizable"; // 对于不支持screen属性的浏览器,可以手工进行最大化。 manually
|
||||
}
|
||||
window.open("onlinePreview?url="
|
||||
+ encodeURIComponent("${baseUrl}" + treeNode.fileName), "_blank",fulls);
|
||||
+ encodeURIComponent("${baseUrl}" + treeNode.fileName)+"&fileKey="+treeNode.fileKey, "_blank",fulls);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
</a>
|
||||
</h4>
|
||||
</div>
|
||||
<div id="collapseOne" class="panel-collapse collapse in">
|
||||
<div id="collapseOne" class="panel-collapse collapse">
|
||||
<div class="panel-body">
|
||||
<div>
|
||||
如果你的项目需要接入文件预览项目,达到对docx、excel、ppt、jpg等文件的预览效果,那么通过在你的项目中加入下面的代码就可以
|
||||
@@ -37,10 +37,19 @@
|
||||
};
|
||||
</pre>
|
||||
</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 class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h4 class="panel-title">
|
||||
@@ -65,6 +74,47 @@
|
||||
</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 class="loading_container">
|
||||
@@ -89,7 +139,6 @@
|
||||
</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="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>
|
||||
|
||||
24
jodconverter-web/src/main/resources/web/media.ftl
Normal file
24
jodconverter-web/src/main/resources/web/media.ftl
Normal file
@@ -0,0 +1,24 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>多媒体文件预览</title>
|
||||
<link rel="stylesheet" href="plyr/plyr.css">
|
||||
</head>
|
||||
<style>
|
||||
body{background-color: #262626}
|
||||
.m{ margin-left: auto; margin-right: auto; width:640px; margin-top: 100px; }
|
||||
</style>
|
||||
<body>
|
||||
<div class="m">
|
||||
<video controls>
|
||||
<source src="${mediaUrl}">
|
||||
</video>
|
||||
</div>
|
||||
<script src="plyr/plyr.js"></script>
|
||||
<script>
|
||||
plyr.setup();
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -7,30 +7,24 @@
|
||||
<style>
|
||||
* { margin: 0; padding: 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%;}*/
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>如果图片质量很好,首次加载图片时间可能会有点长,请耐心等待</h1>
|
||||
|
||||
<ul id="dowebok">
|
||||
<#--<li><img id="Imgbox" src="#" width="800px" height="550px"></li>-->
|
||||
|
||||
<li><img id="Imgbox" src="#" width="800px" height="auto"></li>
|
||||
|
||||
<#list imgurls as img>
|
||||
<li><img id="${img}" url="${img}" src="${img}" width="1px" height="1px"></li>
|
||||
</#list>
|
||||
</ul>
|
||||
<script src="js/viewer.min.js"></script>
|
||||
<script>
|
||||
//初始化图片地址
|
||||
window.onload = function () {
|
||||
// document.getElementById("Imgbox").src = getParameter("imgurl");
|
||||
document.getElementById("Imgbox").src =document.getElementById("url").value;
|
||||
}
|
||||
var viewer = new Viewer(document.getElementById('dowebok'), {url: 'src'});
|
||||
viewer.show();
|
||||
var viewer = new Viewer(document.getElementById('dowebok'), {
|
||||
url: 'src',
|
||||
navbar:false
|
||||
});
|
||||
document.getElementById("${currentUrl}").click();
|
||||
</script>
|
||||
<input name="url" value="${imgurl}" type="hidden" id="url" >
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.yudianbank;
|
||||
package cn.keking;
|
||||
|
||||
import org.junit.Test;
|
||||
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">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.yudianbank</groupId>
|
||||
<groupId>cn.keking</groupId>
|
||||
<artifactId>filepreview</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<modules>
|
||||
|
||||
Reference in New Issue
Block a user