Compare commits

...

79 Commits

Author SHA1 Message Date
陈精华
628efec6bd 2.0.2版 2019-05-23 09:53:37 +08:00
陈精华
6d0846a551 修复rocksdb缓存只缓存一条数据问题 2019-05-23 09:53:37 +08:00
陈精华
41d9015023 支持flv视频预览 2019-05-23 09:53:37 +08:00
陈精华
3f40b60c64 支持7z文件预览 2019-05-23 09:53:37 +08:00
陈精华
f244054462 优化读取动态配置 2019-05-23 09:53:37 +08:00
陈精华
37fbc98827 2.0.2迭代 2019-05-23 09:53:37 +08:00
陈精华
795cf3393e 2.0.1版 2019-05-09 15:20:15 +08:00
陈精华
70323b8ee3 pdf预览支持url中有中文或特殊字符 2019-05-09 15:20:15 +08:00
陈精华
67686e99f0 修复excel预览网页乱码问题 2019-05-09 15:20:15 +08:00
陈精华
90554462dc pdf默认预览模式也从配置文件中取,和word ppt统一 2019-05-09 15:20:15 +08:00
kl
ba3084d698 Update README.md 2019-05-09 09:18:54 +08:00
陈精华
3813f75f65 2.0版本 2019-05-07 10:16:26 +08:00
陈精华
a663e99bcd 背景色统一 2019-04-28 13:55:40 +08:00
陈精华
d517ab4e6f 替换pdf和图片预览相互转跳按钮图标 2019-04-28 13:55:40 +08:00
陈精华
29726c11a3 PDF预览也支持图片模式和查看大图 2019-04-28 13:55:40 +08:00
陈精华
336a18ade7 office预览只有PDF转图片 2019-04-26 15:35:43 +08:00
陈精华
53814fe6ab office图片&PDF预览背景色统一 2019-04-26 14:54:09 +08:00
陈精华
50fb586e6f office图片预览打开大图新开窗口 2019-04-26 14:25:35 +08:00
陈精华
a49ee9d726 图片预览可在viewjs中大图预览&翻页 2019-04-26 14:15:08 +08:00
陈精华
ae40d0233b 加入shutdown脚本 2019-04-26 14:15:08 +08:00
陈精华
8f7c13850e 修复调试时只打开jodconverter-web目录里读不到配置文件异常 2019-04-26 14:15:08 +08:00
陈精华
b4d3419797 word、ppt文档新增图片预览模式 2019-04-26 09:04:34 +08:00
陈精华
68aa5db66b RocksDB缓存实现,并更换默认实现为RocksDB 2019-04-23 11:40:44 +08:00
陈精华
7e8de7c754 解压相关 2019-04-18 16:14:58 +08:00
陈精华
f989fbf9c9 优先使用自定义office.home 2019-04-18 11:53:59 +08:00
陈精华
af8ddc10da 文件转换编码默认根据操作系统获取,变为可选配置
文本和多媒体类型添加默认值,变为可选配置
2019-04-17 13:32:14 +08:00
陈精华
3713e6e550 MacOS下office安装路径更新 2019-04-17 13:32:14 +08:00
陈精华
4a7ba07df1 file.Dir变为选配置添加其默认值 2019-04-16 22:10:48 +08:00
陈精华
b625381de3 脚本修改 2019-04-16 16:11:22 +08:00
陈精华
0968ac774a 脚本修改 2019-04-16 16:11:22 +08:00
陈精华
0db6b23bf7 Linux下集成OpenOffice 2019-04-16 16:11:22 +08:00
陈精华
6dc10e8df4 解决tar包office目录层级过长问题 2019-04-16 16:11:22 +08:00
陈精华
9976f0ae99 dev和release区分开 2019-04-16 16:11:22 +08:00
陈精华
55537d3a25 Windows下集成OpenOffice 2019-04-16 16:11:22 +08:00
陈精华
02e116fd8a 完善启动脚本 2019-04-16 16:11:22 +08:00
陈精华
5af3a97720 支持部分配置在运行时动态改变 2019-04-16 16:11:22 +08:00
陈精华
bf08c2c26f 更新记录 2019-04-16 16:11:22 +08:00
陈精华
236ed405f2 启动脚本&配置文件 2019-04-16 16:11:22 +08:00
陈精华
0fb02e3ccb 打包为zip和tar.gz包 2019-04-16 16:11:22 +08:00
陈精华
3dd6609fd6 缓存及队列实现抽象,提供JDK和REDIS两种实现 2019-04-16 16:11:22 +08:00
kl
dd876792c7 Update pom.xml 2018-10-22 11:34:30 +08:00
kl
3b79ef31e8 Update pom.xml
更新jar版本依赖,老版本有安全风险
2018-10-17 09:09:02 +08:00
kl
deb3abcac1 Merge remote-tracking branch 'origin/master' 2018-03-26 17:06:42 +08:00
kl
1c1a945959 使用畅言替换友言社评服务 2018-03-26 17:03:20 +08:00
duanmuxiangxiao
d1c5211d03 viewerjs版本升级release 1.0.0-rc.1 2018-03-26 16:48:02 +08:00
duanmuxiangxiao
d73bc3a031 图片轮播,修改图片切换按钮样式 2018-03-26 13:39:54 +08:00
chenkailing
6f2001b8c9 1.修复不支持文件类型提示时抛异常的问题
2.添加多媒体文件预览支持,如mp4,mp3等文件
2018-03-25 13:26:51 +08:00
kl
378920b773 解决多图片轮播预览数据量大的问题 2018-03-08 14:28:44 +08:00
kl
c78bf0605d 完善多图片轮播预览接口逻辑 2018-03-08 09:51:47 +08:00
kl
e8f0efe1ec Update README.md 2018-01-22 09:18:24 +08:00
kl
f8ebc4e39b Merge remote-tracking branch 'origin/master' 2018-01-19 15:14:38 +08:00
kl
3ecea6ee6c 修复包名异常问题 2018-01-19 15:14:01 +08:00
kl
540e434954 Update README.md 2018-01-19 14:57:08 +08:00
kl
6754232a1d 1.大文件入队提前处理
2.新增addTask文件转换入队接口
3.支持kkFIleView接口和异构系统redis入队
2018-01-19 14:51:18 +08:00
spiritree
ad790f4ae9 Update README.en.md 2018-01-18 09:06:52 +08:00
klboke
05464bbf1c Update README.md 2018-01-17 18:30:21 +08:00
klboke
cbe22c259f Update README.md 2018-01-17 18:16:37 +08:00
klboke
976a071089 Update README.md 2018-01-17 18:02:22 +08:00
kl
bb7407542f Merge remote-tracking branch 'origin/master' 2018-01-17 17:52:08 +08:00
kl
2f86701eea 1.优化代码结构,抽象预览接口服务
2.新增更多图片预览格式支持
2018-01-17 17:51:53 +08:00
klboke
5b5388e51f Update README.en.md 2018-01-17 15:53:21 +08:00
klboke
02957d98fc Update README.md 2018-01-17 15:52:41 +08:00
klboke
e3126f3711 Update README.md 2018-01-17 15:51:34 +08:00
klboke
a04e68c1af Update README.md 2018-01-17 15:50:40 +08:00
ruhui
d4515dfadd 英文文档稍作修改 2018-01-17 15:47:21 +08:00
kl
78de36964d Merge remote-tracking branch 'origin/master' 2018-01-17 14:10:56 +08:00
kl
dcf37b94db 1.修改包结构为cn.keking,
2.新增压缩包内文件名称排序
2018-01-17 14:10:40 +08:00
幻幻Fate
73764b027b 新增英文版README 2018-01-17 14:04:37 +08:00
kl
6d621dc05f 舍弃缩略图,优化多图片预览轮播效率问题 2018-01-16 20:08:19 +08:00
kl
4d6c5501ae Merge remote-tracking branch 'origin/master' 2018-01-16 18:11:55 +08:00
kl
cd8d1e2ba8 修复压缩包内多图片时总是从第一张开始预览的问题 2018-01-16 18:11:43 +08:00
klboke
4731772d38 Update README.md 2018-01-15 18:54:14 +08:00
kl
bc9bb6862b 移除config.js引用 2018-01-15 17:05:54 +08:00
kl
4462bab4fa 移除config.js引用 2018-01-15 17:02:06 +08:00
kl
6d98c972d1 Merge remote-tracking branch 'origin/master' 2018-01-15 16:24:23 +08:00
kl
852abadf8f 首页新增社会化评论框 2018-01-15 16:24:08 +08:00
klboke
2a93f80827 Update README.md 2018-01-12 17:05:13 +08:00
klboke
a8aef1b97b Update README.md 2018-01-12 16:56:45 +08:00
kl
3e5ba7d3ba 支持压缩包内图片轮番预览 2018-01-12 16:52:03 +08:00
3685 changed files with 675127 additions and 802 deletions

1
.gitignore vendored
View File

@@ -28,7 +28,6 @@ nbdist/
.classpath .classpath
.project .project
**/.settings **/.settings
**/bin/
**/build/ **/build/
**/.externalToolBuilders/ **/.externalToolBuilders/
*.iml *.iml

106
README.en.md Normal file
View File

@@ -0,0 +1,106 @@
# file-online-preview
[![GitHub license](https://img.shields.io/github/license/kekingcn/kkFileView.svg?style=flat-square)](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.
URLhttp://file.keking.cn/
### Documentation
1. 中文文档https://gitee.com/kekingcn/file-online-preview/blob/master/README.md
1. English documenthttps://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.
![输入图片说明](https://gitee.com/uploads/images/2017/1219/173717_934cb068_492218.png "屏幕截图.png")
QQ group613025121
### Pictures for some samples
> Excel
![输入图片说明](https://gitee.com/uploads/images/2017/1213/093051_cd55b3ec_492218.png "屏幕截图.png")
> doc
![输入图片说明](https://gitee.com/uploads/images/2017/1213/092350_5b2ecbe5_492218.png "屏幕截图.png")
> zip,rar
![输入图片说明](https://gitee.com/uploads/images/2017/1213/093806_46cede06_492218.png "屏幕截图.png")
> png,jpeg,jpg,etc., support for zooming with mouse scroll, rotation, inversion,etc.
![输入图片说明](https://gitee.com/uploads/images/2017/1213/094335_657a6f60_492218.png "屏幕截图.png")
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(Optional, Unnecessary by default)
- OpenOffice or LibreOffice
1. First step`git pull https://github.com/kekingcn/file-online-preview.git`
2. Second stepconfigure redis address and OpenOffice directorysuch as
```
##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 stepRun the main method of FilePreviewApplication.java.After starting,visit `http://localhost:8012/`.
If everything is ok,you will see the picture below.
![输入图片说明](https://gitee.com/uploads/images/2017/1213/100221_ea15202e_492218.png "屏幕截图.png")
### Changelog
> April 8th 2019
1. Cache and queue implementations abstract, providing JDK and REDIS implementations (REDIS becomes optional dependencies)
2. Provides zip and tar.gz packages, and provides a one-click startup script
> 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 menusupport 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.

View File

@@ -1,9 +1,25 @@
# 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. 支持officepdf等办公文档
1. 支持txt,java,php,py,md,js,css等所有纯文本
1. 支持zip,rar,jar,tar,gzip等压缩包
1. 支持jpgjpegpnggif等图片预览翻转缩放镜像
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. 详细wiki文档https://gitee.com/kekingcn/file-online-preview/wikis/pages
1. 中文文档https://gitee.com/kekingcn/file-online-preview/blob/master/README.md
1. English documenthttps://github.com/kekingcn/kkFileView/blob/master/README.en.md
### 联系我们,加入组织 ### 联系我们,加入组织
> 我们会用心回答解决大家在项目使用中的问题也请大家在提问前至少Google或baidu过珍爱生命远离无效的交流沟通 > 我们会用心回答解决大家在项目使用中的问题也请大家在提问前至少Google或baidu过珍爱生命远离无效的交流沟通
@@ -35,15 +51,13 @@ QQ群号613025121
- redisson - redisson
- jodconverter - jodconverter
> 依赖外部环境 > 依赖外部环境
- redis - redis (可选,默认不用)
- OpenOffice或者LibreOffice - OpenOffice或者LibreOffice
1. 第一步pull项目https://github.com/kekingcn/file-online-preview.git 1. 第一步pull项目https://github.com/kekingcn/file-online-preview.git
2. 第二步:配置redis地址和OpenOffice目录 2. 第二步配置OpenOffice目录
``` ```
#=============================================#spring Redisson配置#===================================#
spring.redisson.address = 192.168.1.204:6379
##资源映射路径(因为jar方式运行的原因) ##资源映射路径(因为jar方式运行的原因)
file.dir = C:\\Users\\yudian\\Desktop\\dev\\ file.dir = C:\\Users\\yudian\\Desktop\\dev\\
## openoffice相关配置 ## openoffice相关配置
@@ -55,6 +69,38 @@ file.dir为转换文件实际存储地址注意要以/结尾
3. 第三步运行FilePreviewApplication的main方法服务启动后访问http://localhost:8012/ 3. 第三步运行FilePreviewApplication的main方法服务启动后访问http://localhost:8012/
会看到如下界面,代表服务启动成功 会看到如下界面,代表服务启动成功
![输入图片说明](https://gitee.com/uploads/images/2017/1213/100221_ea15202e_492218.png "屏幕截图.png") ![输入图片说明](https://gitee.com/uploads/images/2017/1213/100221_ea15202e_492218.png "屏幕截图.png")
### 历史更新记录
> 2019年04月08日
1. 缓存及队列实现抽象提供JDK和REDIS两种实现(REDIS成为可选依赖)
2. 打包方式提供zip和tar.gz包并提供一键启动脚本
> 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 如果这个项目解决了你的实际问题可在https://gitee.com/kekingcn/file-online-preview/issues/IGSBV
登记下,如果节省了你的三方预览服务费用,也愿意支持下的话,可点击下方【捐助】请作者喝杯咖啡,也是非常感谢 登记下,如果节省了你的三方预览服务费用,也愿意支持下的话,可点击下方【捐助】请作者喝杯咖啡,也是非常感谢

View File

@@ -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>

View File

@@ -12,8 +12,11 @@
// //
package org.artofsolving.jodconverter.office; package org.artofsolving.jodconverter.office;
import java.io.BufferedReader;
import java.io.File; import java.io.File;
import java.io.FileReader;
import java.util.Map; import java.util.Map;
import java.util.Properties;
import org.artofsolving.jodconverter.util.PlatformUtils; import org.artofsolving.jodconverter.util.PlatformUtils;
@@ -61,29 +64,40 @@ public class OfficeUtils {
} }
public static File getDefaultOfficeHome() { public static File getDefaultOfficeHome() {
if (System.getProperty("office.home") != null) { Properties properties = new Properties();
return new File(System.getProperty("office.home")); String customizedConfigPath = getCustomizedConfigPath();
try {
BufferedReader bufferedReader = new BufferedReader(new FileReader(customizedConfigPath));
properties.load(bufferedReader);
} catch (Exception e) {}
if (properties.getProperty("office.home") != null) {
return new File(properties.getProperty("office.home"));
} }
if (PlatformUtils.isWindows()) { if (PlatformUtils.isWindows()) {
// %ProgramFiles(x86)% on 64-bit machines; %ProgramFiles% on 32-bit ones // %ProgramFiles(x86)% on 64-bit machines; %ProgramFiles% on 32-bit ones
String homePath = OfficeUtils.getHomePath();
String programFiles = System.getenv("ProgramFiles(x86)"); String programFiles = System.getenv("ProgramFiles(x86)");
if (programFiles == null) { if (programFiles == null) {
programFiles = System.getenv("ProgramFiles"); programFiles = System.getenv("ProgramFiles");
} }
return findOfficeHome( return findOfficeHome(
programFiles + File.separator + "OpenOffice 4", programFiles + File.separator + "OpenOffice 4",
programFiles + File.separator + "LibreOffice 4" programFiles + File.separator + "LibreOffice 4",
homePath + File.separator + "office"
); );
} else if (PlatformUtils.isMac()) { } else if (PlatformUtils.isMac()) {
return findOfficeHome( return findOfficeHome(
"/Applications/OpenOffice.org.app/Contents", "/Applications/OpenOffice.org.app/Contents",
"/Applications/OpenOffice.app/Contents",
"/Applications/LibreOffice.app/Contents" "/Applications/LibreOffice.app/Contents"
); );
} else { } else {
// Linux or other *nix variants // Linux or other *nix variants
return findOfficeHome( return findOfficeHome(
"/opt/openoffice.org3", "/opt/openoffice.org3",
"/opt/openoffice",
"/opt/libreoffice", "/opt/libreoffice",
"/opt/openoffice4",
"/usr/lib/openoffice", "/usr/lib/openoffice",
"/usr/lib/libreoffice" "/usr/lib/libreoffice"
); );
@@ -108,4 +122,29 @@ public class OfficeUtils {
} }
} }
public static String getHomePath() {
String userDir = System.getenv("KKFILEVIEW_BIN_FOLDER");
if (userDir == null) {
userDir = System.getProperty("user.dir");
}
if (userDir.endsWith("bin")) {
userDir = userDir.substring(0, userDir.length() - 4);
} else {
String separator = File.separator;
if (userDir.contains("jodconverter-web")) {
userDir = userDir + separator + "src" + separator + "main";
} else {
userDir = userDir + separator + "jodconverter-web" + separator + "src" + separator + "main";
}
}
return userDir;
}
public static String getCustomizedConfigPath() {
String homePath = OfficeUtils.getHomePath();
String separator = java.io.File.separator;
String configFilePath = homePath + separator + "conf" + separator + "application.properties";
return configFilePath;
}
} }

View File

@@ -10,7 +10,9 @@
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>jodconverter-web</artifactId> <groupId>cn.keking</groupId>
<artifactId>kkFileView</artifactId>
<version>2.0.2</version>
<properties> <properties>
@@ -48,7 +50,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>
@@ -104,13 +106,19 @@
<dependency> <dependency>
<groupId>org.apache.commons</groupId> <groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId> <artifactId>commons-compress</artifactId>
<version>1.9</version> <version>1.18</version>
</dependency> </dependency>
<!-- 解压(rar)--> <!-- 解压(rar)-->
<dependency> <dependency>
<groupId>com.github.junrar</groupId> <groupId>com.github.junrar</groupId>
<artifactId>junrar</artifactId> <artifactId>junrar</artifactId>
<version>0.7</version> <version>4.0.0</version>
</dependency>
<!-- 解压(7z)-->
<dependency>
<groupId>org.tukaani</groupId>
<artifactId>xz</artifactId>
<version>1.8</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>net.sourceforge.jchardet</groupId> <groupId>net.sourceforge.jchardet</groupId>
@@ -149,6 +157,26 @@
<artifactId>guava</artifactId> <artifactId>guava</artifactId>
<version>19.0</version> <version>19.0</version>
</dependency> </dependency>
<dependency>
<groupId>com.googlecode.concurrentlinkedhashmap</groupId>
<artifactId>concurrentlinkedhashmap-lru</artifactId>
<version>1.4.2</version>
</dependency>
<dependency>
<groupId>org.rocksdb</groupId>
<artifactId>rocksdbjni</artifactId>
<version>5.17.2</version>
</dependency>
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>2.0.15</version>
</dependency>
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox-tools</artifactId>
<version>2.0.15</version>
</dependency>
</dependencies> </dependencies>
<build> <build>
<resources> <resources>
@@ -159,12 +187,36 @@
</includes> </includes>
<filtering>true</filtering> <filtering>true</filtering>
</resource> </resource>
<resource>
<directory>src/main/conf</directory>
<excludes>
<exclude>${build.exclude.resource}</exclude>
</excludes>
</resource>
</resources> </resources>
<plugins> <plugins>
<plugin> <plugin>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId> <artifactId>spring-boot-maven-plugin</artifactId>
</plugin> </plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<appendAssemblyId>false</appendAssemblyId>
<descriptors>
<descriptor>src/main/resources/assembly.xml</descriptor>
</descriptors>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins> </plugins>
</build> </build>

View File

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

View File

@@ -0,0 +1,7 @@
@echo off
set "KKFILEVIEW_BIN_FOLDER=%cd%"
cd "%KKFILEVIEW_BIN_FOLDER%"
echo Using KKFILEVIEW_BIN_FOLDER %KKFILEVIEW_BIN_FOLDER%
echo Starting kkFileView...
echo Please check log file for more information
java -Dsun.java2d.cmm=sun.java2d.cmm.kcms.KcmsServiceProvider -Dspring.config.location=..\conf\application.properties -jar kkFileView-2.0.2.jar -> ..\log\kkFileView.log

View File

@@ -0,0 +1,30 @@
#!/bin/bash
DIR_HOME=("/opt/openoffice.org3" "/opt/libreoffice" "/opt/openoffice4" "/usr/lib/openoffice" "/usr/lib/libreoffice")
FLAG=
OFFICE_HOME=
KKFILEVIEW_BIN_FOLDER=$(cd "$(dirname "$0")";pwd)
export KKFILEVIEW_BIN_FOLDER=$KKFILEVIEW_BIN_FOLDER
cd $KKFILEVIEW_BIN_FOLDER
echo "Using KKFILEVIEW_BIN_FOLDER $KKFILEVIEW_BIN_FOLDER"
grep 'office\.home' ../conf/application.properties | grep '!^#'
if [ $? -eq 0 ]; then
echo "Using customized office.home"
else
for i in ${DIR_HOME[@]}
do
if [ -f $i"/program/soffice.bin" ]; then
FLAG=true
OFFICE_HOME=${i}
break
fi
done
if [ ! -n "${FLAG}" ]; then
echo "Installing OpenOffice"
sh ../script/install.sh
else
echo "Detected office component has been installed in $OFFICE_HOME"
fi
fi
echo "Starting kkFileView..."
echo "Please check log file for more information"
nohup java -Dsun.java2d.cmm=sun.java2d.cmm.kcms.KcmsServiceProvider -Dspring.config.location=../conf/application.properties -jar kkFileView-2.0.2.jar > ../log/kkFileView.log 2>&1 &

View File

@@ -0,0 +1,39 @@
#######################################不可动态配置,需要重启生效#######################################
server.port = 8012
spring.http.encoding.charset = utf8
## Freemarker 配置
spring.freemarker.template-loader-path = classpath:/web/
spring.freemarker.cache = false
spring.freemarker.charset = UTF-8
spring.freemarker.check-template-location = true
spring.freemarker.content-type = text/html
spring.freemarker.expose-request-attributes = true
spring.freemarker.expose-session-attributes = true
spring.freemarker.request-context-attribute = request
spring.freemarker.suffix = .ftl
server.tomcat.uri-encoding = UTF-8
#文件上传限制
spring.http.multipart.max-request-size=100MB
spring.http.multipart.max-file-size=100MB
#文件资源路径默认为打包根路径下的file目录下
#file.dir = D:\\kkFileview\\
#openoffice home路径
#office.home = C:\\Program Files (x86)\\OpenOffice 4
#缓存实现类型不配默认为内嵌RocksDB实现可配置为redis(type = redis)实现需要配置spring.redisson.address等参数和 JDK 内置对象实现type = jdk,
#cache.type = redis
#redis连接
#spring.redisson.address = 192.168.1.204:6379
#spring.redisson.password = xxx
#######################################可在运行时动态配置#######################################
#文本类型,默认如下,可自定义添加
#simText = txt,html,xml,properties,md,java,py,c,cpp,sql
#多媒体类型,默认如下,可自定义添加
#media = mp3,wav,mp4,flv
#文件转换编码,默认根据操作系统获取
#converted.file.charset = GBK
#office类型文档(word ppt)样式,默认为图片(image)可配置为pdf预览时也有按钮切换
#office.preview.type = pdf

View File

@@ -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();

View File

@@ -0,0 +1,69 @@
package cn.keking.config;
import org.artofsolving.jodconverter.office.OfficeUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.io.File;
/**
* @auther: chenjh
* @time: 2019/4/10 17:22
* @description
*/
@Component
public class ConfigConstants {
private static String[] simText = {};
private static String[] media = {};
private static String convertedFileCharset;
private static String officePreviewType;
private static String fileDir = OfficeUtils.getHomePath() + File.separator + "file" + File.separator;
public static String[] getSimText() {
return simText;
}
public static void setSimText(String[] simText) {
ConfigConstants.simText = simText;
}
public static String[] getMedia() {
return media;
}
public static void setMedia(String[] media) {
ConfigConstants.media = media;
}
public static String getConvertedFileCharset() {
return convertedFileCharset;
}
public static void setConvertedFileCharset(String convertedFileCharset) {
ConfigConstants.convertedFileCharset = convertedFileCharset;
}
public static String getOfficePreviewType() {
return officePreviewType;
}
public static void setOfficePreviewType(String officePreviewType) {
ConfigConstants.officePreviewType = officePreviewType;
}
public static String getFileDir() {
return fileDir;
}
@Value("${file.dir:default}")
public void setFileDir(String fileDir) {
if (!"default".equals(fileDir)) {
if (!fileDir.endsWith(File.separator)) {
fileDir = fileDir + File.separator;
}
ConfigConstants.fileDir = fileDir;
}
}
}

View File

@@ -0,0 +1,71 @@
package cn.keking.config;
import cn.keking.service.impl.OfficeFilePreviewImpl;
import org.artofsolving.jodconverter.office.OfficeUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.Properties;
/**
* @auther: chenjh
* @time: 2019/4/10 16:16
* @description 每隔1s读取并更新一次配置文件
*/
@Component
public class ConfigRefreshComponent {
private static final Logger LOGGER = LoggerFactory.getLogger(ConfigRefreshComponent.class);
public static final String DEFAULT_TXT_TYPE = "txt,html,xml,properties,md,java,py,c,cpp,sql";
public static final String DEFAULT_MEDIA_TYPE = "mp3,wav,mp4,flv";
@PostConstruct
void refresh() {
Thread configRefreshThread = new Thread(new ConfigRefreshThread());
configRefreshThread.start();
}
class ConfigRefreshThread implements Runnable {
@Override
public void run() {
try {
Properties properties = new Properties();
Properties sysProperties = System.getProperties();
String text;
String media;
String convertedFileCharset = sysProperties.getProperty("sun.jnu.encoding");
String[] textArray;
String[] mediaArray;
String officePreviewType;
String configFilePath = OfficeUtils.getCustomizedConfigPath();
while (true) {
FileReader fileReader = new FileReader(configFilePath);
BufferedReader bufferedReader = new BufferedReader(fileReader);
properties.load(bufferedReader);
text = properties.getProperty("simText", DEFAULT_TXT_TYPE);
media = properties.getProperty("media", DEFAULT_MEDIA_TYPE);
convertedFileCharset = properties.getProperty("converted.file.charset", convertedFileCharset);
officePreviewType = properties.getProperty("office.preview.type", OfficeFilePreviewImpl.OFFICE_PREVIEW_TYPE_IMAGE);
textArray = text.split(",");
mediaArray = media.split(",");
ConfigConstants.setSimText(textArray);
ConfigConstants.setMedia(mediaArray);
ConfigConstants.setConvertedFileCharset(convertedFileCharset);
ConfigConstants.setOfficePreviewType(officePreviewType);
bufferedReader.close();
fileReader.close();
Thread.sleep(1000L);
}
} catch (IOException | InterruptedException e) {
LOGGER.error("读取配置文件异常:{}", e);
}
}
}
}

View File

@@ -1,10 +1,9 @@
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.api.RedissonClient;
import org.redisson.client.codec.Codec; import org.redisson.client.codec.Codec;
import org.redisson.config.Config; import org.redisson.config.Config;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
@@ -14,6 +13,7 @@ import org.springframework.util.ClassUtils;
* Created by kl on 2017/09/26. * Created by kl on 2017/09/26.
* redisson 客户端配置 * redisson 客户端配置
*/ */
@ConditionalOnExpression("'${cache.type:default}'.equals('redis')")
@ConfigurationProperties(prefix = "spring.redisson") @ConfigurationProperties(prefix = "spring.redisson")
@Configuration @Configuration
public class RedissonConfig { public class RedissonConfig {
@@ -42,8 +42,8 @@ public class RedissonConfig {
private String codec="org.redisson.codec.JsonJacksonCodec"; private String codec="org.redisson.codec.JsonJacksonCodec";
@Bean(destroyMethod = "shutdown") @Bean
RedissonClient redisson() throws Exception { Config config() throws Exception {
Config config = new Config(); Config config = new Config();
config.useSingleServer().setAddress(address) config.useSingleServer().setAddress(address)
.setConnectionMinimumIdleSize(connectionMinimumIdleSize) .setConnectionMinimumIdleSize(connectionMinimumIdleSize)
@@ -69,7 +69,7 @@ public class RedissonConfig {
config.setThreads(thread); config.setThreads(thread);
config.setEventLoopGroup(new NioEventLoopGroup()); config.setEventLoopGroup(new NioEventLoopGroup());
config.setUseLinuxNativeEpoll(false); config.setUseLinuxNativeEpoll(false);
return Redisson.create(config); return config;
} }
public int getThread() { public int getThread() {

View File

@@ -0,0 +1,28 @@
package cn.keking.config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
/**
* @auther: chenjh
* @time: 2019/4/16 20:04
* @description
*/
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
private final static Logger LOGGER = LoggerFactory.getLogger(WebConfig.class);
/**
* 访问外部文件配置
*/
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
String filePath = ConfigConstants.getFileDir();
LOGGER.info("Add resource locations: {}", filePath);
registry.addResourceHandler("/**").addResourceLocations("classpath:/META-INF/resources/","classpath:/resources/","classpath:/static/","classpath:/public/","file:" + filePath);
super.addResourceHandlers(registry);
}
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;
}
}

View 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;
}
}

View File

@@ -1,4 +1,4 @@
package com.yudianbank.param; package cn.keking.model;
import java.io.Serializable; import java.io.Serializable;

View File

@@ -0,0 +1,82 @@
package cn.keking.service;
import cn.keking.model.FileAttribute;
import cn.keking.model.FileType;
import cn.keking.service.cache.CacheService;
import cn.keking.utils.FileUtils;
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
CacheService cacheService;
@Autowired
FileUtils fileUtils;
@PostConstruct
public void startTask(){
ExecutorService executorService = Executors.newFixedThreadPool(3);
executorService.submit(new ConverTask(previewFactory,cacheService,fileUtils));
logger.info("队列处理文件转换任务启动完成 ");
}
class ConverTask implements Runnable{
FilePreviewFactory previewFactory;
CacheService cacheService;
FileUtils fileUtils;
public ConverTask(FilePreviewFactory previewFactory, CacheService cacheService,FileUtils fileUtils) {
this.previewFactory = previewFactory;
this.cacheService = cacheService;
this.fileUtils=fileUtils;
}
@Override
public void run() {
while (true) {
try {
String url = cacheService.takeQueueTask();
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();
}
}
}
}
}

View File

@@ -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);
}

View File

@@ -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());
}
}

View File

@@ -0,0 +1,36 @@
package cn.keking.service.cache;
import java.util.List;
import java.util.Map;
/**
* @auther: chenjh
* @time: 2019/4/2 16:45
* @description
*/
public interface CacheService {
final String REDIS_FILE_PREVIEW_PDF_KEY = "converted-preview-pdf-file";
final String REDIS_FILE_PREVIEW_IMGS_KEY = "converted-preview-imgs-file";//压缩包内图片文件集合
final String REDIS_FILE_PREVIEW_PDF_IMGS_KEY = "converted-preview-pdfimgs-file";
final Integer DEFAULT_PDF_CAPACITY = 500000;
final Integer DEFAULT_IMG_CAPACITY = 500000;
final Integer DEFAULT_PDFIMG_CAPACITY = 500000;
void initPDFCachePool(Integer capacity);
void initIMGCachePool(Integer capacity);
public void initPdfImagesCachePool(Integer capacity);
void putPDFCache(String key, String value);
void putImgCache(String key, List<String> value);
Map<String, String> getPDFCache();
String getPDFCache(String key);
Map<String, List<String>> getImgCache();
List<String> getImgCache(String key);
Integer getPdfImageCache(String key);
void putPdfImageCache(String pdfFilePath, int num);
void addQueueTask(String url);
String takeQueueTask() throws InterruptedException;
}

View File

@@ -0,0 +1,128 @@
package cn.keking.service.cache.impl;
import cn.keking.service.cache.CacheService;
import com.googlecode.concurrentlinkedhashmap.ConcurrentLinkedHashMap;
import com.googlecode.concurrentlinkedhashmap.Weighers;
import org.rocksdb.RocksDB;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
/**
* @auther: chenjh
* @time: 2019/4/2 17:21
* @description
*/
@Service
@ConditionalOnExpression("'${cache.type:default}'.equals('jdk')")
public class CacheServiceJDKImpl implements CacheService {
private Map<String, String> pdfCache;
private Map<String, List<String>> imgCache;
private Map<String, Integer> pdfImagesCache;
private static final int QUEUE_SIZE = 500000;
private BlockingQueue blockingQueue = new ArrayBlockingQueue(QUEUE_SIZE);
@Override
public void initPDFCachePool(Integer capacity) {
pdfCache = new ConcurrentLinkedHashMap.Builder<String, String>()
.maximumWeightedCapacity(capacity).weigher(Weighers.singleton())
.build();
}
@Override
public void initIMGCachePool(Integer capacity) {
imgCache = new ConcurrentLinkedHashMap.Builder<String, List<String>>()
.maximumWeightedCapacity(capacity).weigher(Weighers.singleton())
.build();
}
@Override
public void initPdfImagesCachePool(Integer capacity) {
pdfImagesCache = new ConcurrentLinkedHashMap.Builder<String, Integer>()
.maximumWeightedCapacity(capacity).weigher(Weighers.singleton())
.build();
}
@Override
public void putPDFCache(String key, String value) {
if (pdfCache == null) {
initPDFCachePool(CacheService.DEFAULT_PDF_CAPACITY);
}
pdfCache.put(key, value);
}
@Override
public void putImgCache(String key, List<String> value) {
if (imgCache == null) {
initIMGCachePool(CacheService.DEFAULT_IMG_CAPACITY);
}
imgCache.put(key, value);
}
@Override
public Map<String, String> getPDFCache() {
if (pdfCache == null) {
initPDFCachePool(CacheService.DEFAULT_PDF_CAPACITY);
}
return pdfCache;
}
@Override
public String getPDFCache(String key) {
if (pdfCache == null) {
initPDFCachePool(CacheService.DEFAULT_PDF_CAPACITY);
}
return pdfCache.get(key);
}
@Override
public Map<String, List<String>> getImgCache() {
if (imgCache == null) {
initPDFCachePool(CacheService.DEFAULT_IMG_CAPACITY);
}
return imgCache;
}
@Override
public List<String> getImgCache(String key) {
if (imgCache == null) {
initPDFCachePool(CacheService.DEFAULT_IMG_CAPACITY);
}
return imgCache.get(key);
}
@Override
public Integer getPdfImageCache(String key) {
if (pdfImagesCache == null) {
initPdfImagesCachePool(CacheService.DEFAULT_PDFIMG_CAPACITY);
}
return pdfImagesCache.get(key);
}
@Override
public void putPdfImageCache(String pdfFilePath, int num) {
if (pdfImagesCache == null) {
initPdfImagesCachePool(CacheService.DEFAULT_PDFIMG_CAPACITY);
}
pdfImagesCache.put(pdfFilePath, num);
}
@Override
public void addQueueTask(String url) {
blockingQueue.add(url);
}
@Override
public String takeQueueTask() throws InterruptedException {
return String.valueOf(blockingQueue.take());
}
}

View File

@@ -0,0 +1,108 @@
package cn.keking.service.cache.impl;
import cn.keking.service.FileConverQueueTask;
import cn.keking.service.cache.CacheService;
import org.redisson.Redisson;
import org.redisson.api.RBlockingQueue;
import org.redisson.api.RMapCache;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
/**
* @auther: chenjh
* @time: 2019/4/2 18:02
* @description
*/
@ConditionalOnExpression("'${cache.type:default}'.equals('redis')")
@Service
public class CacheServiceRedisImpl implements CacheService {
private Config config;
@Autowired
public CacheServiceRedisImpl(Config config) {
this.config = config;
this.redissonClient = Redisson.create(config);
}
private RedissonClient redissonClient;
@Override
public void initPDFCachePool(Integer capacity) {
}
@Override
public void initIMGCachePool(Integer capacity) {
}
@Override
public void initPdfImagesCachePool(Integer capacity) {
}
@Override
public void putPDFCache(String key, String value) {
RMapCache<String, String> convertedList = redissonClient.getMapCache(REDIS_FILE_PREVIEW_PDF_KEY);
convertedList.fastPut(key, value);
}
@Override
public void putImgCache(String key, List<String> value) {
RMapCache<String, List<String>> convertedList = redissonClient.getMapCache(REDIS_FILE_PREVIEW_IMGS_KEY);
convertedList.fastPut(key, value);
}
@Override
public Map<String, String> getPDFCache() {
return redissonClient.getMapCache(REDIS_FILE_PREVIEW_PDF_KEY);
}
@Override
public String getPDFCache(String key) {
RMapCache<String, String> convertedList = redissonClient.getMapCache(REDIS_FILE_PREVIEW_PDF_KEY);
return convertedList.get(key);
}
@Override
public Map<String, List<String>> getImgCache() {
return redissonClient.getMapCache(REDIS_FILE_PREVIEW_IMGS_KEY);
}
@Override
public List<String> getImgCache(String key) {
RMapCache<String, List<String>> convertedList = redissonClient.getMapCache(REDIS_FILE_PREVIEW_IMGS_KEY);
return convertedList.get(key);
}
@Override
public Integer getPdfImageCache(String key) {
RMapCache<String, Integer> convertedList = redissonClient.getMapCache(REDIS_FILE_PREVIEW_PDF_IMGS_KEY);
return convertedList.get(key);
}
@Override
public void putPdfImageCache(String pdfFilePath, int num) {
RMapCache<String, Integer> convertedList = redissonClient.getMapCache(REDIS_FILE_PREVIEW_PDF_IMGS_KEY);
convertedList.fastPut(pdfFilePath, num);
}
@Override
public void addQueueTask(String url) {
RBlockingQueue<String> queue = redissonClient.getBlockingQueue(FileConverQueueTask.queueTaskName);
queue.addAsync(url);
}
@Override
public String takeQueueTask() throws InterruptedException {
RBlockingQueue<String> queue = redissonClient.getBlockingQueue(FileConverQueueTask.queueTaskName);
return queue.take();
}
}

View File

@@ -0,0 +1,213 @@
package cn.keking.service.cache.impl;
import cn.keking.service.cache.CacheService;
import org.artofsolving.jodconverter.office.OfficeUtils;
import org.rocksdb.RocksDB;
import org.rocksdb.RocksDBException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.stereotype.Service;
import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
/**
* @auther: chenjh
* @time: 2019/4/22 11:02
* @description
*/
@ConditionalOnExpression("'${cache.type:default}'.equals('default')")
@Service
public class CacheServiceRocksDBImpl implements CacheService {
static {
RocksDB.loadLibrary();
}
private static final String DB_PATH = OfficeUtils.getHomePath() + File.separator + "cache";
private static final int QUEUE_SIZE = 500000;
private static final Logger LOGGER = LoggerFactory.getLogger(CacheServiceRocksDBImpl.class);
private BlockingQueue blockingQueue = new ArrayBlockingQueue(QUEUE_SIZE);
private RocksDB db;
{
try {
db = RocksDB.open(DB_PATH);
if (db.get(REDIS_FILE_PREVIEW_PDF_KEY.getBytes()) == null) {
Map<String, String> initPDFCache = new HashMap<>();
db.put(REDIS_FILE_PREVIEW_PDF_KEY.getBytes(), toByteArray(initPDFCache));
}
if (db.get(REDIS_FILE_PREVIEW_IMGS_KEY.getBytes()) == null) {
Map<String, List<String>> initIMGCache = new HashMap<>();
db.put(REDIS_FILE_PREVIEW_IMGS_KEY.getBytes(), toByteArray(initIMGCache));
}
if (db.get(REDIS_FILE_PREVIEW_PDF_IMGS_KEY.getBytes()) == null) {
Map<String, Integer> initPDFIMGCache = new HashMap<>();
db.put(REDIS_FILE_PREVIEW_PDF_IMGS_KEY.getBytes(), toByteArray(initPDFIMGCache));
}
} catch (RocksDBException | IOException e) {
LOGGER.error("Uable to init RocksDB" + e);
}
}
@Override
public void initPDFCachePool(Integer capacity) {
}
@Override
public void initIMGCachePool(Integer capacity) {
}
@Override
public void initPdfImagesCachePool(Integer capacity) {
}
@Override
public void putPDFCache(String key, String value) {
try {
Map<String, String> pdfCacheItem = getPDFCache();
pdfCacheItem.put(key, value);
db.put(REDIS_FILE_PREVIEW_PDF_KEY.getBytes(), toByteArray(pdfCacheItem));
} catch (RocksDBException | IOException e) {
LOGGER.error("Put into RocksDB Exception" + e);
}
}
@Override
public void putImgCache(String key, List<String> value) {
try {
Map<String, List<String>> imgCacheItem = getImgCache();
imgCacheItem.put(key, value);
db.put(REDIS_FILE_PREVIEW_PDF_KEY.getBytes(), toByteArray(imgCacheItem));
} catch (RocksDBException | IOException e) {
LOGGER.error("Put into RocksDB Exception" + e);
}
}
@Override
public Map<String, String> getPDFCache() {
Map<String, String> result = new HashMap<>();
try{
result = (Map<String, String>) toObject(db.get(REDIS_FILE_PREVIEW_PDF_KEY.getBytes()));
} catch (RocksDBException | IOException | ClassNotFoundException e) {
LOGGER.error("Get from RocksDB Exception" + e);
}
return result;
}
@Override
public String getPDFCache(String key) {
String result = "";
try{
Map<String, String> map = (Map<String, String>) toObject(db.get(REDIS_FILE_PREVIEW_PDF_KEY.getBytes()));
result = map.get(key);
} catch (RocksDBException | IOException | ClassNotFoundException e) {
LOGGER.error("Get from RocksDB Exception" + e);
}
return result;
}
@Override
public Map<String, List<String>> getImgCache() {
Map<String, List<String>> result = new HashMap<>();
try{
result = (Map<String, List<String>>) toObject(db.get(REDIS_FILE_PREVIEW_IMGS_KEY.getBytes()));
} catch (RocksDBException | IOException | ClassNotFoundException e) {
LOGGER.error("Get from RocksDB Exception" + e);
}
return result;
}
@Override
public List<String> getImgCache(String key) {
List<String> result = new ArrayList<>();
Map<String, List<String>> map;
try{
map = (Map<String, List<String>>) toObject(db.get(REDIS_FILE_PREVIEW_IMGS_KEY.getBytes()));
result = map.get(key);
} catch (RocksDBException | IOException | ClassNotFoundException e) {
LOGGER.error("Get from RocksDB Exception" + e);
}
return result;
}
public Map<String, Integer> getPdfImageCaches() {
Map<String, Integer> map = new HashMap<>();
try{
map = (Map<String, Integer>) toObject(db.get(REDIS_FILE_PREVIEW_PDF_IMGS_KEY.getBytes()));
} catch (RocksDBException | IOException | ClassNotFoundException e) {
LOGGER.error("Get from RocksDB Exception" + e);
}
return map;
}
@Override
public Integer getPdfImageCache(String key) {
Integer result = 0;
Map<String, Integer> map;
try{
map = (Map<String, Integer>) toObject(db.get(REDIS_FILE_PREVIEW_PDF_IMGS_KEY.getBytes()));
result = map.get(key);
} catch (RocksDBException | IOException | ClassNotFoundException e) {
LOGGER.error("Get from RocksDB Exception" + e);
}
return result;
}
@Override
public void putPdfImageCache(String pdfFilePath, int num) {
try {
Map<String, Integer> pdfImageCacheItem = getPdfImageCaches();
pdfImageCacheItem.put(pdfFilePath, num);
db.put(REDIS_FILE_PREVIEW_PDF_IMGS_KEY.getBytes(), toByteArray(pdfImageCacheItem));
} catch (RocksDBException | IOException e) {
LOGGER.error("Put into RocksDB Exception" + e);
}
}
@Override
public void addQueueTask(String url) {
blockingQueue.add(url);
}
@Override
public String takeQueueTask() throws InterruptedException {
return String.valueOf(blockingQueue.take());
}
private byte[] toByteArray (Object obj) throws IOException {
byte[] bytes = null;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(obj);
oos.flush();
bytes = bos.toByteArray ();
oos.close();
bos.close();
return bytes;
}
private Object toObject (byte[] bytes) throws IOException, ClassNotFoundException {
Object obj = null;
ByteArrayInputStream bis = new ByteArrayInputStream (bytes);
ObjectInputStream ois = new ObjectInputStream (bis);
obj = ois.readObject();
ois.close();
bis.close();
return obj;
}
}

View File

@@ -0,0 +1,68 @@
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("fileType", suffix);
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);
} else if ("7z".equalsIgnoreCase(suffix)) {
fileTree = zipReader.read7zFile(filePath, fileName);
}
if (fileTree != null && !"null".equals(fileTree)) {
fileUtils.addConvertedFile(fileName, fileTree);
}
} else {
fileTree = fileUtils.getConvertedFile(fileName);
}
if (fileTree != null && !"null".equals(fileTree)) {
model.addAttribute("fileTree", fileTree);
return "compress";
} else {
model.addAttribute("fileType", suffix);
model.addAttribute("msg", "压缩文件类型不受支持尝试在压缩的时候选择RAR4格式");
return "fileNotSupported";
}
}
}

View File

@@ -0,0 +1,33 @@
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;
/**
* @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);
FileAttribute fileAttribute=fileUtils.getFileAttribute(url);
String suffix=fileAttribute.getSuffix();
if ("flv".equalsIgnoreCase(suffix)) {
return "flv";
}
return "media";
}
}

View File

@@ -0,0 +1,102 @@
package cn.keking.service.impl;
import cn.keking.config.ConfigConstants;
import cn.keking.model.FileAttribute;
import cn.keking.model.ReturnResponse;
import cn.keking.service.FilePreview;
import cn.keking.utils.DownloadUtils;
import cn.keking.utils.FileUtils;
import cn.keking.utils.OfficeToPdf;
import cn.keking.utils.PdfUtils;
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;
import java.util.List;
/**
* Created by kl on 2018/1/17.
* Content :处理office文件
*/
@Service
public class OfficeFilePreviewImpl implements FilePreview {
@Autowired
FileUtils fileUtils;
@Autowired
PdfUtils pdfUtils;
@Autowired
DownloadUtils downloadUtils;
@Autowired
private OfficeToPdf officeToPdf;
String fileDir = ConfigConstants.getFileDir();
public static final String OFFICE_PREVIEW_TYPE_PDF = "pdf";
public static final String OFFICE_PREVIEW_TYPE_IMAGE = "image";
public static final String OFFICE_PREVIEW_TYPE_ALLIMAGES = "allImages";
@Override
public String filePreviewHandle(String url, Model model) {
// 预览Type参数传了就取参数的没传取系统默认
String officePreviewType = model.asMap().get("officePreviewType") == null ? ConfigConstants.getOfficePreviewType() : model.asMap().get("officePreviewType").toString();
String originUrl = model.asMap().get("originUrl").toString();
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");
String outFilePath = fileDir + pdfName;
// 判断之前是否已转换过,如果转换过,直接返回,否则执行转换
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("fileType", suffix);
model.addAttribute("msg", response.getMsg());
return "fileNotSupported";
}
filePath = response.getContent();
}
if (StringUtils.hasText(outFilePath)) {
officeToPdf.openOfficeToPDF(filePath, outFilePath);
File f = new File(filePath);
if (f.exists()) {
f.delete();
}
if (isHtml) {
// 对转换后的文件进行操作(改变编码方式)
fileUtils.doActionConvertedFile(outFilePath);
}
// 加入缓存
fileUtils.addConvertedFile(pdfName, fileUtils.getRelativePath(outFilePath));
}
}
if (!isHtml && (OFFICE_PREVIEW_TYPE_IMAGE.equals(officePreviewType) || OFFICE_PREVIEW_TYPE_ALLIMAGES.equals(officePreviewType))) {
List<String> imageUrls = pdfUtils.pdf2jpg(outFilePath, pdfName, originUrl);
if (imageUrls == null || imageUrls.size() < 1) {
model.addAttribute("msg", "office转图片异常请联系管理员");
model.addAttribute("fileType",fileAttribute.getSuffix());
return "fileNotSupported";
}
model.addAttribute("imgurls", imageUrls);
model.addAttribute("currentUrl", imageUrls.get(0));
if (OFFICE_PREVIEW_TYPE_IMAGE.equals(officePreviewType)) {
return "officePicture";
} else {
return "picture";
}
}
model.addAttribute("pdfUrl", pdfName);
return isHtml ? "html" : "pdf";
}
}

View File

@@ -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";
}
}

View File

@@ -0,0 +1,74 @@
package cn.keking.service.impl;
import cn.keking.config.ConfigConstants;
import cn.keking.model.FileAttribute;
import cn.keking.model.ReturnResponse;
import cn.keking.service.FilePreview;
import cn.keking.utils.DownloadUtils;
import cn.keking.utils.FileUtils;
import cn.keking.utils.PdfUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.ui.Model;
import java.io.File;
import java.util.List;
/**
* Created by kl on 2018/1/17.
* Content :处理pdf文件
*/
@Service
public class PdfFilePreviewImpl implements FilePreview{
@Autowired
FileUtils fileUtils;
@Autowired
PdfUtils pdfUtils;
@Autowired
DownloadUtils downloadUtils;
String fileDir = ConfigConstants.getFileDir();
@Override
public String filePreviewHandle(String url, Model model) {
FileAttribute fileAttribute=fileUtils.getFileAttribute(url);
String decodedUrl=fileAttribute.getDecodedUrl();
String suffix=fileAttribute.getSuffix();
String fileName=fileAttribute.getName();
String officePreviewType = model.asMap().get("officePreviewType") == null ? ConfigConstants.getOfficePreviewType() : model.asMap().get("officePreviewType").toString();
String originUrl = model.asMap().get("originUrl").toString();
model.addAttribute("pdfUrl", url);
String pdfName = fileName.substring(0, fileName.lastIndexOf(".") + 1) + "pdf";
String outFilePath = fileDir + pdfName;
if (OfficeFilePreviewImpl.OFFICE_PREVIEW_TYPE_IMAGE.equals(officePreviewType) || OfficeFilePreviewImpl.OFFICE_PREVIEW_TYPE_ALLIMAGES.equals(officePreviewType)) {
//当文件不存在时,就去下载
if (!new File(outFilePath).exists()) {
ReturnResponse<String> response = downloadUtils.downLoad(decodedUrl, suffix, fileName);
if (0 != response.getCode()) {
model.addAttribute("fileType", suffix);
model.addAttribute("msg", response.getMsg());
return "fileNotSupported";
}
outFilePath = response.getContent();
}
List<String> imageUrls = pdfUtils.pdf2jpg(outFilePath, pdfName, originUrl);
if (imageUrls == null || imageUrls.size() < 1) {
model.addAttribute("msg", "pdf转图片异常请联系管理员");
model.addAttribute("fileType",fileAttribute.getSuffix());
return "fileNotSupported";
}
model.addAttribute("imgurls", imageUrls);
model.addAttribute("currentUrl", imageUrls.get(0));
if (OfficeFilePreviewImpl.OFFICE_PREVIEW_TYPE_IMAGE.equals(officePreviewType)) {
return "officePicture";
} else {
return "picture";
}
}
return "pdf";
}
}

View File

@@ -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";
}
}

View File

@@ -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";
}
}

View File

@@ -1,10 +1,11 @@
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;
import org.artofsolving.jodconverter.office.OfficeUtils;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@@ -23,8 +24,8 @@ import java.util.Map;
@Component @Component
public class ConverterUtils { public class ConverterUtils {
@Value("${office.home}") // @Value("${office.home}")
String officeHome; // String officeHome;
// OpenOfficeConnection connection; // OpenOfficeConnection connection;
OfficeManager officeManager; OfficeManager officeManager;
@@ -32,6 +33,7 @@ public class ConverterUtils {
public void initOfficeManager() { public void initOfficeManager() {
//// connection = new SocketOpenOfficeConnection(host,8100); //// connection = new SocketOpenOfficeConnection(host,8100);
//// connection.connect(); //// connection.connect();
String officeHome = OfficeUtils.getDefaultOfficeHome().getAbsolutePath();
DefaultOfficeManagerConfiguration configuration = new DefaultOfficeManagerConfiguration(); DefaultOfficeManagerConfiguration configuration = new DefaultOfficeManagerConfiguration();
configuration.setOfficeHome(officeHome); configuration.setOfficeHome(officeHome);
configuration.setPortNumber(8100); configuration.setPortNumber(8100);

View File

@@ -1,4 +1,4 @@
package com.yudianbank.utils; package cn.keking.utils;
import java.io.File; import java.io.File;

View File

@@ -1,11 +1,10 @@
package com.yudianbank.utils; package cn.keking.utils;
import com.yudianbank.param.ReturnResponse; import cn.keking.config.ConfigConstants;
import org.springframework.beans.factory.annotation.Value; import cn.keking.model.ReturnResponse;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.io.*; import java.io.*;
import java.net.*; import java.net.*;
import java.nio.charset.Charset;
import java.util.UUID; import java.util.UUID;
/** /**
@@ -14,8 +13,7 @@ import java.util.UUID;
@Component @Component
public class DownloadUtils { public class DownloadUtils {
@Value("${file.dir}") String fileDir = ConfigConstants.getFileDir();
String fileDir;
/** /**
* 一开始测试的时候发现有些文件没有下载下来而有些可以当时也是郁闷了好一阵但是最终还是不得解 * 一开始测试的时候发现有些文件没有下载下来而有些可以当时也是郁闷了好一阵但是最终还是不得解

View File

@@ -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 文件编码egUTF-8,GBK,GB2312形式(不确定的时候返回可能的字符编码序列)若无则返回null * @return 文件编码egUTF-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 + "]";
} }
} }
} }

View File

@@ -1,14 +1,19 @@
package com.yudianbank.utils; package cn.keking.utils;
import cn.keking.config.ConfigConstants;
import cn.keking.model.FileAttribute;
import cn.keking.model.FileType;
import cn.keking.service.cache.CacheService;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import org.redisson.api.RMapCache; import org.slf4j.Logger;
import org.redisson.api.RedissonClient; 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.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,24 +24,19 @@ 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";
@Autowired @Autowired
RedissonClient redissonClient; CacheService cacheService;
@Value("${file.dir}")
String fileDir;
@Value("${converted.file.charset}") String fileDir = ConfigConstants.getFileDir();
String charset;
/** /**
* 已转换过的文件集合(redis缓存) * 已转换过的文件集合(redis缓存)
* @return * @return
*/ */
public Map<String, String> listConvertedFiles() { public Map<String, String> listConvertedFiles() {
RMapCache<String, String> convertedList = redissonClient.getMapCache(REDIS_FILE_PREVIEW_PDF_KEY); return cacheService.getPDFCache();
return convertedList;
} }
/** /**
@@ -44,10 +44,50 @@ public class FileUtils {
* @return * @return
*/ */
public String getConvertedFile(String key) { public String getConvertedFile(String key) {
RMapCache<String, String> convertedList = redissonClient.getMapCache(REDIS_FILE_PREVIEW_PDF_KEY); return cacheService.getPDFCache(key);
return convertedList.get(key);
} }
/**
* 已将pdf转换成图片的图片本地路径
* @param key pdf本地路径
* @return
*/
public Integer getConvertedPdfImage(String key) {
return cacheService.getPdfImageCache(key);
}
/**
* 查看文件类型(防止参数中存在.点号或者其他特殊字符所以先抽取文件名然后再获取文件类型)
*
* @param url
* @return
*/
public FileType typeFromUrl(String url) {
String[] simText = ConfigConstants.getSimText();
String[] media = ConfigConstants.getMedia();
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中剥离出文件名 * 从url中剥离出文件名
* @param url * @param url
@@ -89,6 +129,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;
} }
@@ -125,10 +167,35 @@ public class FileUtils {
} }
public void addConvertedFile(String fileName, String value){ public void addConvertedFile(String fileName, String value){
RMapCache<String, String> convertedList = redissonClient.getMapCache(REDIS_FILE_PREVIEW_PDF_KEY); cacheService.putPDFCache(fileName, value);
convertedList.fastPut(fileName, value);
} }
/**
*
* @param pdfFilePath
* @param num
*/
public void addConvertedPdfImage(String pdfFilePath, int num){
cacheService.putPdfImageCache(pdfFilePath, num);
}
/**
* 获取redis中压缩包内图片文件
* @param fileKey
* @return
*/
public List getRedisImgUrls(String fileKey){
return cacheService.getImgCache(fileKey);
}
/**
* 设置redis中压缩包内图片文件
* @param fileKey
* @param imgs
*/
public void setRedisImgUrls(String fileKey,List imgs){
cacheService.putImgCache(fileKey, imgs);
}
/** /**
* 判断文件编码格式 * 判断文件编码格式
* @param path * @param path
@@ -161,6 +228,7 @@ public class FileUtils {
*/ */
public void doActionConvertedFile(String outFilePath) { public void doActionConvertedFile(String outFilePath) {
StringBuffer sb = new StringBuffer(); StringBuffer sb = new StringBuffer();
String charset = ConfigConstants.getConvertedFileCharset();
try (InputStream inputStream = new FileInputStream(outFilePath); try (InputStream inputStream = new FileInputStream(outFilePath);
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, charset))){ BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, charset))){
String line; String line;
@@ -181,7 +249,7 @@ public class FileUtils {
} }
// 重新写入文件 // 重新写入文件
try(FileOutputStream fos = new FileOutputStream(outFilePath); try(FileOutputStream fos = new FileOutputStream(outFilePath);
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(fos))){ BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(fos, "utf-8"))) {
writer.write(sb.toString()); writer.write(sb.toString());
} catch (FileNotFoundException e) { } catch (FileNotFoundException e) {
e.printStackTrace(); e.printStackTrace();
@@ -189,4 +257,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);
}
} }

View File

@@ -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;

View File

@@ -0,0 +1,66 @@
package cn.keking.utils;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.ImageType;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.apache.pdfbox.tools.imageio.ImageIOUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@Component
public class PdfUtils {
private final Logger LOGGER = LoggerFactory.getLogger(PdfUtils.class);
@Autowired
FileUtils fileUtils;
public List<String> pdf2jpg(String pdfFilePath, String pdfName, String url) {
List<String> imageUrls = new ArrayList<>();
Integer imageCount = fileUtils.getConvertedPdfImage(pdfFilePath);
String imageFileSuffix = ".jpg";
// https://8个字符 http://7个字符 从这后面开始出现的第一个/就是当前file.Dir下的根目录
int index1 = url.indexOf("/", 8);
String pdfFolder = pdfName.substring(0, pdfName.length() - 4);
String urlPrefix = url.substring(0, index1 + 1) + pdfFolder;
if (imageCount != null && imageCount.intValue() > 0) {
for (int i = 0; i < imageCount ; i++)
imageUrls.add(urlPrefix + "/" + i + imageFileSuffix);
return imageUrls;
}
try {
File pdfFile = new File(pdfFilePath);
PDDocument doc = PDDocument.load(pdfFile);
int pageCount = doc.getNumberOfPages();
PDFRenderer pdfRenderer = new PDFRenderer(doc);
int index = pdfFilePath.lastIndexOf(".");
String folder = pdfFilePath.substring(0, index);
File path = new File(folder);
if (!path.exists()) {
path.mkdirs();
}
String imageFilePath;
for (int pageIndex = 0; pageIndex < pageCount; pageIndex++) {
imageFilePath = folder + File.separator + pageIndex + imageFileSuffix;
BufferedImage image = pdfRenderer.renderImageWithDPI(pageIndex, 105, ImageType.RGB);
ImageIOUtil.writeImage(image, imageFilePath, 105);
imageUrls.add(urlPrefix + "/" + pageIndex + imageFileSuffix);
}
doc.close();
fileUtils.addConvertedPdfImage(pdfFilePath, pageCount);
} catch (IOException e) {
LOGGER.error("Convert pdf to jpg exception", e);
}
return imageUrls;
}
}

View File

@@ -1,12 +1,11 @@
package com.yudianbank.utils; package cn.keking.utils;
import org.springframework.beans.factory.annotation.Value; import cn.keking.config.ConfigConstants;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@Component @Component
public class ShedulerClean { public class ShedulerClean {
@Value("${file.dir}") String fileDir = ConfigConstants.getFileDir();
String fileDir;
// @Scheduled(cron = "0 0 23 * * ?") //每晚23点执行一次 // @Scheduled(cron = "0 0 23 * * ?") //每晚23点执行一次
public void clean(){ public void clean(){

View File

@@ -1,8 +1,8 @@
package com.yudianbank.utils; package cn.keking.utils;
import com.yudianbank.param.ReturnResponse; import cn.keking.config.ConfigConstants;
import cn.keking.model.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.stereotype.Component; import org.springframework.stereotype.Component;
/** /**
@@ -12,8 +12,7 @@ import org.springframework.stereotype.Component;
*/ */
@Component @Component
public class SimTextUtil { public class SimTextUtil {
@Value("${file.dir}") String fileDir = ConfigConstants.getFileDir();
String fileDir;
@Autowired @Autowired
DownloadUtils downloadUtils; DownloadUtils downloadUtils;

View File

@@ -1,5 +1,7 @@
package com.yudianbank.utils; package cn.keking.utils;
import cn.keking.config.ConfigConstants;
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;
@@ -7,16 +9,23 @@ import com.github.junrar.exception.RarException;
import com.github.junrar.rarfile.FileHeader; import com.github.junrar.rarfile.FileHeader;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import org.apache.commons.compress.archivers.sevenz.SevenZArchiveEntry;
import org.apache.commons.compress.archivers.sevenz.SevenZFile;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipFile; 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.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,11 +34,11 @@ 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;
@Value("${file.dir}") String fileDir = ConfigConstants.getFileDir();
String fileDir;
ExecutorService executors = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); ExecutorService executors = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
@@ -49,9 +58,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 +84,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 +102,8 @@ public class ZipReader {
} }
} }
/** /**
* 排序zipEntries(对原来列表倒序) * 排序zipEntries(对原来列表倒序)
* @param entries * @param entries
@@ -99,10 +117,12 @@ 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 FileInputStream(new File(filePath)));
List<FileHeader> headers = archive.getFileHeaders(); List<FileHeader> headers = archive.getFileHeaders();
headers = sortedHeaders(headers); headers = sortedHeaders(headers);
String archiveFileName = fileUtils.getFileNameFromPath(filePath); String archiveFileName = fileUtils.getFileNameFromPath(filePath);
@@ -123,11 +143,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();
@@ -137,9 +162,76 @@ public class ZipReader {
return null; return null;
} }
/**
* 解压7z文件
* @param filePath
* @param fileKey
* @return
*/
public String read7zFile(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 {
SevenZFile zipFile = new SevenZFile(new File(filePath));
Iterable<SevenZArchiveEntry> entries = zipFile.getEntries();
// 排序
Enumeration<SevenZArchiveEntry> newEntries = sortSevenZEntries(entries);
List<Map<String, SevenZArchiveEntry>> entriesToBeExtracted = Lists.newArrayList();
while (newEntries.hasMoreElements()){
SevenZArchiveEntry entry = newEntries.nextElement();
String fullName = entry.getName();
int level = fullName.split(archiveSeparator).length;
// 展示名
String originName = getLastFileName(fullName, archiveSeparator);
String childName = level + "_" + originName;
boolean directory = entry.isDirectory();
if (!directory) {
childName = archiveFileName + "_" + originName;
entriesToBeExtracted.add(Collections.singletonMap(childName, entry));
}
String parentName = getLast2FileName(fullName, archiveSeparator, archiveFileName);
parentName = (level-1) + "_" + parentName;
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 SevenZExtractorWorker(entriesToBeExtracted, filePath));
fileUtils.setRedisImgUrls(fileKey,imgUrls);
return new ObjectMapper().writeValueAsString(appender.get(""));
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
/**
* 排序7ZEntries(对原来列表倒序)
* @param entries
*/
private Enumeration<SevenZArchiveEntry> sortSevenZEntries(Iterable<SevenZArchiveEntry> entries) {
List<SevenZArchiveEntry> sortedEntries = Lists.newArrayList();
Iterator<SevenZArchiveEntry> iterator = entries.iterator();
while(iterator.hasNext()){
sortedEntries.add(iterator.next());
}
// Collections.sort(sortedEntries, Comparator.comparingInt(o -> o.getName().length()));
return Collections.enumeration(sortedEntries);
}
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);
@@ -151,10 +243,10 @@ public class ZipReader {
private List<FileHeader> sortedHeaders(List<FileHeader> headers) { private List<FileHeader> sortedHeaders(List<FileHeader> headers) {
List<FileHeader> sortedHeaders = new ArrayList<>(); List<FileHeader> sortedHeaders = new ArrayList<>();
Map<Integer, FileHeader> mapHeaders = new TreeMap<>(); Map<Integer, FileHeader> mapHeaders = new TreeMap<>();
headers.forEach(header -> mapHeaders.put(header.getFileNameW().length(), header)); headers.forEach(header -> mapHeaders.put(new Integer(0).equals(header.getFileNameW().length()) ? header.getFileNameString().length() : header.getFileNameW().length(), header));
for (Map.Entry<Integer, FileHeader> entry : mapHeaders.entrySet()){ for (Map.Entry<Integer, FileHeader> entry : mapHeaders.entrySet()){
for (FileHeader header : headers) { for (FileHeader header : headers) {
if (entry.getKey().intValue() == header.getFileNameW().length()) { if (entry.getKey().equals(new Integer(0).equals(header.getFileNameW().length()) ? header.getFileNameString().length() : header.getFileNameW().length())) {
sortedHeaders.add(header); sortedHeaders.add(header);
} }
} }
@@ -204,6 +296,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 +329,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 +342,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;
@@ -335,6 +469,60 @@ public class ZipReader {
} }
} }
/**
* 7z文件抽取线程
*/
class SevenZExtractorWorker implements Runnable {
private List<Map<String, SevenZArchiveEntry>> entriesToBeExtracted;
private String filePath;
public SevenZExtractorWorker(List<Map<String, SevenZArchiveEntry>> entriesToBeExtracted, String filePath) {
this.entriesToBeExtracted = entriesToBeExtracted;
this.filePath = filePath;
}
@Override
public void run() {
System.out.println("解析压缩文件开始《《《《《《《《《《《《《《《《《《《《《《《");
try {
SevenZFile sevenZFile = new SevenZFile(new File(filePath));
SevenZArchiveEntry entry = sevenZFile.getNextEntry();
while (entry != null) {
if (entry.isDirectory()) {
entry = sevenZFile.getNextEntry();
continue;
}
String childName = "default_file";
SevenZArchiveEntry entry1 = null;
for (Map<String, SevenZArchiveEntry> entryMap : entriesToBeExtracted) {
childName = entryMap.keySet().iterator().next();
entry1 = entryMap.values().iterator().next();
if (entry.getName().equals(entry1.getName())) {
break;
}
}
FileOutputStream out = new FileOutputStream(fileDir + childName);
byte[] content = new byte[(int) entry.getSize()];
sevenZFile.read(content, 0, content.length);
out.write(content);
out.close();
entry = sevenZFile.getNextEntry();
}
sevenZFile.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
if (new File(filePath).exists()) {
new File(filePath).delete();
}
System.out.println("解析压缩文件结束《《《《《《《《《《《《《《《《《《《《《《《");
}
}
/** /**
* Rar文件抽取 * Rar文件抽取
*/ */

View File

@@ -1,13 +1,13 @@
package com.yudianbank.web.controller; package cn.keking.web.controller;
import cn.keking.config.ConfigConstants;
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.model.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.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
@@ -28,8 +28,7 @@ import java.util.UUID;
*/ */
@RestController @RestController
public class FileController { public class FileController {
@Value("${file.dir}") String fileDir = ConfigConstants.getFileDir();
String fileDir;
@Autowired @Autowired
FileUtils fileUtils; FileUtils fileUtils;
String demoDir = "demo"; String demoDir = "demo";

View File

@@ -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;

View File

@@ -0,0 +1,127 @@
package cn.keking.web.controller;
import cn.keking.service.FilePreview;
import cn.keking.service.FilePreviewFactory;
import cn.keking.service.cache.CacheService;
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.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.*;
import java.net.*;
import java.util.Arrays;
import java.util.List;
/**
* @author yudian-it
*/
@Controller
public class OnlinePreviewController {
@Autowired
FilePreviewFactory previewFactory;
@Autowired
CacheService cacheService;
/**
* @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"));
model.addAttribute("officePreviewType", req.getParameter("officePreviewType"));
model.addAttribute("originUrl",req.getRequestURL().toString());
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(new URI(strUrl).toASCIIString());
//打开请求连接
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 | URISyntaxException e) {
e.printStackTrace();
} finally {
if (inputStream != null) {
IOUtils.closeQuietly(inputStream);
}
}
}
/**
* 通过api接口入队
* @param url 请编码后在入队
*/
@GetMapping("/addTask")
@ResponseBody
public String addQueueTask(String url) {
cacheService.addQueueTask(url);
return "success";
}
}

View File

@@ -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());
}
}
}

View File

@@ -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"));
}
}

Some files were not shown because too many files have changed in this diff Show More