现有文档在线预览一般有两种方案:1、直接购买第三方成熟方案(如永中dcs,I DOC VIEW);2、利用第三方jar包自行开发。
下面主要展开自行开发方案。
一般最简单的流程为,先上传文档获取文件源,然后再进行文档转换,最后前端展示转换后的文档。
1)controller 层可以使用 MultipartFile 接收多个文件流,然后存于服务端
public Boolean uploadFile(MultipartFile file, String filePath,
String targetFileName) throws Exception {
boolean flag = true;
if (null == file) {
return false;
}
if (!validateFileType(file)) {
logger.info("文件类型校验失败!");
return false;
}
if (file.getSize() > FILESIZE) {
logger.info("文件大小超限!");
return false;
}
if (!createFolder(filePath)) {
logger.info(filePath + "创建失败!");
return false;
}
try {
File targetFile = new File(filePath, targetFileName + "."
+ getFileExt(file));
file.transferTo(targetFile);
} catch (Exception e) {
logger.error(e.getMessage());
flag = false;
}
return flag;
}
2)前端: enctype="multipart/form-data" 和 结合使用
文档转换主要有以下几种方式:
1、JODConverter + openoffice/libreoffice
程序利用 jodconverter 去连接 openoffice(或libreoffice) 服务,实现转换。类似于 MySql 和 数据库连接池。
参考:https://github.com/sbraconnier/jodconverter
maven dependency
org.jodconverter
jodconverter-core
4.2.0
org.jodconverter
jodconverter-local
4.2.0
org.jodconverter
jodconverter-online
4.2.0
org.jodconverter
jodconverter-spring
4.2.0
org.jodconverter
jodconverter-spring-boot-starter
4.2.0
(1)本地安装openoffice(L),应用内设置安装位置,然后启动openoffice服务并实现转换
maven如上设置好之后,代码如下:
officeManager = LocalOfficeManager.builder()
.portNumbers(8100)
.officeHome("/Applications/OpenOffice.app/Contents")
.taskExecutionTimeout(5 * 60 * 1000L)
.taskQueueTimeout(1000 * 1000 * 60 * 24L)
.maxTasksPerProcess(10)
.build();
officeManager.start();
OfficeDocumentConverter converter = new OfficeDocumentConverter(officeManager);
converter.convert(new File(sourceFilePath), new File(targetFilePath));
officeManager.stop();
或者是:
```
JodConverter.convert(inputFile).to(outputFile).execute();
```
各参数含义,详见上面git链接里的wiki
说明:
踩坑记录:1、由于openoffice一个服务一次同时只能转换一个文档,可根据实际需要,利用线程池,并发转换;
2、openoffice启动较为耗时,所以不必每次转换都进行stop和start,可由 maxTasksPerProcess 参数设置转换多少次后进行重启openoffice服务;
(2)远程连接openoffice服务,并实现转换
在jodconverter后续的版本中,开始出现online和local之分,具体哪个版本没仔细研究。利用online可实现连接远程服务
早期的版本中,jodconverter2.2.X 时,代码如下:
OpenOfficeConnection connection = new SocketOpenOfficeConnection("127.0.0.1",8100);
connection.connect();
DocumentConverter converter = new OpenOfficeDocumentConverter(connection);
// 2:获取Format
DocumentFormatRegistry factory = new BasicDocumentFormatRegistry();
DocumentFormat inputDocumentFormat = factory
.getFormatByFileExtension(sourceFilePath);
DocumentFormat outputDocumentFormat = factory
.getFormatByFileExtension(targetFilePath);
File sourceFile = new File(sourceFilePath);
File targetFile = new File(targetFilePath);
// 3:执行转换
converter.convert(sourceFile, inputDocumentFormat, targetFile, outputDocumentFormat);
online manage 代码如下:
final SslConfig sslConfig = new SslConfig();
sslConfig.setEnabled(true);
sslConfig.setTrustStore("/path/to/the/truststore.p12");
sslConfig.setTrustStorePassword("Password of the TrustStore");
final OfficeManager manager =
OnlineOfficeManager.builder()
.urlConnection("your url 如 http://127.0.0.1:8100")
.sslConfig(sslConfig)
.build();
manager.start();
OnlineConverter converter = OnlineConverter.builder().officeManager(manager).formatRegistry(DefaultDocumentFormatRegistry.getInstance()).build();
converter.convert(new File(sourceFilePath)).to(new File(targetFilePath)).execute();
manager.stop();
比较奇怪的是,讲道理,外部已经启动openoffice服务 officeManage 还要start 就不知道为什么了,如果不 start,会报 manage not running
外部设置端口并启动openoffice: mac终端执行 soffice -headless -accept="socket,host=localhost,port=8100;urp;" -nofirststartwizard
2、aspose jar 转换
主要应用中引入 aspose 相关jar包,调用API进行转换,相较于jodconverter:
1、收费
2、转换速度快,且不用在服务器上额外安装软件
3、不同文档的转换需要用到不同的jar包
代码比较简单,如下:
Document doc = new Document(inputStream);
PdfSaveOptions pdfSaveOptions = new PdfSaveOptions();
pdfSaveOptions.setSaveFormat(SaveFormat.PDF);
pdfSaveOptions.getOutlineOptions().setHeadingsOutlineLevels(3); // 设置3级doc书签需要保存到pdf的heading中
pdfSaveOptions.getOutlineOptions().setExpandedOutlineLevels(1); // 设置pdf中默认展开1级
doc.save(outputStream, pdfSaveOptions);
由于是收费的,所以下载jar包之后,需要设置license.xml ,文件内容如下:
Aspose.Total for Java
Aspose.Words for Java
Enterprise
20991231
20991231
8bfe198c-7f0c-4ef8-8ff0-acc3237bf0d7
sNLLKGMUdF0r8O1kKilWAGdgfs2BvJb/2Xp8p5iuDVfZXmhppo+d0Ran1P9TKdjV4ABwAgKXxJ3jcQTqE/2IRfqwnPf8itN8aFZlV3TJPYeD3yWE7IT55Gz6EijUpC7aKeoohTb4w2fpox58wWoF3SNp6sK6jDfiAUGEHYJ9pjU=
jar包会对其中的 signature进行 验签操作。
验签不通过会抛异常,可自行处理保证转换成功,但是试用版转换会有水印,且转换有大小限制,网上有破解方法,反编译改class文件,有点难
jar 下载地址:https://downloads.aspose.com/words/java
展示pdf一般有两种方案,1、利用swftools把pdf转换为swf文件,然后在页面展示flash;2、直接展示PDF文件。
直接在前端显示pdf文件:
1、H5
1) pdf.js:参考 http://mozilla.github.io/pdf.js/
2)jquery.media.js :http://malsup.com/jquery/media/
2、android
可直接通过webview,打开h5的方式
也可以使用 PDFView 控件进行展示:
layout:
activity:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
pdf_view = findViewById(R.id.pdf_view);
pdf_view.setFitsSystemWindows(true);
pdf_view.setFocusableInTouchMode(false);
File file=new File("/storage/emulated/0/Android/data/com.example.qxxia.helloworld/files/pdf-file/test.pdf");
pdf_view.fromFile(file).enableSwipe(true).defaultPage(1).showMinimap(true).load();
}
参考:https://github.com/JoanZapata/android-pdfview
gradle:
implementation 'com.joanzapata.pdfview:android-pdfview:1.0.4@aar'
还有其他的版本的jar可依赖
3、IOS
实在不太懂,勉强能实现
UIWebView *webView = [[UIWebView alloc] initWithFrame:CGRectMake(50, 50, 360, 500)];
// Do any additional setup after loading the view, typically from a nib.
NSString *path = [[NSBundle mainBundle] pathForResource:@"test.pdf" ofType:nil];
NSURL *url = [NSURL fileURLWithPath:path];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[webView loadRequest:request];
[self.view addSubview: webView];
最近研究文档转换,做个记录,侵删。
其他参考地址:
永中:http://www.yozodcs.com/help.html
I Doc View:https://www.idocv.com/docs.html