最近在项目中要做一个文档的预览,在网上搜了好多demo,都可以实现其功能,但是放在自己的项目中有点复杂。
先说明本人的开发环境(win7+tomcat7+maven+svn+myeclipse),接下来最直观的项目需求,如下图:
当用户点击预览的时候能看各种文档,其实在这里有两种思路:
一:如果你的文档是固定的,就是单纯的给用户进行预览和下载的,那就是在点击预览的时候,后台完成将文档转换成pdf,再将pdf文档转换成swf文件,缺点是效率不好,慢,用户体验不好。
二:就是在上传文档的时候,直接将文档转换成pdf,再将pdf转换成swf文件,这样用户点击预览的时候只是给一个存放swf文件的路径,就能直接展示。
项目中我是采用第二种方式:
实现过程说明:
1、使用OpenOffice(JODConverter)将不同类型的附件转换为.pdf后缀的文件(PDF);
2、使用SwfTools将pdf文件转换为swf文件;
3、使用FlexPaper 在jsp中预览swf文件;
实现该功能需要安装两个软件、下载FlexPaper组件
1.openoffice是Apache下的一个开放免费的文字处理软件
下载地址:Apache oppenoffice 官网下载 版本-4.1.3
2.SWFTools是一组用来处理Flash的swf文件的工具包,我们使用它将pdf文件转成swf文件!
下载地址:SWFTools官网下载 swftools-2013-04-09-1007.exe
3.FlexPaper是一个开源轻量级的在浏览器上显示各种文档的组件(下载下来后解压即可)
下载地址:FlexPaper官网下载 版本FlexPaper_2.3.6
将下载的两个软件进行安装,可自定义盘符安装,oppenoffice是一套sun的开源office办公套件,能在widows,linux,solaris等操作系统上执行,可以将word、excel、ppt、txt等文件转换为pdf文件;
安装完成后,我们还需要启动openoffice server。有两种做法:
第一种:以命令的方式启动,在cmd命令下,进入C:\Program Files (x86)\OpenOffice 4\program的目录下,输入命令:
soffice -headless -accept="socket,host=127.0.0.1,port=8100;urp;" -nofirststartwizard
就可以启动成功,但是这种每次服务重启都要来执行此命令,比较麻烦。
第二种:以系统服务的方式启动,此服务需要下载Windows Resource Kit tools,此软件可以将openoffice server设置成系统服务。
Windows Resource Kit tools是一组为管理员、开发者和高级用户设计的软件工具,包括管理活动目录、组策略、TCP/IP网络、注册表、系统安全、监测等涉及Windows Server 2003 操作系统的其它很多方面的非常规安装的工具组。
下载Windows Resource Kit tools,直接百度输入Windows Resource Kit tools应该第一个就是点击download就可以,默认安装即可。
接下来做三个操作:
1.找到Windows Resource Kit tools
在Command Shell中执行以下命令:
"C:\Program Files (x86)\Windows Resource Kits\Tools\instsrv" OpenOfficeUnoServer "C:\Program Files (x86)\Windows Resource Kits\Tools\srvany.exe"
这里注意你的路径,我的是C:\Program Files (x86)\Windows Resource Kits\Tools
2.打开注册表寻找以下路径
HKEY_LOCAL_MACHINE -> SYSTEM ->ControlSet001 ->Services ->OpenOfficeUnoServer
在OpenOfficeUnoServer上新建“项”Parameters,在Parameters新建字符串值Application,添入值:
C:\Program Files (x86)\OpenOffice 4\program\soffice.exe -headless -nofirststartwizard -accept="socket,host=localhost,port=8100;urp;StarOffice.Service"
同样注意C:\Program Files (x86)\OpenOffice 4的路径。
3.在服务控制台启动 openoffice 服务,也可以在cmd命令中运行netstat -anop tcp,查看8100是否已被监听。
2.打开注册表寻找以下路径
在我的项目中我写了两个工具类以便更好的调用:
1.DocumentUtil
package com.elitel.ioms.base.comm.utils;
import java.io.File;
import javax.servlet.http.HttpServletRequest;
public class DocumentUtil {
/**
* 文档工具类,根据上传的文件生成pwf和swf文件。
* @param request
* @param url
*/
public static void topdfAndswf(HttpServletRequest request,String url){
String path = request.getRequestURI();
File f = new File(path+url);
if (f != null) {
String tomcatURL_1 =request.getSession().getServletContext().getRealPath("/");
String tomcatURL_2 = tomcatURL_1.replaceAll("\\\\", "/");
//调用转换类DocConverter,并将需要转换的文件传递给该类的构造方法
DocConverterUtil d = new DocConverterUtil(tomcatURL_2+url);
//调用conver方法开始转换,先执行doc2pdf()将office文件转换为pdf;再执行pdf2swf()将pdf转换为swf;
d.conver();
}
}
}
2.DocConverterUtil 转换类
package com.elitel.ioms.base.comm.utils;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import com.artofsolving.jodconverter.DocumentConverter;
import com.artofsolving.jodconverter.openoffice.connection.OpenOfficeConnection;
import com.artofsolving.jodconverter.openoffice.connection.SocketOpenOfficeConnection;
import com.artofsolving.jodconverter.openoffice.converter.OpenOfficeDocumentConverter;
/**
* doc docx,ppt,pptx等格式转换
*
*
*
*/
public class DocConverterUtil {
private static final int environment = 1;// 环境 1:Windows 2:Linux
private String fileString;// (只涉及PDF2swf路径问题)
private String outputPath = "";// 输入路径 ,如果不设置就输出在默认 的位置
private String fileName;
private File pdfFile;
private File swfFile;
private File docFile;
public DocConverterUtil(String fileString) {
ini(fileString);
System.out.println("文件路径" + fileString);
}
/**
* * 重新设置file
*
* @param fileString
* 32.
*/
public void setFile(String fileString) {
ini(fileString);
}
/**
* * 初始化
*
* @param fileString
*
*/
private void ini(String fileString) {
this.fileString = fileString;
fileName = fileString.substring(0, fileString.lastIndexOf("."));
docFile = new File(fileString);
pdfFile = new File(fileName + ".pdf");
swfFile = new File(fileName + ".swf");
}
/**
* 转为PDF
*
* @param file
*
*/
private void doc2pdf() throws Exception {
//docFile = new File(fileString);
//System.out.println(docFile.exists());
if (docFile.exists()) {
System.out.println("====");
if (!pdfFile.exists()) {
OpenOfficeConnection connection = new SocketOpenOfficeConnection(8100);
try {
connection.connect();
DocumentConverter converter = new OpenOfficeDocumentConverter(connection);
converter.convert(docFile, pdfFile);
// close the connection
connection.disconnect();
System.out.println("****pdf转换成功,PDF输出=====: " + pdfFile.getPath() + "****");
} catch (java.net.ConnectException e) {
e.printStackTrace();
System.out.println("****swf转换器异常,openoffice 服务未启动!****");
throw e;
} catch (com.artofsolving.jodconverter.openoffice.connection.OpenOfficeException e) {
e.printStackTrace();
System.out.println("****swf转换器异常,读取转换文件 失败****");
throw e;
} catch (Exception e) {
e.printStackTrace();
throw e;
}
} else {
System.out.println("****已经转换为pdf,不需要再进行转化 ****");
}
} else {
System.out.println("****swf转换器异常,需要转换的文档不存在, 无法转换****");
}
}
/** * 转换成 swf */
@SuppressWarnings("unused")
private void pdf2swf() throws Exception {
Runtime r = Runtime.getRuntime();
if (!swfFile.exists()) {
if (pdfFile.exists()) {
if (environment == 1) {// windows环境处理
try {
Process p = r.exec("E:/tools/pdf2swf.exe "
+ pdfFile.getPath() + " -o " + swfFile.getPath() + " -T 9");
System.out.print(loadStream(p.getInputStream()));
System.err.print(loadStream(p.getErrorStream()));
System.out.print(loadStream(p.getInputStream()));
System.err.println("****swf转换成功,文件输出: " + swfFile.getPath() + "****");
if (pdfFile.exists()) {
//pdfFile.delete();
}
} catch (IOException e) {
e.printStackTrace();
throw e;
}
} else if (environment == 2) {// linux环境处理
try {
Process p = r.exec("pdf2swf" + pdfFile.getPath() + " -o " + swfFile.getPath() + " -T 9");
System.out.print(loadStream(p.getInputStream()));
System.err.print(loadStream(p.getErrorStream()));
System.err.println("****swf转换成功,文件输出: " + swfFile.getPath() + "****");
if (pdfFile.exists()) {
//pdfFile.delete();
}
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
} else {
System.out.println("****pdf不存在,无法转换****");
}
} else {
System.out.println("****swf已经存在不需要转换****");
}
}
static String loadStream(InputStream in) throws IOException {
int ptr = 0;
in = new BufferedInputStream(in);
StringBuffer buffer = new StringBuffer();
while ((ptr = in.read()) != -1) {
buffer.append((char) ptr);
}
return buffer.toString();
}
/**
* * 转换主方法
*/
@SuppressWarnings("unused")
public boolean conver() {
if (swfFile.exists()) {
System.out.println("****swf转换器开始工作,该文件已经转换为 swf****");
return true;
}
if (environment == 1) {
System.out.println("****swf转换器开始工作,当前设置运行环境 windows****");
} else {
System.out.println("****swf转换器开始工作,当前设置运行环境 linux****");
}
try {
doc2pdf();
pdf2swf();
} catch (Exception e) {
e.printStackTrace();
return false;
}
System.out.println("文件存在吗?" + swfFile);
if (swfFile.exists()) {
System.out.println("存在");
return true;
} else {
System.out.println("不存在");
return false;
}
}
/**
* 返回文件路径 @param
*/
public String getswfPath() {
if (this.swfFile.exists()) {
String tempString = swfFile.getPath();
tempString = tempString.replaceAll("\\\\", "/");
System.out.println("最后文件路径为" + tempString);
return tempString;
} else {
return "文件不存在";
}
}
/**
* 设置输出路径
*
* @param outputPath
*/
public void setOutputPath(String outputPath) {
this.outputPath = outputPath;
if (!outputPath.equals("")) {
String realName = fileName.substring(fileName.lastIndexOf("/"), fileName.lastIndexOf("."));
if (outputPath.charAt(outputPath.length()) == '/') {
swfFile = new File(outputPath + realName + ".swf");
} else {
swfFile = new File(outputPath + realName + ".swf");
}
}
}
}
接下来就是当你上传文件成功的同时,直接调用DocumentUtil工具类:
其中你要用的就是DocumentUtil.topdfAndswf(request, document.getFilelink());这句代码,其中document.getFilelink()这个就是你上传成功的文件夹路径,例如:upload/konwleage/file/20171116/20171116_1510815885273.doc,我这里上传方法不做解析,而在我们项目中这个文件夹是在tomcat中的,所以在这个DocumentUtil工具类中我获取了tomcat路径进行了拼接,后台代码基本就是这些。
当点击预览的时候我们需要拿到转换后的swf文件的路径,默认应该是跟原文件在一起的。
前端代码:
jsp页面:
<%@page import="com.elitel.ioms.main.entity.UserInfo"%>
<%@ page language="java" import="java.util.*,com.elitel.ioms.core.common.*,com.elitel.ioms.base.comm.utils.*,javax.servlet.http.HttpServletRequest,com.elitel.ioms.main.entity.UserInfo" pageEncoding="UTF-8"%>
<%
String basePath = PathUtil.getBasePathFromRequest(request);
String userTheme = ThemeUtil.getUserTheme();
%>
<%-- 浏览器兼容 --%>
注意看标红的部分,
js代码:
var url = art.dialog.data('url');
$(function(){
DocumentView();
});
//预览
function DocumentView(){
$("#viewerPlaceHolder").FlexPaperViewer(
{ config : {
SWFFile : escape(url),
Scale : 1,
ZoomTransition : 'easeOut',
ZoomTime : 0.5,
ZoomInterval : 0.2,
FitPageOnLoad : false,
FitWidthOnLoad : true,
FullScreenAsMaxWindow : false,
ProgressiveLoading : false,
MinZoomSize : 0.5,
MaxZoomSize : 2,
SearchMatchAll : true,
InitViewMode : 'Portrait',
ReaderingOrder :'false',
StartAtPage :'',
ViewModeToolsVisible : true,
ZoomToolsVisible : true,
NavToolsVisible : true,
CursorToolsVisible : true,
SearchToolsVisible : true,
localeChain: 'zh_CN',
}});
}
其中这个url就是生成swf文件的地方,默认是跟原文件在一起的。
预览效果: