加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

doc转swf,主流文档在线查看解决方案--类似百度文档功能

发布时间:2020-12-15 18:39:36 所属栏目:百科 来源:网络整理
导读:引言: 最近项目中对上传的文件需要在线查看功能(就是不用下载到本地,可以直接在网页里打开的查看),通过几周的研究终于搞定,在此总结下供有同样需求的同仁查询和使用。 原理: 通常的在线查看功能都是使用文档转换工具,把原始文档转换成swf文档,然后

引言:

最近项目中对上传的文件需要在线查看功能(就是不用下载到本地,可以直接在网页里打开的查看),通过几周的研究终于搞定,在此总结下供有同样需求的同仁查询和使用。


原理:

通常的在线查看功能都是使用文档转换工具,把原始文档转换成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,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的环境。
	 * @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,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,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,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,至此为止已经完成各种文档的转换和显示问题,希望能有同样需求的同仁们少走弯路。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读