Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
S
slm-fileview
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
梁杰芳
slm-fileview
Commits
dcf37b94
Commit
dcf37b94
authored
Jan 17, 2018
by
kl
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
1.修改包结构为cn.keking,
2.新增压缩包内文件名称排序
parent
6d621dc0
Hide whitespace changes
Inline
Side-by-side
Showing
22 changed files
with
2280 additions
and
4 deletions
+2280
-4
pom.xml
jodconverter-core/pom.xml
+1
-1
pom.xml
jodconverter-web/pom.xml
+1
-1
FilePreviewApplication.java
...r-web/src/main/java/cn/keking/FilePreviewApplication.java
+18
-0
RedissonConfig.java
...er-web/src/main/java/cn/keking/config/RedissonConfig.java
+242
-0
ControlDocumentFormatRegistry.java
.../java/cn/keking/extend/ControlDocumentFormatRegistry.java
+211
-0
ChinesePathFilter.java
...eb/src/main/java/cn/keking/filters/ChinesePathFilter.java
+33
-0
FilterConfiguration.java
.../src/main/java/cn/keking/filters/FilterConfiguration.java
+23
-0
ReturnResponse.java
...ter-web/src/main/java/cn/keking/param/ReturnResponse.java
+57
-0
ConverterUtils.java
...ter-web/src/main/java/cn/keking/utils/ConverterUtils.java
+68
-0
DeleteFileUtil.java
...ter-web/src/main/java/cn/keking/utils/DeleteFileUtil.java
+74
-0
DownloadUtils.java
...rter-web/src/main/java/cn/keking/utils/DownloadUtils.java
+198
-0
FileCharsetDetector.java
...eb/src/main/java/cn/keking/utils/FileCharsetDetector.java
+157
-0
FileUtils.java
...onverter-web/src/main/java/cn/keking/utils/FileUtils.java
+238
-0
OfficeToPdf.java
...verter-web/src/main/java/cn/keking/utils/OfficeToPdf.java
+112
-0
ShedulerClean.java
...rter-web/src/main/java/cn/keking/utils/ShedulerClean.java
+16
-0
SimTextUtil.java
...verter-web/src/main/java/cn/keking/utils/SimTextUtil.java
+24
-0
ZipReader.java
...onverter-web/src/main/java/cn/keking/utils/ZipReader.java
+459
-0
FileController.java
...rc/main/java/cn/keking/web/controller/FileController.java
+113
-0
IndexController.java
...c/main/java/cn/keking/web/controller/IndexController.java
+24
-0
OnlinePreviewController.java
...ava/cn/keking/web/controller/OnlinePreviewController.java
+209
-0
FilePreviewApplicationTests.java
...test/java/com/yudianbank/FilePreviewApplicationTests.java
+1
-1
pom.xml
pom.xml
+1
-1
No files found.
jodconverter-core/pom.xml
View file @
dcf37b94
...
...
@@ -3,7 +3,7 @@
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=
"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"
>
<modelVersion>
4.0.0
</modelVersion>
<groupId>
c
om.yudianbank
</groupId>
<groupId>
c
n.keking
</groupId>
<artifactId>
jodconverter-core
</artifactId>
<version>
1.0-SNAPSHOT
</version>
<packaging>
jar
</packaging>
...
...
jodconverter-web/pom.xml
View file @
dcf37b94
...
...
@@ -48,7 +48,7 @@
<scope>
test
</scope>
</dependency>
<dependency>
<groupId>
c
om.yudianbank
</groupId>
<groupId>
c
n.keking
</groupId>
<artifactId>
jodconverter-core
</artifactId>
<version>
1.0-SNAPSHOT
</version>
<exclusions>
...
...
jodconverter-web/src/main/java/cn/keking/FilePreviewApplication.java
0 → 100644
View file @
dcf37b94
package
cn
.
keking
;
import
org.springframework.boot.SpringApplication
;
import
org.springframework.boot.autoconfigure.SpringBootApplication
;
import
org.springframework.context.annotation.ComponentScan
;
import
org.springframework.scheduling.annotation.EnableScheduling
;
import
java.util.Properties
;
@SpringBootApplication
@EnableScheduling
@ComponentScan
(
value
=
"cn.keking.*"
)
public
class
FilePreviewApplication
{
public
static
void
main
(
String
[]
args
)
{
Properties
properties
=
System
.
getProperties
();
System
.
out
.
println
(
properties
.
get
(
"user.dir"
));
SpringApplication
.
run
(
FilePreviewApplication
.
class
,
args
);
}
}
jodconverter-web/src/main/java/cn/keking/config/RedissonConfig.java
0 → 100644
View file @
dcf37b94
package
cn
.
keking
.
config
;
import
io.netty.channel.nio.NioEventLoopGroup
;
import
org.redisson.Redisson
;
import
org.redisson.api.RedissonClient
;
import
org.redisson.client.codec.Codec
;
import
org.redisson.config.Config
;
import
org.springframework.boot.context.properties.ConfigurationProperties
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.util.ClassUtils
;
/**
* Created by kl on 2017/09/26.
* redisson 客户端配置
*/
@ConfigurationProperties
(
prefix
=
"spring.redisson"
)
@Configuration
public
class
RedissonConfig
{
private
String
address
;
private
int
connectionMinimumIdleSize
=
10
;
private
int
idleConnectionTimeout
=
10000
;
private
int
pingTimeout
=
1000
;
private
int
connectTimeout
=
10000
;
private
int
timeout
=
3000
;
private
int
retryAttempts
=
3
;
private
int
retryInterval
=
1500
;
private
int
reconnectionTimeout
=
3000
;
private
int
failedAttempts
=
3
;
private
String
password
=
null
;
private
int
subscriptionsPerConnection
=
5
;
private
String
clientName
=
null
;
private
int
subscriptionConnectionMinimumIdleSize
=
1
;
private
int
subscriptionConnectionPoolSize
=
50
;
private
int
connectionPoolSize
=
64
;
private
int
database
=
0
;
private
boolean
dnsMonitoring
=
false
;
private
int
dnsMonitoringInterval
=
5000
;
private
int
thread
;
//当前处理核数量 * 2
private
String
codec
=
"org.redisson.codec.JsonJacksonCodec"
;
@Bean
(
destroyMethod
=
"shutdown"
)
RedissonClient
redisson
()
throws
Exception
{
Config
config
=
new
Config
();
config
.
useSingleServer
().
setAddress
(
address
)
.
setConnectionMinimumIdleSize
(
connectionMinimumIdleSize
)
.
setConnectionPoolSize
(
connectionPoolSize
)
.
setDatabase
(
database
)
.
setDnsMonitoring
(
dnsMonitoring
)
.
setDnsMonitoringInterval
(
dnsMonitoringInterval
)
.
setSubscriptionConnectionMinimumIdleSize
(
subscriptionConnectionMinimumIdleSize
)
.
setSubscriptionConnectionPoolSize
(
subscriptionConnectionPoolSize
)
.
setSubscriptionsPerConnection
(
subscriptionsPerConnection
)
.
setClientName
(
clientName
)
.
setFailedAttempts
(
failedAttempts
)
.
setRetryAttempts
(
retryAttempts
)
.
setRetryInterval
(
retryInterval
)
.
setReconnectionTimeout
(
reconnectionTimeout
)
.
setTimeout
(
timeout
)
.
setConnectTimeout
(
connectTimeout
)
.
setIdleConnectionTimeout
(
idleConnectionTimeout
)
.
setPingTimeout
(
pingTimeout
)
.
setPassword
(
password
);
Codec
codec
=(
Codec
)
ClassUtils
.
forName
(
getCodec
(),
ClassUtils
.
getDefaultClassLoader
()).
newInstance
();
config
.
setCodec
(
codec
);
config
.
setThreads
(
thread
);
config
.
setEventLoopGroup
(
new
NioEventLoopGroup
());
config
.
setUseLinuxNativeEpoll
(
false
);
return
Redisson
.
create
(
config
);
}
public
int
getThread
()
{
return
thread
;
}
public
void
setThread
(
int
thread
)
{
this
.
thread
=
thread
;
}
public
String
getAddress
()
{
return
address
;
}
public
void
setAddress
(
String
address
)
{
this
.
address
=
address
;
}
public
int
getIdleConnectionTimeout
()
{
return
idleConnectionTimeout
;
}
public
void
setIdleConnectionTimeout
(
int
idleConnectionTimeout
)
{
this
.
idleConnectionTimeout
=
idleConnectionTimeout
;
}
public
int
getPingTimeout
()
{
return
pingTimeout
;
}
public
void
setPingTimeout
(
int
pingTimeout
)
{
this
.
pingTimeout
=
pingTimeout
;
}
public
int
getConnectTimeout
()
{
return
connectTimeout
;
}
public
void
setConnectTimeout
(
int
connectTimeout
)
{
this
.
connectTimeout
=
connectTimeout
;
}
public
int
getTimeout
()
{
return
timeout
;
}
public
void
setTimeout
(
int
timeout
)
{
this
.
timeout
=
timeout
;
}
public
int
getRetryAttempts
()
{
return
retryAttempts
;
}
public
void
setRetryAttempts
(
int
retryAttempts
)
{
this
.
retryAttempts
=
retryAttempts
;
}
public
int
getRetryInterval
()
{
return
retryInterval
;
}
public
void
setRetryInterval
(
int
retryInterval
)
{
this
.
retryInterval
=
retryInterval
;
}
public
int
getReconnectionTimeout
()
{
return
reconnectionTimeout
;
}
public
void
setReconnectionTimeout
(
int
reconnectionTimeout
)
{
this
.
reconnectionTimeout
=
reconnectionTimeout
;
}
public
int
getFailedAttempts
()
{
return
failedAttempts
;
}
public
void
setFailedAttempts
(
int
failedAttempts
)
{
this
.
failedAttempts
=
failedAttempts
;
}
public
String
getPassword
()
{
return
password
;
}
public
void
setPassword
(
String
password
)
{
this
.
password
=
password
;
}
public
int
getSubscriptionsPerConnection
()
{
return
subscriptionsPerConnection
;
}
public
void
setSubscriptionsPerConnection
(
int
subscriptionsPerConnection
)
{
this
.
subscriptionsPerConnection
=
subscriptionsPerConnection
;
}
public
String
getClientName
()
{
return
clientName
;
}
public
void
setClientName
(
String
clientName
)
{
this
.
clientName
=
clientName
;
}
public
int
getSubscriptionConnectionMinimumIdleSize
()
{
return
subscriptionConnectionMinimumIdleSize
;
}
public
void
setSubscriptionConnectionMinimumIdleSize
(
int
subscriptionConnectionMinimumIdleSize
)
{
this
.
subscriptionConnectionMinimumIdleSize
=
subscriptionConnectionMinimumIdleSize
;
}
public
int
getSubscriptionConnectionPoolSize
()
{
return
subscriptionConnectionPoolSize
;
}
public
void
setSubscriptionConnectionPoolSize
(
int
subscriptionConnectionPoolSize
)
{
this
.
subscriptionConnectionPoolSize
=
subscriptionConnectionPoolSize
;
}
public
int
getConnectionMinimumIdleSize
()
{
return
connectionMinimumIdleSize
;
}
public
void
setConnectionMinimumIdleSize
(
int
connectionMinimumIdleSize
)
{
this
.
connectionMinimumIdleSize
=
connectionMinimumIdleSize
;
}
public
int
getConnectionPoolSize
()
{
return
connectionPoolSize
;
}
public
void
setConnectionPoolSize
(
int
connectionPoolSize
)
{
this
.
connectionPoolSize
=
connectionPoolSize
;
}
public
int
getDatabase
()
{
return
database
;
}
public
void
setDatabase
(
int
database
)
{
this
.
database
=
database
;
}
public
boolean
isDnsMonitoring
()
{
return
dnsMonitoring
;
}
public
void
setDnsMonitoring
(
boolean
dnsMonitoring
)
{
this
.
dnsMonitoring
=
dnsMonitoring
;
}
public
int
getDnsMonitoringInterval
()
{
return
dnsMonitoringInterval
;
}
public
void
setDnsMonitoringInterval
(
int
dnsMonitoringInterval
)
{
this
.
dnsMonitoringInterval
=
dnsMonitoringInterval
;
}
public
String
getCodec
()
{
return
codec
;
}
public
void
setCodec
(
String
codec
)
{
this
.
codec
=
codec
;
}
}
jodconverter-web/src/main/java/cn/keking/extend/ControlDocumentFormatRegistry.java
0 → 100644
View file @
dcf37b94
package
cn
.
keking
.
extend
;
import
com.google.common.collect.Maps
;
import
com.sun.star.beans.PropertyValue
;
import
org.artofsolving.jodconverter.document.DocumentFamily
;
import
org.artofsolving.jodconverter.document.DocumentFormat
;
import
org.artofsolving.jodconverter.document.SimpleDocumentFormatRegistry
;
import
java.util.Collections
;
import
java.util.LinkedHashMap
;
import
java.util.Map
;
/**
* 重写了DefaultDocumentFormatRegistry类,因为要添加自定义行为,比如字符编码。。。
* @author yudian-it
* @date 2017/12/5
*/
public
class
ControlDocumentFormatRegistry
extends
SimpleDocumentFormatRegistry
{
public
ControlDocumentFormatRegistry
()
{
DocumentFormat
pdf
=
new
DocumentFormat
(
"Portable Document Format"
,
"pdf"
,
"application/pdf"
);
pdf
.
setStoreProperties
(
DocumentFamily
.
TEXT
,
Collections
.
singletonMap
(
"FilterName"
,
"writer_pdf_Export"
));
pdf
.
setStoreProperties
(
DocumentFamily
.
SPREADSHEET
,
Collections
.
singletonMap
(
"FilterName"
,
"calc_pdf_Export"
));
pdf
.
setStoreProperties
(
DocumentFamily
.
PRESENTATION
,
Collections
.
singletonMap
(
"FilterName"
,
"impress_pdf_Export"
));
pdf
.
setStoreProperties
(
DocumentFamily
.
DRAWING
,
Collections
.
singletonMap
(
"FilterName"
,
"draw_pdf_Export"
));
addFormat
(
pdf
);
DocumentFormat
swf
=
new
DocumentFormat
(
"Macromedia Flash"
,
"swf"
,
"application/x-shockwave-flash"
);
swf
.
setStoreProperties
(
DocumentFamily
.
PRESENTATION
,
Collections
.
singletonMap
(
"FilterName"
,
"impress_flash_Export"
));
swf
.
setStoreProperties
(
DocumentFamily
.
DRAWING
,
Collections
.
singletonMap
(
"FilterName"
,
"draw_flash_Export"
));
addFormat
(
swf
);
// disabled because it's not always available
//DocumentFormat xhtml = new DocumentFormat("XHTML", "xhtml", "application/xhtml+xml");
//xhtml.setStoreProperties(DocumentFamily.TEXT, Collections.singletonMap("FilterName", "XHTML Writer File"));
//xhtml.setStoreProperties(DocumentFamily.SPREADSHEET, Collections.singletonMap("FilterName", "XHTML Calc File"));
//xhtml.setStoreProperties(DocumentFamily.PRESENTATION, Collections.singletonMap("FilterName", "XHTML Impress File"));
//addFormat(xhtml);
DocumentFormat
html
=
new
DocumentFormat
(
"HTML"
,
"html"
,
"text/html"
);
// HTML is treated as Text when supplied as input, but as an output it is also
// available for exporting Spreadsheet and Presentation formats
html
.
setInputFamily
(
DocumentFamily
.
TEXT
);
html
.
setStoreProperties
(
DocumentFamily
.
TEXT
,
Collections
.
singletonMap
(
"FilterName"
,
"HTML (StarWriter)"
));
Map
<
String
,
Object
>
htmlLoadAndStoreProperties
=
new
LinkedHashMap
<
String
,
Object
>();
htmlLoadAndStoreProperties
.
put
(
"FilterName"
,
"HTML (StarCalc)"
);
htmlLoadAndStoreProperties
.
put
(
"FilterOptions"
,
"utf8"
);
html
.
setStoreProperties
(
DocumentFamily
.
SPREADSHEET
,
htmlLoadAndStoreProperties
);
html
.
setStoreProperties
(
DocumentFamily
.
PRESENTATION
,
Collections
.
singletonMap
(
"FilterName"
,
"impress_html_Export"
));
addFormat
(
html
);
DocumentFormat
odt
=
new
DocumentFormat
(
"OpenDocument Text"
,
"odt"
,
"application/vnd.oasis.opendocument.text"
);
odt
.
setInputFamily
(
DocumentFamily
.
TEXT
);
odt
.
setStoreProperties
(
DocumentFamily
.
TEXT
,
Collections
.
singletonMap
(
"FilterName"
,
"writer8"
));
addFormat
(
odt
);
DocumentFormat
sxw
=
new
DocumentFormat
(
"OpenOffice.org 1.0 Text Document"
,
"sxw"
,
"application/vnd.sun.xml.writer"
);
sxw
.
setInputFamily
(
DocumentFamily
.
TEXT
);
sxw
.
setStoreProperties
(
DocumentFamily
.
TEXT
,
Collections
.
singletonMap
(
"FilterName"
,
"StarOffice XML (Writer)"
));
addFormat
(
sxw
);
DocumentFormat
doc
=
new
DocumentFormat
(
"Microsoft Word"
,
"doc"
,
"application/msword"
);
doc
.
setInputFamily
(
DocumentFamily
.
TEXT
);
doc
.
setStoreProperties
(
DocumentFamily
.
TEXT
,
Collections
.
singletonMap
(
"FilterName"
,
"MS Word 97"
));
addFormat
(
doc
);
DocumentFormat
docx
=
new
DocumentFormat
(
"Microsoft Word 2007 XML"
,
"docx"
,
"application/vnd.openxmlformats-officedocument.wordprocessingml.document"
);
docx
.
setInputFamily
(
DocumentFamily
.
TEXT
);
addFormat
(
docx
);
DocumentFormat
rtf
=
new
DocumentFormat
(
"Rich Text Format"
,
"rtf"
,
"text/rtf"
);
rtf
.
setInputFamily
(
DocumentFamily
.
TEXT
);
rtf
.
setStoreProperties
(
DocumentFamily
.
TEXT
,
Collections
.
singletonMap
(
"FilterName"
,
"Rich Text Format"
));
addFormat
(
rtf
);
DocumentFormat
wpd
=
new
DocumentFormat
(
"WordPerfect"
,
"wpd"
,
"application/wordperfect"
);
wpd
.
setInputFamily
(
DocumentFamily
.
TEXT
);
addFormat
(
wpd
);
DocumentFormat
txt
=
new
DocumentFormat
(
"Plain Text"
,
"txt"
,
"text/plain"
);
txt
.
setInputFamily
(
DocumentFamily
.
TEXT
);
Map
<
String
,
Object
>
txtLoadAndStoreProperties
=
new
LinkedHashMap
<
String
,
Object
>();
txtLoadAndStoreProperties
.
put
(
"FilterName"
,
"Text (encoded)"
);
txtLoadAndStoreProperties
.
put
(
"FilterOptions"
,
"utf8"
);
txt
.
setLoadProperties
(
txtLoadAndStoreProperties
);
txt
.
setStoreProperties
(
DocumentFamily
.
TEXT
,
txtLoadAndStoreProperties
);
addFormat
(
txt
);
DocumentFormat
wikitext
=
new
DocumentFormat
(
"MediaWiki wikitext"
,
"wiki"
,
"text/x-wiki"
);
wikitext
.
setStoreProperties
(
DocumentFamily
.
TEXT
,
Collections
.
singletonMap
(
"FilterName"
,
"MediaWiki"
));
//addFormat(wikitext);
DocumentFormat
ods
=
new
DocumentFormat
(
"OpenDocument Spreadsheet"
,
"ods"
,
"application/vnd.oasis.opendocument.spreadsheet"
);
ods
.
setInputFamily
(
DocumentFamily
.
SPREADSHEET
);
ods
.
setStoreProperties
(
DocumentFamily
.
SPREADSHEET
,
Collections
.
singletonMap
(
"FilterName"
,
"calc8"
));
addFormat
(
ods
);
DocumentFormat
sxc
=
new
DocumentFormat
(
"OpenOffice.org 1.0 Spreadsheet"
,
"sxc"
,
"application/vnd.sun.xml.calc"
);
sxc
.
setInputFamily
(
DocumentFamily
.
SPREADSHEET
);
sxc
.
setStoreProperties
(
DocumentFamily
.
SPREADSHEET
,
Collections
.
singletonMap
(
"FilterName"
,
"StarOffice XML (Calc)"
));
addFormat
(
sxc
);
DocumentFormat
xls
=
new
DocumentFormat
(
"Microsoft Excel"
,
"xls"
,
"application/vnd.ms-excel"
);
xls
.
setInputFamily
(
DocumentFamily
.
SPREADSHEET
);
xls
.
setStoreProperties
(
DocumentFamily
.
SPREADSHEET
,
Collections
.
singletonMap
(
"FilterName"
,
"MS Excel 97"
));
addFormat
(
xls
);
DocumentFormat
xlsx
=
new
DocumentFormat
(
"Microsoft Excel 2007 XML"
,
"xlsx"
,
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
);
xlsx
.
setInputFamily
(
DocumentFamily
.
SPREADSHEET
);
addFormat
(
xlsx
);
DocumentFormat
csv
=
new
DocumentFormat
(
"Comma Separated Values"
,
"csv"
,
"text/csv"
);
csv
.
setInputFamily
(
DocumentFamily
.
SPREADSHEET
);
Map
<
String
,
Object
>
csvLoadAndStoreProperties
=
new
LinkedHashMap
<
String
,
Object
>();
csvLoadAndStoreProperties
.
put
(
"FilterName"
,
"Text - txt - csv (StarCalc)"
);
csvLoadAndStoreProperties
.
put
(
"FilterOptions"
,
"44,34,0"
);
// Field Separator: ','; Text Delimiter: '"'
csv
.
setLoadProperties
(
csvLoadAndStoreProperties
);
csv
.
setStoreProperties
(
DocumentFamily
.
SPREADSHEET
,
csvLoadAndStoreProperties
);
addFormat
(
csv
);
DocumentFormat
tsv
=
new
DocumentFormat
(
"Tab Separated Values"
,
"tsv"
,
"text/tab-separated-values"
);
tsv
.
setInputFamily
(
DocumentFamily
.
SPREADSHEET
);
Map
<
String
,
Object
>
tsvLoadAndStoreProperties
=
new
LinkedHashMap
<
String
,
Object
>();
tsvLoadAndStoreProperties
.
put
(
"FilterName"
,
"Text - txt - csv (StarCalc)"
);
tsvLoadAndStoreProperties
.
put
(
"FilterOptions"
,
"9,34,0"
);
// Field Separator: '\t'; Text Delimiter: '"'
tsv
.
setLoadProperties
(
tsvLoadAndStoreProperties
);
tsv
.
setStoreProperties
(
DocumentFamily
.
SPREADSHEET
,
tsvLoadAndStoreProperties
);
addFormat
(
tsv
);
DocumentFormat
odp
=
new
DocumentFormat
(
"OpenDocument Presentation"
,
"odp"
,
"application/vnd.oasis.opendocument.presentation"
);
odp
.
setInputFamily
(
DocumentFamily
.
PRESENTATION
);
odp
.
setStoreProperties
(
DocumentFamily
.
PRESENTATION
,
Collections
.
singletonMap
(
"FilterName"
,
"impress8"
));
addFormat
(
odp
);
DocumentFormat
sxi
=
new
DocumentFormat
(
"OpenOffice.org 1.0 Presentation"
,
"sxi"
,
"application/vnd.sun.xml.impress"
);
sxi
.
setInputFamily
(
DocumentFamily
.
PRESENTATION
);
sxi
.
setStoreProperties
(
DocumentFamily
.
PRESENTATION
,
Collections
.
singletonMap
(
"FilterName"
,
"StarOffice XML (Impress)"
));
addFormat
(
sxi
);
DocumentFormat
ppt
=
new
DocumentFormat
(
"Microsoft PowerPoint"
,
"ppt"
,
"application/vnd.ms-powerpoint"
);
ppt
.
setInputFamily
(
DocumentFamily
.
PRESENTATION
);
ppt
.
setStoreProperties
(
DocumentFamily
.
PRESENTATION
,
Collections
.
singletonMap
(
"FilterName"
,
"MS PowerPoint 97"
));
addFormat
(
ppt
);
DocumentFormat
pptx
=
new
DocumentFormat
(
"Microsoft PowerPoint 2007 XML"
,
"pptx"
,
"application/vnd.openxmlformats-officedocument.presentationml.presentation"
);
pptx
.
setInputFamily
(
DocumentFamily
.
PRESENTATION
);
addFormat
(
pptx
);
DocumentFormat
odg
=
new
DocumentFormat
(
"OpenDocument Drawing"
,
"odg"
,
"application/vnd.oasis.opendocument.graphics"
);
odg
.
setInputFamily
(
DocumentFamily
.
DRAWING
);
odg
.
setStoreProperties
(
DocumentFamily
.
DRAWING
,
Collections
.
singletonMap
(
"FilterName"
,
"draw8"
));
addFormat
(
odg
);
DocumentFormat
svg
=
new
DocumentFormat
(
"Scalable Vector Graphics"
,
"svg"
,
"image/svg+xml"
);
svg
.
setStoreProperties
(
DocumentFamily
.
DRAWING
,
Collections
.
singletonMap
(
"FilterName"
,
"draw_svg_Export"
));
addFormat
(
svg
);
}
/**
* 创建默认的导出属性
* @return
*/
private
PropertyValue
[]
getCommonPropertyValue
()
{
PropertyValue
[]
aFilterData
=
new
PropertyValue
[
11
];
// 不显示文档标题
aFilterData
[
0
]
=
new
PropertyValue
();
aFilterData
[
0
].
Name
=
"DisplayPDFDocumentTitle"
;
aFilterData
[
0
].
Value
=
true
;
// 导出文件编码方式
aFilterData
[
1
]
=
new
PropertyValue
();
aFilterData
[
1
].
Name
=
"Encoding"
;
aFilterData
[
1
].
Value
=
"UTF-8"
;
// 隐藏工具条
aFilterData
[
2
]
=
new
PropertyValue
();
aFilterData
[
2
].
Name
=
"HideViewerToolbar"
;
aFilterData
[
2
].
Value
=
false
;
// 隐藏窗口控制条
aFilterData
[
3
]
=
new
PropertyValue
();
aFilterData
[
3
].
Name
=
"HideViewerWindowControls"
;
aFilterData
[
3
].
Value
=
true
;
// 全屏展示
aFilterData
[
4
]
=
new
PropertyValue
();
aFilterData
[
4
].
Name
=
"OpenInFullScreenMode"
;
aFilterData
[
4
].
Value
=
false
;
// 第一页左边展示
aFilterData
[
5
]
=
new
PropertyValue
();
aFilterData
[
5
].
Name
=
"MathToMathType"
;
aFilterData
[
5
].
Value
=
true
;
// 文档标题内容
aFilterData
[
6
]
=
new
PropertyValue
();
aFilterData
[
6
].
Name
=
"Watermark"
;
aFilterData
[
6
].
Value
=
"KEKING.CN"
;
// 导出文件编码方式
aFilterData
[
7
]
=
new
PropertyValue
();
aFilterData
[
7
].
Name
=
"CharacterSet"
;
aFilterData
[
7
].
Value
=
"UTF-8"
;
// 导出文件编码方式
aFilterData
[
8
]
=
new
PropertyValue
();
aFilterData
[
8
].
Name
=
"Encoding"
;
aFilterData
[
8
].
Value
=
"UTF-8"
;
// 导出文件编码方式
aFilterData
[
9
]
=
new
PropertyValue
();
aFilterData
[
9
].
Name
=
"CharSet"
;
aFilterData
[
9
].
Value
=
"UTF-8"
;
// 导出文件编码方式
aFilterData
[
10
]
=
new
PropertyValue
();
aFilterData
[
10
].
Name
=
"charset"
;
aFilterData
[
10
].
Value
=
"UTF-8"
;
return
aFilterData
;
}
}
jodconverter-web/src/main/java/cn/keking/filters/ChinesePathFilter.java
0 → 100644
View file @
dcf37b94
package
cn
.
keking
.
filters
;
import
javax.servlet.*
;
import
javax.servlet.http.HttpServletRequest
;
import
java.io.IOException
;
/**
*
* @author yudian-it
* @date 2017/11/30
*/
public
class
ChinesePathFilter
implements
Filter
{
@Override
public
void
init
(
FilterConfig
filterConfig
)
throws
ServletException
{
}
@Override
public
void
doFilter
(
ServletRequest
request
,
ServletResponse
response
,
FilterChain
chain
)
throws
IOException
,
ServletException
{
request
.
setCharacterEncoding
(
"UTF-8"
);
response
.
setCharacterEncoding
(
"UTF-8"
);
StringBuilder
pathBuilder
=
new
StringBuilder
();
pathBuilder
.
append
(
request
.
getScheme
()).
append
(
"://"
).
append
(
request
.
getServerName
()).
append
(
":"
)
.
append
(
request
.
getServerPort
()).
append
(((
HttpServletRequest
)
request
).
getContextPath
()).
append
(
"/"
);
request
.
setAttribute
(
"baseUrl"
,
pathBuilder
.
toString
());
chain
.
doFilter
(
request
,
response
);
}
@Override
public
void
destroy
()
{
}
}
jodconverter-web/src/main/java/cn/keking/filters/FilterConfiguration.java
0 → 100644
View file @
dcf37b94
package
cn
.
keking
.
filters
;
import
org.springframework.boot.web.servlet.FilterRegistrationBean
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
/**
*
* @author yudian-it
* @date 2017/11/30
*/
@Configuration
public
class
FilterConfiguration
{
@Bean
public
FilterRegistrationBean
getChinesePathFilter
(){
ChinesePathFilter
filter
=
new
ChinesePathFilter
();
FilterRegistrationBean
registrationBean
=
new
FilterRegistrationBean
();
registrationBean
.
setFilter
(
filter
);
return
registrationBean
;
}
}
jodconverter-web/src/main/java/cn/keking/param/ReturnResponse.java
0 → 100644
View file @
dcf37b94
package
cn
.
keking
.
param
;
import
java.io.Serializable
;
/**
* 接口返回值结构
* @author yudian-it
* @date 2017/11/17
*/
public
class
ReturnResponse
<
T
>
implements
Serializable
{
private
static
final
long
serialVersionUID
=
313975329998789878L
;
/**
* 返回状态
* 0. 成功
* 1. 失败
*/
private
int
code
;
/**
* 返回状态描述
* XXX成功
* XXX失败
*/
private
String
msg
;
private
T
content
;
public
ReturnResponse
(
int
code
,
String
msg
,
T
content
)
{
this
.
code
=
code
;
this
.
msg
=
msg
;
this
.
content
=
content
;
}
public
int
getCode
()
{
return
code
;
}
public
void
setCode
(
int
code
)
{
this
.
code
=
code
;
}
public
String
getMsg
()
{
return
msg
;
}
public
void
setMsg
(
String
msg
)
{
this
.
msg
=
msg
;
}
public
T
getContent
()
{
return
content
;
}
public
void
setContent
(
T
content
)
{
this
.
content
=
content
;
}
}
jodconverter-web/src/main/java/cn/keking/utils/ConverterUtils.java
0 → 100644
View file @
dcf37b94
package
cn
.
keking
.
utils
;
import
com.sun.star.document.UpdateDocMode
;
import
cn.keking.extend.ControlDocumentFormatRegistry
;
import
org.artofsolving.jodconverter.OfficeDocumentConverter
;
import
org.artofsolving.jodconverter.office.DefaultOfficeManagerConfiguration
;
import
org.artofsolving.jodconverter.office.OfficeManager
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.stereotype.Component
;
import
javax.annotation.PostConstruct
;
import
javax.annotation.PreDestroy
;
import
java.nio.charset.Charset
;
import
java.util.HashMap
;
import
java.util.Map
;
/**
* 创建文件转换器
*
* @author yudian-it
* @date 2017/11/13
*/
@Component
public
class
ConverterUtils
{
@Value
(
"${office.home}"
)
String
officeHome
;
// OpenOfficeConnection connection;
OfficeManager
officeManager
;
@PostConstruct
public
void
initOfficeManager
()
{
//// connection = new SocketOpenOfficeConnection(host,8100);
//// connection.connect();
DefaultOfficeManagerConfiguration
configuration
=
new
DefaultOfficeManagerConfiguration
();
configuration
.
setOfficeHome
(
officeHome
);
configuration
.
setPortNumber
(
8100
);
officeManager
=
configuration
.
buildOfficeManager
();
officeManager
.
start
();
// 设置任务执行超时为5分钟
// configuration.setTaskExecutionTimeout(1000 * 60 * 5L);//
// 设置任务队列超时为24小时
// configuration.setTaskQueueTimeout(1000 * 60 * 60 * 24L);//
}
public
OfficeDocumentConverter
getDocumentConverter
()
{
OfficeDocumentConverter
converter
=
new
OfficeDocumentConverter
(
officeManager
,
new
ControlDocumentFormatRegistry
());
converter
.
setDefaultLoadProperties
(
getLoadProperties
());
return
converter
;
}
private
Map
<
String
,?>
getLoadProperties
()
{
Map
<
String
,
Object
>
loadProperties
=
new
HashMap
<>(
10
);
loadProperties
.
put
(
"Hidden"
,
true
);
loadProperties
.
put
(
"ReadOnly"
,
true
);
loadProperties
.
put
(
"UpdateDocMode"
,
UpdateDocMode
.
QUIET_UPDATE
);
loadProperties
.
put
(
"CharacterSet"
,
Charset
.
forName
(
"UTF-8"
).
name
());
return
loadProperties
;
}
@PreDestroy
public
void
destroyOfficeManager
(){
if
(
null
!=
officeManager
&&
officeManager
.
isRunning
())
{
officeManager
.
stop
();
}
}
}
jodconverter-web/src/main/java/cn/keking/utils/DeleteFileUtil.java
0 → 100644
View file @
dcf37b94
package
cn
.
keking
.
utils
;
import
java.io.File
;
public
class
DeleteFileUtil
{
/**
* 删除单个文件
*
* @param fileName
* 要删除的文件的文件名
* @return 单个文件删除成功返回true,否则返回false
*/
public
static
boolean
deleteFile
(
String
fileName
)
{
File
file
=
new
File
(
fileName
);
// 如果文件路径所对应的文件存在,并且是一个文件,则直接删除
if
(
file
.
exists
()
&&
file
.
isFile
())
{
if
(
file
.
delete
())
{
System
.
out
.
println
(
"删除单个文件"
+
fileName
+
"成功!"
);
return
true
;
}
else
{
System
.
out
.
println
(
"删除单个文件"
+
fileName
+
"失败!"
);
return
false
;
}
}
else
{
System
.
out
.
println
(
"删除单个文件失败:"
+
fileName
+
"不存在!"
);
return
false
;
}
}
/**
* 删除目录及目录下的文件
*
* @param dir
* 要删除的目录的文件路径
* @return 目录删除成功返回true,否则返回false
*/
public
static
boolean
deleteDirectory
(
String
dir
)
{
// 如果dir不以文件分隔符结尾,自动添加文件分隔符
if
(!
dir
.
endsWith
(
File
.
separator
))
{
dir
=
dir
+
File
.
separator
;
}
File
dirFile
=
new
File
(
dir
);
// 如果dir对应的文件不存在,或者不是一个目录,则退出
if
((!
dirFile
.
exists
())
||
(!
dirFile
.
isDirectory
()))
{
System
.
out
.
println
(
"删除目录失败:"
+
dir
+
"不存在!"
);
return
false
;
}
boolean
flag
=
true
;
// 删除文件夹中的所有文件包括子目录
File
[]
files
=
dirFile
.
listFiles
();
for
(
int
i
=
0
;
i
<
files
.
length
;
i
++)
{
// 删除子文件
if
(
files
[
i
].
isFile
())
{
flag
=
DeleteFileUtil
.
deleteFile
(
files
[
i
].
getAbsolutePath
());
if
(!
flag
)
break
;
}
// 删除子目录
else
if
(
files
[
i
].
isDirectory
())
{
flag
=
DeleteFileUtil
.
deleteDirectory
(
files
[
i
]
.
getAbsolutePath
());
if
(!
flag
)
break
;
}
}
if
(!
flag
)
{
System
.
out
.
println
(
"删除目录失败!"
);
return
false
;
}
return
true
;
}
}
jodconverter-web/src/main/java/cn/keking/utils/DownloadUtils.java
0 → 100644
View file @
dcf37b94
package
cn
.
keking
.
utils
;
import
cn.keking.param.ReturnResponse
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.stereotype.Component
;
import
java.io.*
;
import
java.net.*
;
import
java.nio.charset.Charset
;
import
java.util.UUID
;
/**
* @author yudian-it
*/
@Component
public
class
DownloadUtils
{
@Value
(
"${file.dir}"
)
String
fileDir
;
/**
* 一开始测试的时候发现有些文件没有下载下来,而有些可以;当时也是郁闷了好一阵,但是最终还是不得解
* 再次测试的时候,通过前台对比url发现,原来参数中有+号特殊字符存在,但是到后之后却变成了空格,突然恍然大悟
* 应该是转义出了问题,url转义中会把+号当成空格来计算,所以才会出现这种情况,遂想要通过整体替换空格为加号,因为url
* 中的参数部分是不会出现空格的,但是文件名中就不好确定了,所以只对url参数部分做替换
* 注: 针对URLEncoder.encode(s,charset)会将空格转成+的情况需要做下面的替换工作
* @param urlAddress
* @param type
* @return
*/
public
ReturnResponse
<
String
>
downLoad
(
String
urlAddress
,
String
type
,
String
fileName
){
ReturnResponse
<
String
>
response
=
new
ReturnResponse
<>(
0
,
"下载成功!!!"
,
""
);
URL
url
=
null
;
try
{
urlAddress
=
replacePlusMark
(
urlAddress
);
urlAddress
=
encodeUrlParam
(
urlAddress
);
// 因为tomcat不能处理'+'号,所以讲'+'号替换成'%20%'
urlAddress
=
urlAddress
.
replaceAll
(
"\\+"
,
"%20"
);
url
=
new
URL
(
urlAddress
);
}
catch
(
MalformedURLException
e
)
{
e
.
printStackTrace
();
}
UUID
uuid
=
UUID
.
randomUUID
();
if
(
null
==
fileName
)
{
fileName
=
uuid
+
"."
+
type
;
}
else
{
// 文件后缀不一致时,以type为准(针对simText【将类txt文件转为txt】)
fileName
=
fileName
.
replace
(
fileName
.
substring
(
fileName
.
lastIndexOf
(
"."
)
+
1
),
type
);
}
String
realPath
=
fileDir
+
fileName
;
File
dirFile
=
new
File
(
fileDir
);
if
(!
dirFile
.
exists
())
{
dirFile
.
mkdirs
();
}
try
{
URLConnection
connection
=
url
.
openConnection
();
InputStream
in
=
connection
.
getInputStream
();
FileOutputStream
os
=
new
FileOutputStream
(
realPath
);
byte
[]
buffer
=
new
byte
[
4
*
1024
];
int
read
;
while
((
read
=
in
.
read
(
buffer
))
>
0
)
{
os
.
write
(
buffer
,
0
,
read
);
}
os
.
close
();
in
.
close
();
response
.
setContent
(
realPath
);
// 同样针对类txt文件,如果成功msg包含的是转换后的文件名
response
.
setMsg
(
fileName
);
// txt转换文件编码为utf8
if
(
"txt"
.
equals
(
type
)){
convertTextPlainFileCharsetToUtf8
(
realPath
);
}
return
response
;
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
response
.
setCode
(
1
);
response
.
setContent
(
null
);
if
(
e
instanceof
FileNotFoundException
)
{
response
.
setMsg
(
"文件不存在!!!"
);
}
else
{
response
.
setMsg
(
e
.
getMessage
());
}
return
response
;
}
}
/**
* 注:可能是原来因为前端通过encodeURI来编码的,因为通过encodeURI编码+会被转成+号(亦即没有转),
* 而通过encodeURIComponent则会转成%2B,这样URLDecoder是可以正确处理的,所以也就没有必要在这里替换了
* 转换url参数部分的空格为加号(因为在url编解码的过程中出现+转为空格的情况)
* @param urlAddress
* @return
*/
private
String
replacePlusMark
(
String
urlAddress
)
{
if
(
urlAddress
.
contains
(
"?"
))
{
String
nonParamStr
=
urlAddress
.
substring
(
0
,
urlAddress
.
indexOf
(
"?"
)
+
1
);
String
paramStr
=
urlAddress
.
substring
(
nonParamStr
.
length
());
return
nonParamStr
+
paramStr
.
replace
(
" "
,
"+"
);
}
return
urlAddress
;
}
/**
* 对最有一个路径进行转码
* @param urlAddress
* http://192.168.2.111:8013/demo/Handle中文.zip
* @return
*/
private
String
encodeUrlParam
(
String
urlAddress
)
{
String
newUrl
=
""
;
try
{
String
path
=
""
;
String
param
=
""
;
if
(
urlAddress
.
contains
(
"?"
))
{
path
=
urlAddress
.
substring
(
0
,
urlAddress
.
indexOf
(
"?"
));
param
=
urlAddress
.
substring
(
urlAddress
.
indexOf
(
"?"
));
}
else
{
path
=
urlAddress
;
}
String
lastPath
=
path
.
substring
(
path
.
lastIndexOf
(
"/"
)
+
1
);
String
leftPath
=
path
.
substring
(
0
,
path
.
lastIndexOf
(
"/"
)
+
1
);
String
encodeLastPath
=
URLEncoder
.
encode
(
lastPath
,
"UTF-8"
);
newUrl
+=
leftPath
+
encodeLastPath
;
if
(
urlAddress
.
contains
(
"?"
))
{
newUrl
+=
param
;
}
}
catch
(
UnsupportedEncodingException
e
)
{
e
.
printStackTrace
();
}
return
newUrl
;
}
/**
* 因为jodConvert2.1不支持ms2013版本的office转换,这里偷懒,尝试看改一下文件类型,让jodConvert2.1去
* 处理ms2013,看结果如何,如果问题很大的话只能采取其他方式,如果没有问题,暂时使用该版本来转换
* @param type
* @return
*/
private
String
dealWithMS2013
(
String
type
)
{
String
newType
=
null
;
switch
(
type
){
case
"docx"
:
newType
=
"doc"
;
break
;
case
"xlsx"
:
newType
=
"doc"
;
break
;
case
"pptx"
:
newType
=
"ppt"
;
break
;
default
:
newType
=
type
;
break
;
}
return
newType
;
}
/**
* 转换文本文件编码为utf8
* 探测源文件编码,探测到编码切不为utf8则进行转码
* @param filePath 文件路径
*/
private
static
void
convertTextPlainFileCharsetToUtf8
(
String
filePath
)
throws
IOException
{
File
sourceFile
=
new
File
(
filePath
);
if
(
sourceFile
.
exists
()
&&
sourceFile
.
isFile
()
&&
sourceFile
.
canRead
())
{
String
encoding
=
null
;
try
{
FileCharsetDetector
.
Observer
observer
=
FileCharsetDetector
.
guessFileEncoding
(
sourceFile
);
// 为准确探测到编码,不适用猜测的编码
encoding
=
observer
.
isFound
()?
observer
.
getEncoding
():
null
;
// 为准确探测到编码,可以考虑使用GBK 大部分文件都是windows系统产生的
}
catch
(
IOException
e
)
{
// 编码探测失败,
e
.
printStackTrace
();
}
if
(
encoding
!=
null
&&
!
"UTF-8"
.
equals
(
encoding
)){
// 不为utf8,进行转码
File
tmpUtf8File
=
new
File
(
filePath
+
".utf8"
);
Writer
writer
=
new
OutputStreamWriter
(
new
FileOutputStream
(
tmpUtf8File
),
"UTF-8"
);
Reader
reader
=
new
BufferedReader
(
new
InputStreamReader
(
new
FileInputStream
(
sourceFile
),
encoding
));
char
[]
buf
=
new
char
[
1024
];
int
read
;
while
((
read
=
reader
.
read
(
buf
))
>
0
){
writer
.
write
(
buf
,
0
,
read
);
}
reader
.
close
();
writer
.
close
();
// 删除源文件
sourceFile
.
delete
();
// 重命名
tmpUtf8File
.
renameTo
(
sourceFile
);
}
}
}
}
jodconverter-web/src/main/java/cn/keking/utils/FileCharsetDetector.java
0 → 100644
View file @
dcf37b94
package
cn
.
keking
.
utils
;
import
java.io.BufferedInputStream
;
import
java.io.File
;
import
java.io.FileInputStream
;
import
java.io.FileNotFoundException
;
import
java.io.IOException
;
import
org.mozilla.intl.chardet.nsDetector
;
import
org.mozilla.intl.chardet.nsICharsetDetectionObserver
;
/**
* 文本文件编码探测工具类
*
* @author HWliao
* @date 2017-12-24
*/
public
class
FileCharsetDetector
{
/**
* 传入一个文件(File)对象,检查文件编码
*
* @param file File对象实例
* @return 文件编码,若无,则返回null
* @throws FileNotFoundException
* @throws IOException
*/
public
static
Observer
guessFileEncoding
(
File
file
)
throws
FileNotFoundException
,
IOException
{
return
guessFileEncoding
(
file
,
new
nsDetector
());
}
/**
* <pre>
* 获取文件的编码
* @param file
* File对象实例
* @param languageHint
* 语言提示区域代码 @see #nsPSMDetector ,取值如下:
* 1 : Japanese
* 2 : Chinese
* 3 : Simplified Chinese
* 4 : Traditional Chinese
* 5 : Korean
* 6 : Dont know(default)
* </pre>
*
* @return 文件编码,eg:UTF-8,GBK,GB2312形式(不确定的时候,返回可能的字符编码序列);若无,则返回null
* @throws FileNotFoundException
* @throws IOException
*/
public
static
Observer
guessFileEncoding
(
File
file
,
int
languageHint
)
throws
FileNotFoundException
,
IOException
{
return
guessFileEncoding
(
file
,
new
nsDetector
(
languageHint
));
}
/**
* 获取文件的编码
*
* @param file
* @param det
* @return
* @throws FileNotFoundException
* @throws IOException
*/
private
static
Observer
guessFileEncoding
(
File
file
,
nsDetector
det
)
throws
FileNotFoundException
,
IOException
{
// new Observer
Observer
observer
=
new
Observer
();
// set Observer
// The Notify() will be called when a matching charset is found.
det
.
Init
(
observer
);
BufferedInputStream
imp
=
new
BufferedInputStream
(
new
FileInputStream
(
file
));
byte
[]
buf
=
new
byte
[
1024
];
int
len
;
boolean
done
=
false
;
boolean
isAscii
=
false
;
while
((
len
=
imp
.
read
(
buf
,
0
,
buf
.
length
))
!=
-
1
)
{
// Check if the stream is only ascii.
isAscii
=
det
.
isAscii
(
buf
,
len
);
if
(
isAscii
)
{
break
;
}
// DoIt if non-ascii and not done yet.
done
=
det
.
DoIt
(
buf
,
len
,
false
);
if
(
done
)
{
break
;
}
}
imp
.
close
();
det
.
DataEnd
();
if
(
isAscii
)
{
observer
.
encoding
=
"ASCII"
;
observer
.
found
=
true
;
}
if
(!
observer
.
isFound
())
{
String
[]
prob
=
det
.
getProbableCharsets
();
// // 这里将可能的字符集组合起来返回
// for (int i = 0; i < prob.length; i++) {
// if (i == 0) {
// encoding = prob[i];
// } else {
// encoding += "," + prob[i];
// }
// }
if
(
prob
.
length
>
0
)
{
// 在没有发现情况下,去第一个可能的编码
observer
.
encoding
=
prob
[
0
];
}
else
{
observer
.
encoding
=
null
;
}
}
return
observer
;
}
/**
* @author liaohongwei
* @Description: 文件字符编码观察者, 但判断出字符编码时候调用
* @date 2016年6月20日 下午2:27:06
*/
public
static
class
Observer
implements
nsICharsetDetectionObserver
{
/**
* @Fields encoding : 字符编码
*/
private
String
encoding
=
null
;
/**
* @Fields found : 是否找到字符集
*/
private
boolean
found
=
false
;
@Override
public
void
Notify
(
String
charset
)
{
this
.
encoding
=
charset
;
this
.
found
=
true
;
}
public
String
getEncoding
()
{
return
encoding
;
}
public
boolean
isFound
()
{
return
found
;
}
@Override
public
String
toString
()
{
return
"Observer [encoding="
+
encoding
+
", found="
+
found
+
"]"
;
}
}
}
jodconverter-web/src/main/java/cn/keking/utils/FileUtils.java
0 → 100644
View file @
dcf37b94
package
cn
.
keking
.
utils
;
import
com.google.common.collect.Lists
;
import
org.redisson.api.RMapCache
;
import
org.redisson.api.RedissonClient
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.stereotype.Component
;
import
java.io.*
;
import
java.nio.charset.Charset
;
import
java.util.Arrays
;
import
java.util.List
;
import
java.util.Map
;
/**
*
* @author yudian-it
* @date 2017/11/13
*/
@Component
public
class
FileUtils
{
final
String
REDIS_FILE_PREVIEW_PDF_KEY
=
"converted-preview-pdf-file"
;
final
String
REDIS_FILE_PREVIEW_IMGS_KEY
=
"converted-preview-imgs-file"
;
//压缩包内图片文件集合
@Autowired
RedissonClient
redissonClient
;
@Value
(
"${file.dir}"
)
String
fileDir
;
@Value
(
"${converted.file.charset}"
)
String
charset
;
@Value
(
"${simText}"
)
String
[]
simText
;
/**
* 已转换过的文件集合(redis缓存)
* @return
*/
public
Map
<
String
,
String
>
listConvertedFiles
()
{
RMapCache
<
String
,
String
>
convertedList
=
redissonClient
.
getMapCache
(
REDIS_FILE_PREVIEW_PDF_KEY
);
return
convertedList
;
}
/**
* 已转换过的文件,根据文件名获取
* @return
*/
public
String
getConvertedFile
(
String
key
)
{
RMapCache
<
String
,
String
>
convertedList
=
redissonClient
.
getMapCache
(
REDIS_FILE_PREVIEW_PDF_KEY
);
return
convertedList
.
get
(
key
);
}
/**
* 查看文件类型(防止参数中存在.点号或者其他特殊字符,所以先抽取文件名,然后再获取文件类型)
*
* @param url
* @return
*/
public
String
typeFromUrl
(
String
url
)
{
String
nonPramStr
=
url
.
substring
(
0
,
url
.
indexOf
(
"?"
)
!=
-
1
?
url
.
indexOf
(
"?"
)
:
url
.
length
());
String
fileName
=
nonPramStr
.
substring
(
nonPramStr
.
lastIndexOf
(
"/"
)
+
1
);
String
fileType
=
fileName
.
substring
(
fileName
.
lastIndexOf
(
"."
)
+
1
);
if
(
listPictureTypes
().
contains
(
fileType
.
toLowerCase
()))
{
fileType
=
"picture"
;
}
if
(
listArchiveTypes
().
contains
(
fileType
.
toLowerCase
()))
{
fileType
=
"compress"
;
}
if
(
listOfficeTypes
().
contains
(
fileType
.
toLowerCase
()))
{
fileType
=
"office"
;
}
if
(
Arrays
.
asList
(
simText
).
contains
(
fileType
.
toLowerCase
()))
{
fileType
=
"simText"
;
}
return
fileType
;
}
/**
* 从url中剥离出文件名
* @param url
* 格式如:http://keking.ufile.ucloud.com.cn/20171113164107_月度绩效表模板(新).xls?UCloudPublicKey=ucloudtangshd@weifenf.com14355492830001993909323&Expires=&Signature=I D1NOFtAJSPT16E6imv6JWuq0k=
* @return
*/
public
String
getFileNameFromURL
(
String
url
)
{
// 因为url的参数中可能会存在/的情况,所以直接url.lastIndexOf("/")会有问题
// 所以先从?处将url截断,然后运用url.lastIndexOf("/")获取文件名
String
noQueryUrl
=
url
.
substring
(
0
,
url
.
indexOf
(
"?"
)
!=
-
1
?
url
.
indexOf
(
"?"
):
url
.
length
());
String
fileName
=
noQueryUrl
.
substring
(
noQueryUrl
.
lastIndexOf
(
"/"
)
+
1
);
return
fileName
;
}
/**
* 获取文件后缀
* @param fileName
* @return
*/
public
String
getSuffixFromFileName
(
String
fileName
)
{
String
suffix
=
fileName
.
substring
(
fileName
.
lastIndexOf
(
"."
));
return
suffix
;
}
/**
* 从路径中获取
* @param path
* 类似这种:C:\Users\yudian-it\Downloads
* @return
*/
public
String
getFileNameFromPath
(
String
path
)
{
return
path
.
substring
(
path
.
lastIndexOf
(
File
.
separator
)
+
1
);
}
public
List
<
String
>
listPictureTypes
(){
List
<
String
>
list
=
Lists
.
newArrayList
();
list
.
add
(
"jpg"
);
list
.
add
(
"jpeg"
);
list
.
add
(
"png"
);
list
.
add
(
"gif"
);
list
.
add
(
"bmp"
);
return
list
;
}
public
List
<
String
>
listArchiveTypes
(){
List
<
String
>
list
=
Lists
.
newArrayList
();
list
.
add
(
"rar"
);
list
.
add
(
"zip"
);
list
.
add
(
"jar"
);
list
.
add
(
"7-zip"
);
list
.
add
(
"tar"
);
list
.
add
(
"gzip"
);
list
.
add
(
"7z"
);
return
list
;
}
public
List
<
String
>
listOfficeTypes
()
{
List
<
String
>
list
=
Lists
.
newArrayList
();
list
.
add
(
"docx"
);
list
.
add
(
"doc"
);
list
.
add
(
"xls"
);
list
.
add
(
"xlsx"
);
list
.
add
(
"ppt"
);
list
.
add
(
"pptx"
);
return
list
;
}
/**
* 获取相对路径
* @param absolutePath
* @return
*/
public
String
getRelativePath
(
String
absolutePath
)
{
return
absolutePath
.
substring
(
fileDir
.
length
());
}
public
void
addConvertedFile
(
String
fileName
,
String
value
){
RMapCache
<
String
,
String
>
convertedList
=
redissonClient
.
getMapCache
(
REDIS_FILE_PREVIEW_PDF_KEY
);
convertedList
.
fastPut
(
fileName
,
value
);
}
/**
* 获取redis中压缩包内图片文件
* @param fileKey
* @return
*/
public
List
getRedisImgUrls
(
String
fileKey
){
RMapCache
<
String
,
List
>
convertedList
=
redissonClient
.
getMapCache
(
REDIS_FILE_PREVIEW_IMGS_KEY
);
return
convertedList
.
get
(
fileKey
);
}
/**
* 设置redis中压缩包内图片文件
* @param fileKey
* @param imgs
*/
public
void
setRedisImgUrls
(
String
fileKey
,
List
imgs
){
RMapCache
<
String
,
List
>
convertedList
=
redissonClient
.
getMapCache
(
REDIS_FILE_PREVIEW_IMGS_KEY
);
convertedList
.
fastPut
(
fileKey
,
imgs
);
}
/**
* 判断文件编码格式
* @param path
* @return
*/
public
String
getFileEncodeUTFGBK
(
String
path
){
String
enc
=
Charset
.
forName
(
"GBK"
).
name
();
File
file
=
new
File
(
path
);
InputStream
in
=
null
;
try
{
in
=
new
FileInputStream
(
file
);
byte
[]
b
=
new
byte
[
3
];
in
.
read
(
b
);
in
.
close
();
if
(
b
[
0
]
==
-
17
&&
b
[
1
]
==
-
69
&&
b
[
2
]
==
-
65
)
{
enc
=
Charset
.
forName
(
"UTF-8"
).
name
();
}
}
catch
(
FileNotFoundException
e
)
{
e
.
printStackTrace
();
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
System
.
out
.
println
(
"文件编码格式为:"
+
enc
);
return
enc
;
}
/**
* 对转换后的文件进行操作(改变编码方式)
* @param outFilePath
*/
public
void
doActionConvertedFile
(
String
outFilePath
)
{
StringBuffer
sb
=
new
StringBuffer
();
try
(
InputStream
inputStream
=
new
FileInputStream
(
outFilePath
);
BufferedReader
reader
=
new
BufferedReader
(
new
InputStreamReader
(
inputStream
,
charset
))){
String
line
;
while
(
null
!=
(
line
=
reader
.
readLine
())){
if
(
line
.
contains
(
"charset=gb2312"
))
{
line
=
line
.
replace
(
"charset=gb2312"
,
"charset=utf-8"
);
}
sb
.
append
(
line
);
}
// 添加sheet控制头
sb
.
append
(
"<script src=\"js/jquery-3.0.0.min.js\" type=\"text/javascript\"></script>"
);
sb
.
append
(
"<script src=\"js/excel.header.js\" type=\"text/javascript\"></script>"
);
sb
.
append
(
"<link rel=\"stylesheet\" href=\"http://cdn.static.runoob.com/libs/bootstrap/3.3.7/css/bootstrap.min.css\">"
);
}
catch
(
FileNotFoundException
e
)
{
e
.
printStackTrace
();
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
// 重新写入文件
try
(
FileOutputStream
fos
=
new
FileOutputStream
(
outFilePath
);
BufferedWriter
writer
=
new
BufferedWriter
(
new
OutputStreamWriter
(
fos
))){
writer
.
write
(
sb
.
toString
());
}
catch
(
FileNotFoundException
e
)
{
e
.
printStackTrace
();
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
}
}
jodconverter-web/src/main/java/cn/keking/utils/OfficeToPdf.java
0 → 100644
View file @
dcf37b94
package
cn
.
keking
.
utils
;
import
org.artofsolving.jodconverter.OfficeDocumentConverter
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Component
;
import
java.io.File
;
/**
* @author yudian-it
*/
@Component
public
class
OfficeToPdf
{
/**
* 获取OpenOffice.org 3的安装目录
*
* @return OpenOffice.org 3的安装目录
*/
@Autowired
ConverterUtils
converterUtils
;
/**
* 使Office2003-2007全部格式的文档(.doc|.docx|.xls|.xlsx|.ppt|.pptx) 转化为pdf文件<br>
*
* @param inputFilePath
* 源文件路径,如:"e:/test.docx"
* @param outputFilePath
* 目标文件路径,如:"e:/test_docx.pdf"
* @return
*/
public
boolean
openOfficeToPDF
(
String
inputFilePath
,
String
outputFilePath
)
{
return
office2pdf
(
inputFilePath
,
outputFilePath
);
}
/**
* 转换文件
*
* @param inputFile
* @param outputFilePath_end
* @param inputFilePath
* @param outputFilePath
* @param converter
*/
public
static
void
converterFile
(
File
inputFile
,
String
outputFilePath_end
,
String
inputFilePath
,
String
outputFilePath
,
OfficeDocumentConverter
converter
)
{
File
outputFile
=
new
File
(
outputFilePath_end
);
// 假如目标路径不存在,则新建该路径
if
(!
outputFile
.
getParentFile
().
exists
())
{
outputFile
.
getParentFile
().
mkdirs
();
}
converter
.
convert
(
inputFile
,
outputFile
);
}
/**
* 使Office2003-2007全部格式的文档(.doc|.docx|.xls|.xlsx|.ppt|.pptx) 转化为pdf文件
*
* @param inputFilePath
* 源文件路径,如:"e:/test.docx"
* @param outputFilePath
* 目标文件路径,如:"e:/test_docx.pdf"
* @return
*/
public
boolean
office2pdf
(
String
inputFilePath
,
String
outputFilePath
)
{
boolean
flag
=
false
;
OfficeDocumentConverter
converter
=
converterUtils
.
getDocumentConverter
();
if
(
null
!=
inputFilePath
)
{
File
inputFile
=
new
File
(
inputFilePath
);
// 判断目标文件路径是否为空
if
(
null
==
outputFilePath
)
{
// 转换后的文件路径
String
outputFilePath_end
=
getOutputFilePath
(
inputFilePath
);
if
(
inputFile
.
exists
())
{
// 找不到源文件, 则返回
converterFile
(
inputFile
,
outputFilePath_end
,
inputFilePath
,
outputFilePath
,
converter
);
flag
=
true
;
}
}
else
{
if
(
inputFile
.
exists
())
{
// 找不到源文件, 则返回
converterFile
(
inputFile
,
outputFilePath
,
inputFilePath
,
outputFilePath
,
converter
);
flag
=
true
;
}
}
// officeManager.stop();
}
else
{
flag
=
false
;
}
return
flag
;
}
/**
* 获取输出文件
*
* @param inputFilePath
* @return
*/
public
static
String
getOutputFilePath
(
String
inputFilePath
)
{
String
outputFilePath
=
inputFilePath
.
replaceAll
(
"."
+
getPostfix
(
inputFilePath
),
".pdf"
);
return
outputFilePath
;
}
/**
* 获取inputFilePath的后缀名,如:"e:/test.pptx"的后缀名为:"pptx"
*
* @param inputFilePath
* @return
*/
public
static
String
getPostfix
(
String
inputFilePath
)
{
return
inputFilePath
.
substring
(
inputFilePath
.
lastIndexOf
(
"."
)
+
1
);
}
}
jodconverter-web/src/main/java/cn/keking/utils/ShedulerClean.java
0 → 100644
View file @
dcf37b94
package
cn
.
keking
.
utils
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.stereotype.Component
;
@Component
public
class
ShedulerClean
{
@Value
(
"${file.dir}"
)
String
fileDir
;
// @Scheduled(cron = "0 0 23 * * ?") //每晚23点执行一次
public
void
clean
(){
System
.
out
.
println
(
"执行一次清空文件夹"
);
DeleteFileUtil
.
deleteDirectory
(
fileDir
);
}
}
jodconverter-web/src/main/java/cn/keking/utils/SimTextUtil.java
0 → 100644
View file @
dcf37b94
package
cn
.
keking
.
utils
;
import
cn.keking.param.ReturnResponse
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.stereotype.Component
;
/**
* 读取类文本文件
* @author yudian-it
* @date 2017/12/13
*/
@Component
public
class
SimTextUtil
{
@Value
(
"${file.dir}"
)
String
fileDir
;
@Autowired
DownloadUtils
downloadUtils
;
public
ReturnResponse
<
String
>
readSimText
(
String
url
,
String
fileName
){
ReturnResponse
<
String
>
response
=
downloadUtils
.
downLoad
(
url
,
"txt"
,
fileName
);
return
response
;
}
}
jodconverter-web/src/main/java/cn/keking/utils/ZipReader.java
0 → 100644
View file @
dcf37b94
package
cn
.
keking
.
utils
;
import
com.fasterxml.jackson.core.JsonProcessingException
;
import
com.fasterxml.jackson.databind.ObjectMapper
;
import
com.github.junrar.Archive
;
import
com.github.junrar.exception.RarException
;
import
com.github.junrar.rarfile.FileHeader
;
import
com.google.common.collect.Lists
;
import
com.google.common.collect.Maps
;
import
org.apache.commons.compress.archivers.zip.ZipArchiveEntry
;
import
org.apache.commons.compress.archivers.zip.ZipFile
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.stereotype.Component
;
import
org.springframework.web.context.request.RequestContextHolder
;
import
java.io.*
;
import
java.math.BigDecimal
;
import
java.text.CollationKey
;
import
java.text.Collator
;
import
java.util.*
;
import
java.util.concurrent.ExecutorService
;
import
java.util.concurrent.Executors
;
import
java.util.regex.Matcher
;
import
java.util.regex.Pattern
;
/**
*
* @author yudian-it
* @date 2017/11/27
*/
@Component
public
class
ZipReader
{
static
Pattern
pattern
=
Pattern
.
compile
(
"^\\d+"
);
@Autowired
FileUtils
fileUtils
;
@Value
(
"${file.dir}"
)
String
fileDir
;
ExecutorService
executors
=
Executors
.
newFixedThreadPool
(
Runtime
.
getRuntime
().
availableProcessors
());
/**
* 读取压缩文件
* 文件压缩到统一目录fileDir下,并且命名使用压缩文件名+文件名因为文件名
* 可能会重复(在系统中对于同一种类型的材料压缩文件内的文件是一样的,如果文件名
* 重复,那么这里会被覆盖[同一个压缩文件中的不同目录中的相同文件名暂时不考虑])
* <b>注:</b>
* <p>
* 文件名命名中的参数的说明:
* 1.archiveName,为避免解压的文件中有重名的文件会彼此覆盖,所以加上了archiveName,因为在ufile中archiveName
* 是不会重复的。
* 2.level,这里层级结构的列表我是通过一个map来构造的,map的key是文件的名字,值是对应的文件,这样每次向map中
* 加入节点的时候都会获取父节点是否存在,存在则会获取父节点的value并将当前节点加入到父节点的childList中(这里利用
* 的是java语言的引用的特性)。
* </p>
* @param filePath
*/
public
String
readZipFile
(
String
filePath
,
String
fileKey
)
{
String
archiveSeparator
=
"/"
;
Map
<
String
,
FileNode
>
appender
=
Maps
.
newHashMap
();
List
imgUrls
=
Lists
.
newArrayList
();
String
baseUrl
=
(
String
)
RequestContextHolder
.
currentRequestAttributes
().
getAttribute
(
"baseUrl"
,
0
);
String
archiveFileName
=
fileUtils
.
getFileNameFromPath
(
filePath
);
try
{
ZipFile
zipFile
=
new
ZipFile
(
filePath
,
fileUtils
.
getFileEncodeUTFGBK
(
filePath
));
Enumeration
<
ZipArchiveEntry
>
entries
=
zipFile
.
getEntries
();
// 排序
entries
=
sortZipEntries
(
entries
);
List
<
Map
<
String
,
ZipArchiveEntry
>>
entriesToBeExtracted
=
Lists
.
newArrayList
();
while
(
entries
.
hasMoreElements
()){
ZipArchiveEntry
entry
=
entries
.
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
;
String
type
=
fileUtils
.
typeFromUrl
(
childName
);
if
(
type
.
equalsIgnoreCase
(
"picture"
)){
//添加图片文件到图片列表
imgUrls
.
add
(
baseUrl
+
childName
);
}
FileNode
node
=
new
FileNode
(
originName
,
childName
,
parentName
,
new
ArrayList
<>(),
directory
,
fileKey
);
addNodes
(
appender
,
parentName
,
node
);
appender
.
put
(
childName
,
node
);
}
// 开启新的线程处理文件解压
executors
.
submit
(
new
ZipExtractorWorker
(
entriesToBeExtracted
,
zipFile
,
filePath
));
fileUtils
.
setRedisImgUrls
(
fileKey
,
imgUrls
);
return
new
ObjectMapper
().
writeValueAsString
(
appender
.
get
(
""
));
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
return
null
;
}
}
/**
* 排序zipEntries(对原来列表倒序)
* @param entries
*/
private
Enumeration
<
ZipArchiveEntry
>
sortZipEntries
(
Enumeration
<
ZipArchiveEntry
>
entries
)
{
List
<
ZipArchiveEntry
>
sortedEntries
=
Lists
.
newArrayList
();
while
(
entries
.
hasMoreElements
()){
sortedEntries
.
add
(
entries
.
nextElement
());
}
Collections
.
sort
(
sortedEntries
,
Comparator
.
comparingInt
(
o
->
o
.
getName
().
length
()));
return
Collections
.
enumeration
(
sortedEntries
);
}
public
String
unRar
(
String
filePath
,
String
fileKey
){
Map
<
String
,
FileNode
>
appender
=
Maps
.
newHashMap
();
List
imgUrls
=
Lists
.
newArrayList
();
String
baseUrl
=
(
String
)
RequestContextHolder
.
currentRequestAttributes
().
getAttribute
(
"baseUrl"
,
0
);
try
{
Archive
archive
=
new
Archive
(
new
File
(
filePath
));
List
<
FileHeader
>
headers
=
archive
.
getFileHeaders
();
headers
=
sortedHeaders
(
headers
);
String
archiveFileName
=
fileUtils
.
getFileNameFromPath
(
filePath
);
List
<
Map
<
String
,
FileHeader
>>
headersToBeExtracted
=
Lists
.
newArrayList
();
for
(
FileHeader
header
:
headers
)
{
String
fullName
;
if
(
header
.
isUnicode
())
{
fullName
=
header
.
getFileNameW
();
}
else
{
fullName
=
header
.
getFileNameString
();
}
// 展示名
String
originName
=
getLastFileName
(
fullName
,
"\\"
);
String
childName
=
originName
;
boolean
directory
=
header
.
isDirectory
();
if
(!
directory
)
{
childName
=
archiveFileName
+
"_"
+
originName
;
headersToBeExtracted
.
add
(
Collections
.
singletonMap
(
childName
,
header
));
}
String
parentName
=
getLast2FileName
(
fullName
,
"\\"
,
archiveFileName
);
String
type
=
fileUtils
.
typeFromUrl
(
childName
);
if
(
type
.
equalsIgnoreCase
(
"picture"
)){
//添加图片文件到图片列表
imgUrls
.
add
(
baseUrl
+
childName
);
}
FileNode
node
=
new
FileNode
(
originName
,
childName
,
parentName
,
new
ArrayList
<>(),
directory
,
fileKey
);
addNodes
(
appender
,
parentName
,
node
);
appender
.
put
(
childName
,
node
);
}
executors
.
submit
(
new
RarExtractorWorker
(
headersToBeExtracted
,
archive
,
filePath
));
fileUtils
.
setRedisImgUrls
(
fileKey
,
imgUrls
);
return
new
ObjectMapper
().
writeValueAsString
(
appender
.
get
(
""
));
}
catch
(
RarException
e
)
{
e
.
printStackTrace
();
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
return
null
;
}
private
void
addNodes
(
Map
<
String
,
FileNode
>
appender
,
String
parentName
,
FileNode
node
)
{
if
(
appender
.
containsKey
(
parentName
))
{
appender
.
get
(
parentName
).
getChildList
().
add
(
node
);
Collections
.
sort
(
appender
.
get
(
parentName
).
getChildList
(),
sortComparator
);
// appender.get(parentName).getChildList().sort((final FileNode h1, final FileNode h2) -> h1.getOriginName().compareTo(h2.getOriginName()));//排序
}
else
{
// 根节点
FileNode
nodeRoot
=
new
FileNode
(
parentName
,
parentName
,
""
,
new
ArrayList
<>(),
true
);
nodeRoot
.
getChildList
().
add
(
node
);
appender
.
put
(
""
,
nodeRoot
);
appender
.
put
(
parentName
,
nodeRoot
);
}
}
private
List
<
FileHeader
>
sortedHeaders
(
List
<
FileHeader
>
headers
)
{
List
<
FileHeader
>
sortedHeaders
=
new
ArrayList
<>();
Map
<
Integer
,
FileHeader
>
mapHeaders
=
new
TreeMap
<>();
headers
.
forEach
(
header
->
mapHeaders
.
put
(
header
.
getFileNameW
().
length
(),
header
));
for
(
Map
.
Entry
<
Integer
,
FileHeader
>
entry
:
mapHeaders
.
entrySet
()){
for
(
FileHeader
header
:
headers
)
{
if
(
entry
.
getKey
().
intValue
()
==
header
.
getFileNameW
().
length
())
{
sortedHeaders
.
add
(
header
);
}
}
}
return
sortedHeaders
;
}
/**
* 获取倒数第二个文件(夹)名
* @param fullName
* @param seperator
* 压缩文件解压后,不同的压缩格式分隔符不一样zip是/,而rar是\
* @param rootName
* 根目录名:如果倒数第二个路径为空,那么赋值为rootName
* @return
*/
private
static
String
getLast2FileName
(
String
fullName
,
String
seperator
,
String
rootName
)
{
if
(
fullName
.
endsWith
(
seperator
))
{
fullName
=
fullName
.
substring
(
0
,
fullName
.
length
()-
1
);
}
// 1.获取剩余部分
int
endIndex
=
fullName
.
lastIndexOf
(
seperator
);
String
leftPath
=
fullName
.
substring
(
0
,
endIndex
==
-
1
?
0
:
endIndex
);
if
(
null
!=
leftPath
&&
leftPath
.
length
()
>
1
)
{
// 2.获取倒数第二个
return
getLastFileName
(
leftPath
,
seperator
);
}
else
{
return
rootName
;
}
}
/**
* 获取最后一个文件(夹)的名字
* @param fullName
* @param seperator
* 压缩文件解压后,不同的压缩格式分隔符不一样zip是/,而rar是\
* @return
*/
private
static
String
getLastFileName
(
String
fullName
,
String
seperator
)
{
if
(
fullName
.
endsWith
(
seperator
))
{
fullName
=
fullName
.
substring
(
0
,
fullName
.
length
()-
1
);
}
String
newName
=
fullName
;
if
(
null
!=
fullName
&&
fullName
.
contains
(
seperator
))
{
newName
=
fullName
.
substring
(
fullName
.
lastIndexOf
(
seperator
)
+
1
);
}
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
;
}
/**
* 文件节点(区分文件上下级)
*/
public
class
FileNode
{
private
String
originName
;
private
String
fileName
;
private
String
parentFileName
;
private
boolean
directory
;
private
String
fileKey
;
//用于图片预览时寻址
private
List
<
FileNode
>
childList
;
public
FileNode
()
{
}
public
FileNode
(
String
originName
,
String
fileName
,
String
parentFileName
,
List
<
FileNode
>
childList
,
boolean
directory
)
{
this
.
originName
=
originName
;
this
.
fileName
=
fileName
;
this
.
parentFileName
=
parentFileName
;
this
.
childList
=
childList
;
this
.
directory
=
directory
;
}
public
FileNode
(
String
originName
,
String
fileName
,
String
parentFileName
,
List
<
FileNode
>
childList
,
boolean
directory
,
String
fileKey
)
{
this
.
originName
=
originName
;
this
.
fileName
=
fileName
;
this
.
parentFileName
=
parentFileName
;
this
.
childList
=
childList
;
this
.
directory
=
directory
;
this
.
fileKey
=
fileKey
;
}
public
String
getFileKey
()
{
return
fileKey
;
}
public
void
setFileKey
(
String
fileKey
)
{
this
.
fileKey
=
fileKey
;
}
public
String
getFileName
()
{
return
fileName
;
}
public
void
setFileName
(
String
fileName
)
{
this
.
fileName
=
fileName
;
}
public
String
getParentFileName
()
{
return
parentFileName
;
}
public
void
setParentFileName
(
String
parentFileName
)
{
this
.
parentFileName
=
parentFileName
;
}
public
List
<
FileNode
>
getChildList
()
{
return
childList
;
}
public
void
setChildList
(
List
<
FileNode
>
childList
)
{
this
.
childList
=
childList
;
}
@Override
public
String
toString
()
{
try
{
return
new
ObjectMapper
().
writeValueAsString
(
this
);
}
catch
(
JsonProcessingException
e
)
{
e
.
printStackTrace
();
return
""
;
}
}
public
String
getOriginName
()
{
return
originName
;
}
public
void
setOriginName
(
String
originName
)
{
this
.
originName
=
originName
;
}
public
boolean
isDirectory
()
{
return
directory
;
}
public
void
setDirectory
(
boolean
directory
)
{
this
.
directory
=
directory
;
}
}
/**
* Zip文件抽取线程
*/
class
ZipExtractorWorker
implements
Runnable
{
private
List
<
Map
<
String
,
ZipArchiveEntry
>>
entriesToBeExtracted
;
private
ZipFile
zipFile
;
private
String
filePath
;
public
ZipExtractorWorker
(
List
<
Map
<
String
,
ZipArchiveEntry
>>
entriesToBeExtracted
,
ZipFile
zipFile
,
String
filePath
)
{
this
.
entriesToBeExtracted
=
entriesToBeExtracted
;
this
.
zipFile
=
zipFile
;
this
.
filePath
=
filePath
;
}
@Override
public
void
run
()
{
System
.
out
.
println
(
"解析压缩文件开始《《《《《《《《《《《《《《《《《《《《《《《"
);
for
(
Map
<
String
,
ZipArchiveEntry
>
entryMap
:
entriesToBeExtracted
)
{
String
childName
=
entryMap
.
keySet
().
iterator
().
next
();
ZipArchiveEntry
entry
=
entryMap
.
values
().
iterator
().
next
();
try
{
extractZipFile
(
childName
,
zipFile
.
getInputStream
(
entry
));
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
}
try
{
zipFile
.
close
();
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
if
(
new
File
(
filePath
).
exists
())
{
new
File
(
filePath
).
delete
();
}
System
.
out
.
println
(
"解析压缩文件结束《《《《《《《《《《《《《《《《《《《《《《《"
);
}
/**
* 读取压缩文件并写入到fileDir文件夹下
* @param childName
* @param zipFile
*/
private
void
extractZipFile
(
String
childName
,
InputStream
zipFile
)
{
String
outPath
=
fileDir
+
childName
;
try
(
OutputStream
ot
=
new
FileOutputStream
(
outPath
)){
byte
[]
inByte
=
new
byte
[
1024
];
int
len
;
while
((-
1
!=
(
len
=
zipFile
.
read
(
inByte
)))){
ot
.
write
(
inByte
,
0
,
len
);
}
}
catch
(
FileNotFoundException
e
)
{
e
.
printStackTrace
();
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
}
}
/**
* Rar文件抽取
*/
class
RarExtractorWorker
implements
Runnable
{
private
List
<
Map
<
String
,
FileHeader
>>
headersToBeExtracted
;
private
Archive
archive
;
/**
* 用以删除源文件
*/
private
String
filePath
;
public
RarExtractorWorker
(
List
<
Map
<
String
,
FileHeader
>>
headersToBeExtracted
,
Archive
archive
,
String
filePath
)
{
this
.
headersToBeExtracted
=
headersToBeExtracted
;
this
.
archive
=
archive
;
this
.
filePath
=
filePath
;
}
@Override
public
void
run
()
{
System
.
out
.
println
(
"解析压缩文件开始《《《《《《《《《《《《《《《《《《《《《《《"
);
for
(
Map
<
String
,
FileHeader
>
entryMap
:
headersToBeExtracted
)
{
String
childName
=
entryMap
.
keySet
().
iterator
().
next
();
extractRarFile
(
childName
,
entryMap
.
values
().
iterator
().
next
(),
archive
);
}
try
{
archive
.
close
();
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
if
(
new
File
(
filePath
).
exists
())
{
new
File
(
filePath
).
delete
();
}
System
.
out
.
println
(
"解析压缩文件结束《《《《《《《《《《《《《《《《《《《《《《《"
);
}
/**
* 抽取rar文件到指定目录下
* @param childName
* @param header
* @param archive
*/
private
void
extractRarFile
(
String
childName
,
FileHeader
header
,
Archive
archive
)
{
String
outPath
=
fileDir
+
childName
;
try
(
OutputStream
ot
=
new
FileOutputStream
(
outPath
))
{
archive
.
extractFile
(
header
,
ot
);
}
catch
(
FileNotFoundException
e
)
{
e
.
printStackTrace
();
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
catch
(
RarException
e
)
{
e
.
printStackTrace
();
}
}
}
}
jodconverter-web/src/main/java/cn/keking/web/controller/FileController.java
0 → 100644
View file @
dcf37b94
package
cn
.
keking
.
web
.
controller
;
import
com.fasterxml.jackson.core.JsonProcessingException
;
import
com.fasterxml.jackson.databind.ObjectMapper
;
import
com.google.common.collect.ImmutableMap
;
import
com.google.common.collect.Lists
;
import
cn.keking.param.ReturnResponse
;
import
cn.keking.utils.FileUtils
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RequestMethod
;
import
org.springframework.web.bind.annotation.RequestParam
;
import
org.springframework.web.bind.annotation.RestController
;
import
org.springframework.web.multipart.MultipartFile
;
import
javax.servlet.http.HttpServletRequest
;
import
java.io.*
;
import
java.util.Arrays
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.UUID
;
/**
*
* @author yudian-it
* @date 2017/12/1
*/
@RestController
public
class
FileController
{
@Value
(
"${file.dir}"
)
String
fileDir
;
@Autowired
FileUtils
fileUtils
;
String
demoDir
=
"demo"
;
String
demoPath
=
demoDir
+
File
.
separator
;
@RequestMapping
(
value
=
"fileUpload"
,
method
=
RequestMethod
.
POST
)
public
String
fileUpload
(
@RequestParam
(
"file"
)
MultipartFile
file
,
HttpServletRequest
request
)
throws
JsonProcessingException
{
String
fileName
=
file
.
getOriginalFilename
();
// 判断该文件类型是否有上传过,如果上传过则提示不允许再次上传
if
(
existsTypeFile
(
fileName
))
{
return
new
ObjectMapper
().
writeValueAsString
(
new
ReturnResponse
<
String
>(
1
,
"每一种类型只可以上传一个文件,请先删除原有文件再次上传"
,
null
));
}
File
outFile
=
new
File
(
fileDir
+
demoPath
);
if
(!
outFile
.
exists
())
{
outFile
.
mkdirs
();
}
try
(
InputStream
in
=
file
.
getInputStream
();
OutputStream
ot
=
new
FileOutputStream
(
fileDir
+
demoPath
+
fileName
)){
byte
[]
buffer
=
new
byte
[
1024
];
int
len
;
while
((-
1
!=
(
len
=
in
.
read
(
buffer
))))
{
ot
.
write
(
buffer
,
0
,
len
);
}
return
new
ObjectMapper
().
writeValueAsString
(
new
ReturnResponse
<
String
>(
0
,
"SUCCESS"
,
null
));
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
return
new
ObjectMapper
().
writeValueAsString
(
new
ReturnResponse
<
String
>(
1
,
"FAILURE"
,
null
));
}
}
@RequestMapping
(
value
=
"deleteFile"
,
method
=
RequestMethod
.
GET
)
public
String
deleteFile
(
String
fileName
)
throws
JsonProcessingException
{
if
(
fileName
.
contains
(
"/"
))
{
fileName
=
fileName
.
substring
(
fileName
.
lastIndexOf
(
"/"
)
+
1
);
}
File
file
=
new
File
(
fileDir
+
demoPath
+
fileName
);
if
(
file
.
exists
())
{
file
.
delete
();
}
return
new
ObjectMapper
().
writeValueAsString
(
new
ReturnResponse
<
String
>(
0
,
"SUCCESS"
,
null
));
}
@RequestMapping
(
value
=
"listFiles"
,
method
=
RequestMethod
.
GET
)
public
String
getFiles
()
throws
JsonProcessingException
{
List
<
Map
<
String
,
String
>>
list
=
Lists
.
newArrayList
();
File
file
=
new
File
(
fileDir
+
demoPath
);
if
(
file
.
exists
())
{
Arrays
.
stream
(
file
.
listFiles
()).
forEach
(
file1
->
list
.
add
(
ImmutableMap
.
of
(
"fileName"
,
demoDir
+
"/"
+
file1
.
getName
())));
}
return
new
ObjectMapper
().
writeValueAsString
(
list
);
}
private
String
getFileName
(
String
name
)
{
String
suffix
=
name
.
substring
(
name
.
lastIndexOf
(
"."
));
String
nameNoSuffix
=
name
.
substring
(
0
,
name
.
lastIndexOf
(
"."
));
String
uuid
=
UUID
.
randomUUID
().
toString
();
return
uuid
+
"-"
+
nameNoSuffix
+
suffix
;
}
/**
* 是否存在该类型的文件
* @return
* @param fileName
*/
private
boolean
existsTypeFile
(
String
fileName
)
{
boolean
result
=
false
;
String
suffix
=
fileUtils
.
getSuffixFromFileName
(
fileName
);
File
file
=
new
File
(
fileDir
+
demoPath
);
if
(
file
.
exists
())
{
for
(
File
file1
:
file
.
listFiles
()){
String
existsFileSuffix
=
fileUtils
.
getSuffixFromFileName
(
file1
.
getName
());
if
(
suffix
.
equals
(
existsFileSuffix
))
{
result
=
true
;
break
;
}
}
}
return
result
;
}
}
jodconverter-web/src/main/java/cn/keking/web/controller/IndexController.java
0 → 100644
View file @
dcf37b94
package
cn
.
keking
.
web
.
controller
;
import
org.springframework.stereotype.Controller
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RequestMethod
;
/**
* 页面跳转
* @author yudian-it
* @date 2017/12/27
*/
@Controller
public
class
IndexController
{
@RequestMapping
(
value
=
"index"
,
method
=
RequestMethod
.
GET
)
public
String
go2Index
(){
return
"index"
;
}
@RequestMapping
(
value
=
"/"
,
method
=
RequestMethod
.
GET
)
public
String
root
()
{
return
"redirect:/index"
;
}
}
jodconverter-web/src/main/java/cn/keking/web/controller/OnlinePreviewController.java
0 → 100644
View file @
dcf37b94
package
cn
.
keking
.
web
.
controller
;
import
com.google.common.collect.Lists
;
import
cn.keking.param.ReturnResponse
;
import
cn.keking.utils.*
;
import
org.apache.commons.io.IOUtils
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.stereotype.Controller
;
import
org.springframework.ui.Model
;
import
org.springframework.util.StringUtils
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RequestMethod
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
import
java.io.File
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.UnsupportedEncodingException
;
import
java.net.HttpURLConnection
;
import
java.net.URL
;
import
java.net.URLConnection
;
import
java.net.URLDecoder
;
import
java.util.Arrays
;
import
java.util.List
;
import
java.util.Map
;
/**
* @author yudian-it
*/
@Controller
public
class
OnlinePreviewController
{
@Autowired
private
OfficeToPdf
officeToPdf
;
@Autowired
FileUtils
fileUtils
;
@Autowired
DownloadUtils
downloadUtils
;
@Autowired
ZipReader
zipReader
;
@Autowired
SimTextUtil
simTextUtil
;
@Value
(
"${file.dir}"
)
String
fileDir
;
/**
* @param url
* @param model
* @return
*/
@RequestMapping
(
value
=
"onlinePreview"
,
method
=
RequestMethod
.
GET
)
public
String
onlinePreview
(
String
url
,
Model
model
,
HttpServletRequest
req
)
throws
UnsupportedEncodingException
{
// 路径转码
String
decodedUrl
=
URLDecoder
.
decode
(
url
,
"utf-8"
);
String
type
=
fileUtils
.
typeFromUrl
(
url
);
String
suffix
=
suffixFromUrl
(
url
);
// 抽取文件并返回文件列表
String
fileName
=
fileUtils
.
getFileNameFromURL
(
decodedUrl
);
model
.
addAttribute
(
"fileType"
,
suffix
);
if
(
type
.
equalsIgnoreCase
(
"picture"
))
{
List
imgUrls
=
Lists
.
newArrayList
(
url
);
try
{
String
fileKey
=
req
.
getParameter
(
"fileKey"
);
imgUrls
.
clear
();
imgUrls
.
addAll
(
fileUtils
.
getRedisImgUrls
(
fileKey
));
}
catch
(
Exception
e
){
imgUrls
=
Lists
.
newArrayList
(
url
);
}
model
.
addAttribute
(
"imgurls"
,
imgUrls
);
model
.
addAttribute
(
"currentUrl"
,
url
);
return
"picture"
;
}
else
if
(
type
.
equalsIgnoreCase
(
"simText"
))
{
ReturnResponse
<
String
>
response
=
simTextUtil
.
readSimText
(
decodedUrl
,
fileName
);
if
(
0
!=
response
.
getCode
())
{
model
.
addAttribute
(
"msg"
,
response
.
getMsg
());
return
"fileNotSupported"
;
}
model
.
addAttribute
(
"ordinaryUrl"
,
response
.
getMsg
());
return
"txt"
;
}
else
if
(
type
.
equalsIgnoreCase
(
"pdf"
))
{
model
.
addAttribute
(
"pdfUrl"
,
url
);
return
"pdf"
;
}
else
if
(
type
.
equalsIgnoreCase
(
"compress"
))
{
String
fileTree
=
null
;
// 判断文件名是否存在(redis缓存读取)
if
(!
StringUtils
.
hasText
(
fileUtils
.
getConvertedFile
(
fileName
)))
{
ReturnResponse
<
String
>
response
=
downloadUtils
.
downLoad
(
decodedUrl
,
suffix
,
fileName
);
if
(
0
!=
response
.
getCode
())
{
model
.
addAttribute
(
"msg"
,
response
.
getMsg
());
return
"fileNotSupported"
;
}
String
filePath
=
response
.
getContent
();
if
(
"zip"
.
equalsIgnoreCase
(
suffix
)
||
"jar"
.
equalsIgnoreCase
(
suffix
)
||
"gzip"
.
equalsIgnoreCase
(
suffix
))
{
fileTree
=
zipReader
.
readZipFile
(
filePath
,
fileName
);
}
else
if
(
"rar"
.
equalsIgnoreCase
(
suffix
))
{
fileTree
=
zipReader
.
unRar
(
filePath
,
fileName
);
}
fileUtils
.
addConvertedFile
(
fileName
,
fileTree
);
}
else
{
fileTree
=
fileUtils
.
getConvertedFile
(
fileName
);
}
if
(
null
!=
fileTree
)
{
model
.
addAttribute
(
"fileTree"
,
fileTree
);
return
"compress"
;
}
else
{
model
.
addAttribute
(
"msg"
,
"压缩文件类型不受支持,尝试在压缩的时候选择RAR4格式"
);
return
"fileNotSupported"
;
}
}
else
if
(
"office"
.
equalsIgnoreCase
(
type
))
{
boolean
isHtml
=
suffix
.
equalsIgnoreCase
(
"xls"
)
||
suffix
.
equalsIgnoreCase
(
"xlsx"
);
String
pdfName
=
fileName
.
substring
(
0
,
fileName
.
lastIndexOf
(
"."
)
+
1
)
+
(
isHtml
?
"html"
:
"pdf"
);
// 判断之前是否已转换过,如果转换过,直接返回,否则执行转换
if
(!
fileUtils
.
listConvertedFiles
().
containsKey
(
pdfName
))
{
String
filePath
=
fileDir
+
fileName
;
if
(!
new
File
(
filePath
).
exists
())
{
ReturnResponse
<
String
>
response
=
downloadUtils
.
downLoad
(
decodedUrl
,
suffix
,
null
);
if
(
0
!=
response
.
getCode
())
{
model
.
addAttribute
(
"msg"
,
response
.
getMsg
());
return
"fileNotSupported"
;
}
filePath
=
response
.
getContent
();
}
String
outFilePath
=
fileDir
+
pdfName
;
if
(
StringUtils
.
hasText
(
outFilePath
))
{
officeToPdf
.
openOfficeToPDF
(
filePath
,
outFilePath
);
File
f
=
new
File
(
filePath
);
if
(
f
.
exists
())
{
f
.
delete
();
}
if
(
isHtml
)
{
// 对转换后的文件进行操作(改变编码方式)
fileUtils
.
doActionConvertedFile
(
outFilePath
);
}
// 加入缓存
fileUtils
.
addConvertedFile
(
pdfName
,
fileUtils
.
getRelativePath
(
outFilePath
));
}
}
model
.
addAttribute
(
"pdfUrl"
,
pdfName
);
return
isHtml
?
"html"
:
"pdf"
;
}
else
{
model
.
addAttribute
(
"msg"
,
"系统还不支持该格式文件的在线预览,"
+
"如有需要请按下方显示的邮箱地址联系系统维护人员"
);
return
"fileNotSupported"
;
}
}
/**
* 多图片切换预览
*
* @param model
* @param req
* @return
* @throws UnsupportedEncodingException
*/
@RequestMapping
(
value
=
"picturesPreview"
,
method
=
RequestMethod
.
GET
)
public
String
picturesPreview
(
String
urls
,
Model
model
,
HttpServletRequest
req
)
throws
UnsupportedEncodingException
{
// 路径转码
String
decodedUrl
=
URLDecoder
.
decode
(
urls
,
"utf-8"
);
// 抽取文件并返回文件列表
String
[]
imgs
=
decodedUrl
.
split
(
"|"
);
List
imgurls
=
Arrays
.
asList
(
imgs
);
model
.
addAttribute
(
"imgurls"
,
imgurls
);
return
"picture"
;
}
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
;
}
/**
* 根据url获取文件内容
* 当pdfjs读取存在跨域问题的文件时将通过此接口读取
*
* @param urlPath
* @param resp
*/
@RequestMapping
(
value
=
"/getCorsFile"
,
method
=
RequestMethod
.
GET
)
public
void
getCorsFile
(
String
urlPath
,
HttpServletResponse
resp
)
{
InputStream
inputStream
=
null
;
try
{
String
strUrl
=
urlPath
.
trim
();
URL
url
=
new
URL
(
strUrl
);
//打开请求连接
URLConnection
connection
=
url
.
openConnection
();
HttpURLConnection
httpURLConnection
=
(
HttpURLConnection
)
connection
;
httpURLConnection
.
setRequestProperty
(
"User-Agent"
,
"Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)"
);
inputStream
=
httpURLConnection
.
getInputStream
();
byte
[]
bs
=
new
byte
[
1024
];
int
len
;
while
(-
1
!=
(
len
=
inputStream
.
read
(
bs
)))
{
resp
.
getOutputStream
().
write
(
bs
,
0
,
len
);
}
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
finally
{
if
(
inputStream
!=
null
)
{
IOUtils
.
closeQuietly
(
inputStream
);
}
}
}
}
jodconverter-web/src/test/java/com/yudianbank/FilePreviewApplicationTests.java
View file @
dcf37b94
package
c
om
.
yudianbank
;
package
c
n
.
keking
;
import
org.junit.Test
;
import
org.junit.runner.RunWith
;
...
...
pom.xml
View file @
dcf37b94
...
...
@@ -3,7 +3,7 @@
xsi:schemaLocation=
"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
>
<modelVersion>
4.0.0
</modelVersion>
<groupId>
c
om.yudianbank
</groupId>
<groupId>
c
n.keking
</groupId>
<artifactId>
filepreview
</artifactId>
<version>
0.0.1-SNAPSHOT
</version>
<modules>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment