引言:
最近项目中对上传的文件需要在线查看功能(就是不用下载到本地,可以直接在网页里打开的查看),通过几周的研究终于搞定,在此总结下供有同样需求的同仁查询和使用。
原理:
通常的在线查看功能都是使用文档转换工具,把原始文档转换成swf文档,然后通过网页直接展示文档内容。
解决方案:
在前期技术研究的过程中,发现有三种解决方案,他们分别是:
1、使用 FlexPaper + Pdf2swf 组合。
缺点是只能提供pdf转换成swf然后在线查看。要支持其他格式的话,需要先转成pdf,这样的话效率有点低。不过网上这种方式的资料挺多的。
相关资料: www.cnblogs.com/luckyxiaoxuan/archive/2012/06/13/2548510.html
2、使用FlashPaper 把文档转成swf直接显示
这种方式的好处在于支持多种格式的文档转换,支持的文档格式包括(doc、docx、xls、xlsx、pdf、txt, ppt、pptx), ppt、pptx的支持效果不怎么好,转换有些慢,要支持这两种方式的话,有专有的转换工具。
原来准备使用FlashPaper转换成swf文档,然后使用FlexPaper显示的,但是发现使用FlexPaper显示FlashPaper转成的swf存在问题,不能显示swf内容,而且不停的闪。后来想起浏览器可以直接支持swf显示的。使用<object><embed>标签即可。
还有一个好处就是这个工具免费。
缺点就是: 最后版本2.2,发布于2008年5月,此后不再支持;支持winxp, server2003等,不支持win7系统;
3、使用Print2Flash把文档转换成swf直接显示
这个东西比FlashPaper更强大,功能更全面,而且提供各种系统的支持。是一个非常不错的工具。
缺点就是:需要money,有需求的公司可以使用。
相关资料: http://www.blue-pacific.com/print2flash/samples/default.htm
我的方案:
我选用的第二种方案,免费,而且对各种当前流行的文档都支持,同时服务器是window server 2003。下面说下具体的程序吧。
1、FlashPaper的安装
可以在网上下载 FlashPaper2.2绿色版,地址: http://download.csdn.net/detail/walkerjong/4420486
下载安装程序后,可以点击install.bat安装FlashPaper,若出现下面的错误:
flashpaper AddPrinterDriver stage 13: error 126 - 找不到指定的模块
错误原因: 安装操作系统的时候没有开启系统还原功能,FlashPaper需要使用该功能。
解决方案: 把安装文件包里的srclient.dll文件拷贝到c:/windows/system32/目录下。
当然也可以使用java程序自动安装,下面是我的工具类代码:FlashPaperUtil.java
- package org.study.isap.common.util;
- import java.io.BufferedReader;
- import java.io.File;
- import java.io.FileNotFoundException;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.InputStreamReader;
- import org.apache.log4j.Logger;
- public class FlashPaperUtil {
- private static final Logger logger = Logger.getLogger(FlashPaperUtil.class);
- // flashPaper的存放位置
- public static final String FLASH_PAPER_DIR = "bin/flashPaper2_2";
- // 转换各种格式的文档为swf的命令
- public static final String FLASH_PAPER_CMD = "FlashPrinter.exe";
- // 检查swf是否转换完成的最大等待次数
- private static final int maxWaitCount = 60;
- // 检查swf是否存在的时间间隔, 单位ms。
- private static final int checkInterval = 20000;
- private static final File flashPaperDir = initDir();
- private FlashPaperUtil(){
- }
- private static File initDir(){
- File dir = new File(FileUtil.getWebRootPath(), FLASH_PAPER_DIR);
- logger.debug("flashPaperDir["+dir.getAbsolutePath()+"]");
- return dir;
- }
- /**
- * 卸载flashPaper。
- */
- public static void uninstall(){
- String uninstallCmd = "uninstall.bat";
- try {
- String cmd =new File(flashPaperDir, uninstallCmd).getAbsolutePath();
- Runtime runtime = Runtime.getRuntime();
- Process process = runtime.exec(cmd, null, flashPaperDir);
- try {
- // 读取process输出流,放置buffer过小阻塞
- InputStream infoStream = process.getInputStream();
- new ReadThread(infoStream).start();
- InputStream errorStream = process.getErrorStream();
- new ReadThread(errorStream).start();
- process.waitFor();
- } catch (InterruptedException e) {
- logger.error(e);
- }finally{
- process.destroy();
- }
- runtime = null;
- logger.info("卸载FlashPaper成功,cmd["+cmd+"]");
- } catch (IOException e) {
- logger.error(e);
- logger.error("卸载FlashPaper时出现错误。");
- }
- }
- /**
- * 安装flashPaper。
- */
- public static void install(){
- String installCmd = "install.bat";
- if(checkInstallEnvironment()){
- try {
- String cmd =new File(flashPaperDir, installCmd).getAbsolutePath();
- Runtime runtime = Runtime.getRuntime();
- Process process = runtime.exec(cmd, null, flashPaperDir);
- try {
- // 读取process输出流,放置buffer过小阻塞
- InputStream infoStream = process.getInputStream();
- new ReadThread(infoStream).start();
- InputStream errorStream = process.getErrorStream();
- new ReadThread(errorStream).start();
- process.waitFor();
- } catch (InterruptedException e) {
- logger.error(e);
- }finally{
- process.destroy();
- }
- runtime = null;
- logger.info("安装FlashPaper成功,cmd["+cmd+"]");
- } catch (IOException e) {
- logger.error(e);
- logger.error("安装FlashPaper时出现错误。");
- }
- }
- }
- 便民养生网站长提供:http://www.yangsheng52.com/
- /**
- * 检查安装flashPaper的环境。
- * @return
- */
- private static boolean checkInstallEnvironment(){
- String systemRoot = System.getenv("SystemRoot");
- File dest = new File(systemRoot, "system32/srclient.dll");
- logger.debug("操作系统安装路径["+systemRoot+"]");
- if(!dest.exists()){
- logger.info("系统安装目录下不存在该文件["+dest.getAbsolutePath()+"],程序将自动复制该文件。");
- String srcFile = "srclient.dll";
- try {
- File src = new File(flashPaperDir, srcFile);
- FileUtil.copyFile(src, dest);
- return true;
- } catch (FileNotFoundException e) {
- logger.error("找不到要拷贝的源文件["+srcFile+"]", e);
- } catch (IOException e) {
- logger.error("复制文件出错, 源文件["+srcFile+"], 目标文件["+dest.getAbsolutePath()+"]", e);
- }
- logger.error("您的环境不能自动安装FlashPaPer,需要手动安装,安装程序位置/WEB-INF/classes/"+FLASH_PAPER_DIR);
- return false;
- }else{
- logger.info("系统安装目录下存在该文件["+dest.getAbsolutePath()+"],FlashPaper可以开始安装。");
- return true;
- }
- }
- /**
- * 使用flashpaper将文档格式转换生产swf文件。
- * 支持格式: office(word、excel),pdf, txt等主流格式。
- * @param path
- * @return
- */
- public static File fileToSwf(String input, String output){
- File inputFile = new File(input);
- File outputFile = new File(output);
- return fileToSwf(inputFile, outputFile);
- }
- /**
- * 使用flashpaper将文档格式转换生产swf文件。
- * 支持格式: office(word、excel),pdf, txt等主流格式。
- * @param path
- * @return
- */
- public static File fileToSwf(File input, File output){
- return fileToSwf(input, output, true);
- }
- public static File fileToSwf(File input, File output, boolean waitFinished){
- if(input == null || !input.exists()){
- logger.error("要转换为swf的文件["+input.getAbsolutePath()+"]为空或不存在!");
- return null;
- }
- if(output.exists()){
- logger.info("swf["+output+"]已经存在。");
- return output;
- }
- String printerCmd = new File(flashPaperDir, FLASH_PAPER_CMD).getAbsolutePath();
- String cmd = printerCmd+" "+input.getAbsolutePath()+" -o "+output.getAbsolutePath();
- logger.debug("fileToSwf cmd["+cmd+"]");
- int resultCode = 1;
- try {
- Process process = Runtime.getRuntime().exec(cmd, null, flashPaperDir);
- try {
- // 读取process输出流,系统提供的buffer过小不读取会阻塞
- new ReadThread(process.getInputStream()).start();
- new ReadThread(process.getErrorStream()).start();
- resultCode = process.waitFor();
- if(resultCode == 1){
- logger.error("转换文件过程中出现错误,请检查FlashPaper环境是否安装正确!");
- }
- } catch (InterruptedException e) {
- logger.error(e);
- }finally{
- process.destroy();
- }
- if(resultCode != 1 && waitFinished){
- for(int count=maxWaitCount; count>=0; count--){
- if(output.exists()){
- logger.info("转换文档为swf成功,swf["+output.getAbsolutePath()+"]");
- break;
- }else{
- try { // 休眠checkInterval秒后检查swf文件是否转换完成
- Thread.sleep(checkInterval);
- } catch (InterruptedException e) {
- logger.error(e);
- }
- }
- }
- }
- } catch (IOException e) {
- logger.error("转换文档为swf失败, path["+input.getAbsolutePath()+"]", e);
- }
- return output;
- }
- private static class ReadThread extends Thread {
- private InputStream inputStream;
- public ReadThread(InputStream inputStream){
- this.inputStream = inputStream;
- }
- public void run(){
- BufferedReader input = null;
- String str = null;
- try {
- input = new BufferedReader(new InputStreamReader(this.inputStream, "GBK"));
- while( (str=input.readLine())!= null){
- logger.debug(str);
- }
- } catch (IOException e) {
- logger.error("读取执行线程信息时出错", e);
- }finally{
- try {
- input.close();
- this.inputStream = null;
- } catch (IOException e) {
- logger.error(e);
- }
- }
- }
- }
- }
另外,为了方便程序部署,我们写了一个自动安装程序。
FlashPaperInstallService.java
- package org.study.isap.common.service;
- import org.springframework.stereotype.Service;
- import com.cosbulk.isap.common.util.FlashPaperUtil;
- @Service
- public class FlashPaperInstallService {
- public FlashPaperInstallService(){
- Thread thread = new InstallThread();
- thread.start();
- }
- private static class InstallThread extends Thread {
- public InstallThread(){
- setName("[Install FlashPaper Thread]");
- setDaemon(true);
- }
- public void run(){
- FlashPaperUtil.uninstall();
- FlashPaperUtil.install();
- }
- }
- }
FileUtil.java 文件如下:
- package org.study.isap.common.util;
- import java.io.BufferedInputStream;
- import java.io.BufferedOutputStream;
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.OutputStream;
- import java.io.UnsupportedEncodingException;
- import java.net.URLDecoder;
- import javax.servlet.http.HttpServletRequest;
- import org.apache.log4j.Logger;
- import org.springframework.util.StringUtils;
- public class FileUtil {
- private static final Logger logger = Logger.getLogger(FileUtil.class);
- // web工程的文件系统根目录 (/**/isap)
- private static final String webRootPath;
- // web工程的URL根目录 (http://***.**/isap)
- private static String webRootUrl;
- static {
- webRootPath = initWebFileBase();
- webRootUrl = null;
- }
- private FileUtil(){
- }
- private static String initWebFileBase(){
- String fileBase = null;
- String path = FlashPaperUtil.class.getClassLoader().getResource("").getFile();
- // 获取的文件路径为url地址编码,需要处理空格问题
- String classPath = path;
- try {
- classPath = URLDecoder.decode(path, "UTF-8");
- } catch (UnsupportedEncodingException e) {
- logger.error(e);
- }
- int index = classPath.lastIndexOf("/WEB-INF/classes");
- if(index != -1){
- fileBase = classPath.substring(0, index);
- logger.debug("获取isap文件系统根路径成功, webFileBase["+fileBase+"]");
- }else{
- index = classPath.lastIndexOf("/build/classes");
- if(index != -1){
- fileBase = classPath.substring(0, index)+"/WebRoot";
- }else{
- fileBase="";
- logger.error("获取isap文件系统根路径错误。path["+classPath+"]");
- }
- }
- return fileBase;
- }
- //------------------ 路径相关 -----------------
- /**
- * 返回web工程的文件系统的绝对路径。
- * @return
- */
- public static String getWebRootPath(){
- return webRootPath;
- }
- /**
- * 把相对webFileBase的path转换成url形式的字符串。
- * 例如:<br/>
- * 输入: /uploadFiles/project/file/test.doc <br/>
- * 输出:http://127.0.0.1:8080/isap/uploadFiles/project/file/test.doc <br/>
- * @param request
- * @param path
- * @return
- */
- public static String getDocUrl(HttpServletRequest request, String path){
- if(!StringUtils.hasLength(webRootUrl)){
- webRootUrl = request.getScheme()+"://"+request.getLocalAddr()+":"+request.getLocalPort()+request.getContextPath();
- }
- if(StringUtils.hasLength(path)){
- if(path.startsWith("http://")){
- return path;
- }
- path = path.replace('\\', '/');
- }else{
- return webRootUrl;
- }
- if(!path.startsWith("/")){
- return webRootUrl+"/"+path;
- }
- return webRootUrl+path;
- }
- // ----------------------- 文件名和文件类型相关 ----------------
- /**
- * 获取文件名称。
- */
- public static String getFileName(String docUrl){
- int index = docUrl.lastIndexOf("/");
- if(index != -1){
- return docUrl.substring(index+1);
- }else{
- return docUrl;
- }
- }
- /**
- * 获取文件类型, 返回带点号的文件类型。例如“.doc”
- *
- * @param docUrl
- * @return
- */
- public static String getFileType(String docUrl){
- int index = docUrl.lastIndexOf(".");
- if(index != -1){
- return docUrl.substring(index);
- }else{
- return docUrl;
- }
- }
- /**
- * 获得输入路径下,同名文件的swf文件。 <br />
- *
- * @param path
- * @param fileType
- * @return
- */
- public static String getSwfFile(String path){
- String swfPath = null;
- if(StringUtils.hasLength(path)){
- int index = path.lastIndexOf(".");
- if(index != -1){
- swfPath = path.substring(0, index)+".swf";
- }
- }
- return swfPath;
- }
- public static File getSwfFile(File file) {
- String swfpath = getSwfFile(file.getAbsolutePath());
- return new File(swfpath);
- }
- // ---------- 复制文件 ---------
- public static void copyFile(File src, File dest) throws IOException{
- File dir = dest.getParentFile();
- if(!dir.exists()){
- dir.mkdirs();
- }
- BufferedInputStream input = null;
- BufferedOutputStream output = null;
- try{
- input = new BufferedInputStream(new FileInputStream(src));
- output = new BufferedOutputStream(new FileOutputStream(dest));
- int length = 0;
- byte[] buffer = new byte[4*1024];
- while((length = input.read(buffer)) >= 0){
- output.write(buffer, 0, length);
- }
- }finally{
- FileUtil.closeOutputStream(output);
- FileUtil.closeInputStream(input);
- }
- }
- // ------------- 关闭文件流 --------------------
- /**
- * 关闭输入流。
- * @param input
- */
- public static void closeInputStream(InputStream input){
- if(input != null){
- try {
- input.close();
- } catch (IOException e) {
- logger.error("关闭输入文件失败!");
- logger.error(e);
- }
- }
- }
- /**
- * 关闭输出流。
- * @param output
- */
- public static void closeOutputStream(OutputStream output){
- if(output != null){
- try {
- output.close();
- } catch (IOException e) {
- logger.error("关闭输出文件失败!");
- logger.error(e);
- }
- }
- }
- }
说明: 下载下来的flashPaper安装程序解压后放置在 WebContent/bin/目录下。
程序自动的时候自动安装,若检测到没有使用系统还原功能,自动拷贝文件到系统system32目录下。
2、在上面贴出的代码中,使用FlashPaperUtil. fileToSwf()函数即可完成对可支持文档的转换。即转成swf文件。
3、显示转成成的swf文件。
displaySwf.jsp
- <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" isELIgnored="false" %>
- <%@ taglib prefix="c" uri="/WEB-INF/tld/c.tld" %>
- <%
- String webRoot = request.getContextPath();
- %>
- <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
- <html>
- <head>
- <base href="<%=webRoot%>/view/common/" />
- <title>在线显示文档</title>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
- <style type="text/css" media="screen">
- html,body{
- margin: 0px;
- padding: 0px;
- overflow: hidden;
- height: 100%;
- }
- #content{
- width:100%;
- height:100%;
- MARGIN: 0px auto;
- }
- </style>
- </head>
- <body>
- <c:if test="${swfUrl!=null}">
- <div id="content">
- <object
- classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
- codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=7,0,19,0"
- width="100%"
- height="100%"
- >
- <param name="movie" value="${swfUrl}" />
- <param name="quality" value="high" />
- <param name="allowFullScreen" value="true" />
- <embed
- pluginspage="http://www.macromedia.com/go/getflashplayer"
- type="application/x-shockwave-flash"
- src="${swfUrl}"
- allowfullscreen="true"
- quality="high"
- width="100%"
- height="100%"
- >
- </embed>
- </object>
- </div>
- </c:if>
- <c:if test="${swfUrl==null}">
- <div class="box error center" style="width:60%;">
- <h1>没有指定要显示的文档路径!</h1>
- </div>
- </c:if>
- </body>
- </html>
处理请求的controller类中相关方法:
- /**
- * 显示在线文档。
- * @return
- */
- @RequestMapping("show")
- public String show(String swfUrl, HttpServletRequest request){
- request.setAttribute("swfUrl", swfUrl);
- return "common/displaySwf";
- }
请求显示在线文档的url如下:
- http://localhost:8080/isap/fileManage/show.action?swfUrl=http://192.168.1.100/isap_doc/1341818769265.swf
注: 在FlashPaper转各类文档的时候,看到他们相关程序打开了要转的文件,然后转换的。所以碰到问题的时候注意检查一下几点:
1、服务器上是否安装相关文档的打开程序,例如office 2007 --> docx;
2、检查服务器上的Print Spoller服务是否启动,虚拟打印需要用到该服务;
3、还是失败的话,用cmd运行FlashPaper安装程序下的install.bat, 查看错误原因。
ok,至此为止已经完成各种文档的转换和显示问题,希望能有同样需求的同仁们少走弯路。
相关推荐
在这个"doc转pdf终极解决方案demo"中,我们将会看到如何利用Aspose.Words的Java API在两种操作系统上实现这个功能。 首先,让我们了解一下为什么需要将DOC转换为PDF。DOC是Microsoft Word的默认格式,而PDF...
新高考教务教学整体解决方案-智慧新高考解决方案-智慧新高考走班排课选课解决方案.doc
JAVA文件文档在线预览项目解决方案,对标业内付费产品有【永中office】【office365】【idocv】等,该项目使用流行的spring boot搭建,易上手和部署,支持主流办公文档的在线预览,如doc,docx,Excel,pdf,txt,zip,rar,...
在本文档中,作者介绍了一个基于Java技术的文档在线预览系统的设计与实现,该系统模仿了百度文库的功能,允许用户预览但不下载上传的文档。主要知识点包括: 1. **文档转换**: - 首先,利用开源软件OpenOffice将...
本文将详细介绍如何使用PHP在Linux环境下实现类似百度文库那样的文档在线预览功能。具体来说,我们将通过一系列步骤完成以下核心功能: - 用户上传DOC格式文档。 - 将DOC文档转换为PDF格式。 - 进一步将PDF文件转换...
**Spire.Doc API 帮助文档** Spire.Doc API 是一个强大的C#库,专为处理Microsoft Word文档设计,提供了全面的类、接口和属性集合,使得在.NET环境中创建、编辑、转换和操作Word文档变得轻而易举。这个API帮助文档...
综上所述,zyplayer-doc通过其全面的功能和易用性,为企业提供了专业而实用的文档管理和知识库解决方案。无论是在日常工作中整理文档,还是在团队协作中分享知识,zyplayer-doc都能成为企业不可或缺的工具。通过私有...
5. **zyplayer-doc-v1.1.6**:这个文件可能是解压后的zyplayer-doc主程序或其相关文件夹,包含了运行该在线文档工具所需的所有文件。用户可能需要将这些文件部署到服务器或者本地环境中才能启动和使用zyplayer-doc。...
包含翻译后的API文档:guava-23.0-javadoc-API文档-中文(简体)版.zip; Maven坐标:com.google.guava:guava:23.0; 标签:google、guava、中文文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开...
总的来说,`poi-tl`库结合其提供的Demo,为Java开发者提供了一个强大且灵活的文档处理解决方案,特别是对于那些需要频繁生成定制化文档的业务场景。通过熟悉和掌握这个库,开发者可以提高文档处理的效率,减少手动...
对于许多企业管理者来说,如何防止公司的机密信息泄露是一个长期而艰巨的任务,一套优秀的内网安全管理软件-IP-guard,将能够更好的堵截信息泄露的途径,从而保证企业竞争力长久不衰。
要将Swagger的在线文档转换为Word文档,我们可以借助第三方工具或库,如`swagger2doc`。这是一个Python脚本,它可以解析Swagger JSON或YAML格式的文档并将其转换为Markdown或Word格式。首先,你需要安装`swagger2doc...
本篇文章将详细介绍如何利用Java技术将Office文档(如Word、Excel、PowerPoint等)以及PDF文档转换成SWF文件,并实现在线预览的功能。SWF(Small Web Format/Shockwave Flash)是一种广泛应用于网页展示的文件格式,...
MES系统解决方案-C2.doc
将.DOC后缀的文档转换成.DOCX后缀的文档,便于后续进行合并分页或者其它作用
青葡萄--科技云桌面解决方案-学校.doc
这份"jdk-17.0.2_doc-all"文档集全面覆盖了Java 17.0.2版本的特性,是理解、学习和使用Java编程语言的关键资源。 在Java 17.0.2中,我们可以找到以下几个关键的知识点: 1. **核心类库**:Java API文档首先会介绍...
华为云计算文档实施材料,桌面虚拟化桌面虚拟化桌面虚拟化桌面虚拟化桌面虚拟化
Flashpaper的使用相信大多数人都知道,这里的Demo是用于在线转换 .doc文件转换为 .swf的flash文件。 其原理是通过进程指令对文件进行转换,所以会涉及到进程的操作, 而 doc转换为swf文件的指令则是: ...
一卡通解决方案-指纹一卡通旅游管理系统解决方案