引言:
最近项目中对上传的文件需要在线查看功能(就是不用下载到本地,可以直接在网页里打开的查看),通过几周的研究终于搞定,在此总结下供有同样需求的同仁查询和使用。
原理:
通常的在线查看功能都是使用文档转换工具,把原始文档转换成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,至此为止已经完成各种文档的转换和显示问题,希望能有同样需求的同仁们少走弯路。
相关推荐
总结来说,这个"Office文档转换预览解决方案(JAVA)"提供了一种基于Java的实现方式,通过Apache POI、PDFBox和PDF2SWF等工具,实现了Office文档到SWF的转换,从而实现在线预览功能。然而,随着技术的发展,开发者...
要将Swagger的在线文档转换为Word文档,我们可以借助第三方工具或库,如`swagger2doc`。这是一个Python脚本,它可以解析Swagger JSON或YAML格式的文档并将其转换为Markdown或Word格式。首先,你需要安装`swagger2doc...
总之,这是一个将Office文档转换为SWF格式的自定义解决方案,适用于在线预览需求,且具备文件夹监控和多线程转换的特性。对于开发者而言,它提供了学习和研究多线程编程、文件转换以及Office文档解析等技术的机会。
其次,`echarts-doc-4.8.zip`是ECharts的文档,包含了离线文档、示例和在线编辑器。离线文档为开发者提供了一份详尽的API参考,覆盖了ECharts的所有配置项和方法,便于在无网络环境下查阅。示例部分则展示了各种图表...
综上所述,zyplayer-doc通过其全面的功能和易用性,为企业提供了专业而实用的文档管理和知识库解决方案。无论是在日常工作中整理文档,还是在团队协作中分享知识,zyplayer-doc都能成为企业不可或缺的工具。通过私有...
这款工具在当时因其高效便捷的转换能力而受到欢迎,尤其对于需要在线分享、展示文档内容或者保护文档版权的用户来说,它提供了极好的解决方案。 1. **FlashPaper**:FlashPaper是Adobe公司推出的一款产品,它可以将...
对于许多企业管理者来说,如何防止公司的机密信息泄露是一个长期而艰巨的任务,一套优秀的内网安全管理软件-IP-guard,将能够更好的堵截信息泄露的途径,从而保证企业竞争力长久不衰。
总的来说,`poi-tl`库结合其提供的Demo,为Java开发者提供了一个强大且灵活的文档处理解决方案,特别是对于那些需要频繁生成定制化文档的业务场景。通过熟悉和掌握这个库,开发者可以提高文档处理的效率,减少手动...
影响总装操作工装配质量的因素和解决方案---.doc
青葡萄--科技云桌面解决方案-学校.doc
华为云计算文档实施材料,桌面虚拟化桌面虚拟化桌面虚拟化桌面虚拟化桌面虚拟化
一卡通解决方案-指纹一卡通旅游管理系统解决方案
包含翻译后的API文档:spire_2.12-0.13.0-javadoc-API文档-中文(简体)版.zip; Maven坐标:org.spire-math:spire_2.12:0.13.0; 标签:spire、中文文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开...
物联网一卡通解决方案-RFID无线作业管理系统解决方案
本文档在线预览方案主要涉及到文档在线预览的两种方式:一种是类似于百度文库和豆丁网的Flash形式展示(Office→Flash),另一种是类似于网易邮箱和移动139 邮箱的Html形式展示(Office→Html)。 文档在线预览方案...
7. **打印与预览**:内建打印和预览功能,便于用户查看和打印PDF文档。 **Spire.Doc** Spire.Doc 是一个强大的.NET Word处理库,它支持Word文档的创建、读取、编辑和转换。主要特性包括: 1. **创建Word**:可以...
**仿百度文库解决方案**旨在构建一个类似于百度文库的文档分享系统,其核心功能之一是能够支持各种类型的文档在线预览。为了达到这一目标,系统需要解决的关键问题是文档转换问题:即将用户上传的各种格式的文档(如...
在线文档下载器是一种工具软件,专门设计用于帮助用户免费下载来自特定平台的文档,如百度文库和豆丁网。这种下载器的便利之处在于它无需用户注册或登录即可使用,简化了获取文档的过程,提高了效率。对于经常需要...
智慧交通产品总体解决方案-交通运维管理平台.doc
【标题】"仿百度文库在线预览文档转换的demo"是针对文档在线预览功能的一个示例项目,它借鉴了百度文库的功能设计,旨在帮助开发者实现多种格式的文档(如doc、xls、ppt、txt)在网页上的预览。这种技术在现代Web...