`

linux word 转 pdf 下类似百度文库开发研究与实战

    博客分类:
  • java
阅读更多

缘起

由于项目需要开发了类似百度文库和DOCIN类似的Flash播放器读取上传文档的系统,虽然最终技术问题都得以解决,但开发的过程中走了不少弯路,浪费了不少时间,特别是FlexPaper去掉自带的Logo这一步上,前后花了几天才得以解决,郁闷的有点不想在事后整理这个文档。为了让自己更好的记下解决问题的关键点所在,让同样有此需求的开发人员避免浪费时间,少走一些弯路,打起精神整理本次开发过程的技术研究和技术实现过程。

基于Linux环境的技术选型

项目基于Linux环境,如果你的服务器是windows,那么某些部分的技术选型跟本文可能会有出入,最主要的一个过程是把文档统一转成PDF,如果在Windows下可以考虑跳过,因为使用Flash Paper或者Print Flash可以把文档直接转成SWF。但这两者都不支持Linux环境。因此我们采用先把所有文档统一转成PDF,然后再转成SWF的方案。

主要技术点和步骤

基于对Linux环境的支持考虑(当然Windows下也可以采用这种技术选型),团队讨论决定引入openoffice sdk + pdf2swf tool,分两个步骤,先利用openoffice sdk把文档统一转成pdf,然后利用pdf2swf toolpdf转成swf

为了提高系统的反映速度并降低系统的耦合,主业务上传文档和文档转换流程采用异步处理(分开两个应用,降低耦合)、同时采用Concurrent多线程来处理文档转换(可以通过线程数的配置,统分利用cpu资源,提高并发处理速度,提高系统的反应时间),同时可以进一步扩展设计,以支持多台机器同时处理文档转换。

主要技术点实现

1. Linux(CentOS5.3)下安装OpenOfficeOpenOffice SDK

OpenOffice安装:

1)下载了3.3版本的OpenOffice

2tar zxvf OOo_3.3.0_Linux_x86-64_install-rpm-wJRE_zh-CN.tar.gz

弯路:解压后,发现目录下有个可执行的setup,大喜,心想肯定执行setup安装了。

执行后抛出错误1

错误信息No X11 DISPLAY variable was set”

心想直接到本机操作是否会不同,结果还是一样的错误。

有大致的信息说要设置DISPLAY系统变量,又设置

export DISPLAY=localhost:0.0

再次执行抛出错误2:

抛出异常Exception in thread "main" java.lang.UnsatisfiedLinkError: /var/tmp/install_28877/usr/java/jre1.6.0_22/lib/amd64/xawt/libmawt.so

按提示给安装相关的图形界面包

yum install libXp

yum install libXtst

yum install libXp-devel

yum install libXau-devel

再次setup,又回到No X11 DISPLAY variable was set报错,我就想了,是不是当时装操作系统时没装上x windows server

也没想太多,搜了google,安装XWindow

yum groupinstall "X Window System"

yum groupinstall "GNOME Desktop Environment"

yum install nc expect

yum install freenx

yum groupinstall chinese-support

不放心,装好后reboot,再次进行setup,还是同样的出错。血压都升高了,心里在想难道要进图形界面才能安装么,但我们服务器原则上不推荐使用图形界面,如果安装的openoffice需要在图形界面下运行,那有点偏移了最初的技术选型目的。看来setup方式在文本界面下已经走不下去了,再次问google去,这次发现了另外一种安装方法。

3 cd OOO330_m20_native_packed-1_zh-CN.9567/RPMS/

4rpm -ivh *.rpm

5RPMS/desktop-integration

6rpm -ivh openoffice.org3.3-redhat-menus-3.3-*.noarch.rpm

7/opt/openoffice.org3/program/soffice -headless -accept="socket,host=127.0.0.1,port=8100;urp;" -nofirststartwizard &

前提:如果你没有安装jdk或者安装后没有把jdk/bin加入到PATH,则会报出找不到jre

vi /etc/profile,加入以下三行

export JAVA_HOME=/usr/local/jdk1.6.0_17

export PATH=$JAVA_HOME/bin:$PATH

export CLASSPATH=$JAVA_HOME/lib/tools.jar:$CLASSPATH

8)查看服务是否运行正常

netstat -ano 可以查看到8100端口被soffice服务占用

ps aux|grep soffice 查看进程

OpenOffice SDK3.3安装:

1) 下载OpenOffice SDK3.3

2tar zxvf OOo-SDK_3.3.0_Linux_x86-64_install-rpm_en-US.tar.gz

3cd OOO330_m20_native_packed-1_en-US.9567/RPMS/

4rpm -vih *.rpm

2.Linux下安装pdf2swf Tool

中文支持安装:

1) mkdir –p /usr/share/xpdf

cd /usr/share/xpdf/

2) 下载中文支持及字体库

wget ftp://ftp.foolabs.com/pub/xpdf/xpdf-chinese-simplified.tar.gz

wget http://www.nginxs.com/download/font.zip

3 tar zxvf xpdf-chinese-simplified.tar.gz

unzip font.zip

mv Gbsn00lp.ttf gkai00mp.ttf xpdf-chinese-simplified/CMap/

cd /usr/share/xpdf/xpdf-chinese-simplified

4vi add-to-xpdfrc

内容如下:

cidToUnicode Adobe-GB1 /usr/share/xpdf/chinese-simplified/Adobe-GB1.cidToUnicode

unicodeMap ISO-2022-CN /usr/share/xpdf/chinese-simplified/ISO-2022-CN.unicodeMap

unicodeMap EUC-CN /usr/share/xpdf/chinese-simplified/EUC-CN.unicodeMap

unicodeMap GBK /usr/share/xpdf/chinese-simplified/GBK.unicodeMap

cMapDir Adobe-GB1 /usr/share/xpdf/chinese-simplified/CMap

toUnicodeDir /usr/share/xpdf/chinese-simplified/CMap

displayCIDFontTT Adobe-GB1 /usr/share/xpdf/chinese-simplified/CMap/gkai00mp.ttf

保存后退出

相关Lib包安装:

1) yum –y install gcc-c++(如果已安装可跳过)

2) yum install giflib-devel.x86_64

3) yum install zlib-devel.x86_64

4) yum install freetype-devel.x86_64

5) yum install libjpeg-devel.x86_64

SwfTool安装:

1cd /usr/local/

2wget http://www.swftools.org/swftools-0.9.1.tar.gz

3tar zxvf swftools-0.9.1.tar.gz

4cd swftools-0.9.1

5./configure

6make

7make install

8)测试一下是否可用

pdf2swf -o /path/output.swf -T -z -t -f /path/yourpdffile.pdf -s languagedir=/usr/share/xpdf/xpdf-chinese-simplified -s flashversion=9

小意外:

测试环境意外宕机重起后,运行pdf2swf,抛出错误:

pdf2swf: error while loading shared libraries: libjpeg.so.8: cannot open shared object file: No such file or directory

find了一遍,发现libjpeg.so.8被装到了/usr/local/lib下,这不是默认的/lib/usr/lib目录。问了下google,对于动态库的路径问题有以下三种解决方案

动态库的路径问题

为了让执行程序顺利找到动态库,有三种方法:

(1)把库拷贝到/usr/lib/lib目录下。

(2)LD_LIBRARY_PATH环境变量中加上库所在路径。例如动态库libhello.so/home/ting/lib目录下,以bash为例,使用命令:

$export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/ting/lib

(3) 修改/etc/ld.so.conf文件,把库所在的路径加到文件末尾,并执行ldconfig刷新。这样,加入的目录下的所有库文件都可见。

本人使用了第2种办法,再次运行pdf2swf正常。

pdf2swf参数很多,以下参数是经网友翻译后的详细说明:

  • -h , –help Print short help message and exit 打印帮助信息
  • -V , –version Print version info and exit 打印版本号
  • -o , –output file.swf Direct output to file.swf. If file.swf contains ‘13568621′ (file13568630.swf), then each page指定输出的swf文件名
  • -p , –pages range Convert only pages in range with range e.g. 1-20
    or 1,4,6,9-11 or

指定转换的页面范围,使用的页码描述方法与打印机打印文件时候的选页一样

  • -P , –password password Use password for deciphering the pdf.指定打开pdf的密码
  • -v , –verbose Be verbose. Use more than one -v for greater effect.转换时输出详细的内容
  • -z , –zlib Use Flash 6 (MX) zlib compression.使用Flash 6zlib压缩机制
  • -i , –ignore Allows pdf2swf to change the draw order of the pdf. This may make the generated允许程序修改pdf的绘制顺序,可能会导致结果与原来有差异
  • -j , –jpegquality quality Set quality of embedded jpeg pictures to quality. 0 is worst (small), 100 is best (big). (default:85)设置转换其中的jpeg图片的质量,从0100,默认值是85
  • -s , –set param=value Set a SWF encoder specific parameter. See pdf2swf -s help for more information. 设置SWF转码时候的参数,具体参数可以用pdf2swf -s help获取
  • -w , –samewindow When converting pdf hyperlinks, don’t make the links open a new window. 设置转换后的swf打开原pdf中的连接时使用相同的窗口
  • -t , –stop Insert a stop() command in each page. 在每页结尾添加一个stop()命令
  • -T , –flashversion num Set Flash Version in the SWF header to num. 设置SWF所使用的flash版本号
  • -F , –fontdir directory Add directory to the font search path. 指定字体文件所在路径
  • -b , –defaultviewer Link a standard viewer to the swf file. 指定默认的swf导航文件,用来翻页、放大缩小等等
  • -l , –defaultloader Link a standard preloader to the swf file which will be displayed while the main swf is loading. 指定默认的swf加载文件,用来显示加载进程效果
  • -B , –viewer filename Link viewer filename to the swf file. 指定swf导航文件,作用同-b
  • -L , –preloader filename Link preloader filename to the swf file. 指定swf加载文件,作用同-l
  • -q , –quiet Suppress normal messages. Use -qq to suppress warnings, also. 不打印普通信息,用-qq就不打印警告信息。
  • -S , –shapes Don’t use SWF Fonts, but store everything as shape. 不使用字体,所有都转为形状。
  • -f , –fonts Store full fonts in SWF. (Don’t reduce to used characters). swf中保存全部字体。
  • -G , –flatten Remove as many clip layers from file as possible. 在文件中尽量去除影片层,合并它们
  • -I , –info Don’t do actual conversion, just display a list of all pages in the PDF. 不做实际转换,仅显示PDF的信息。
  • -Q , –maxtime n Abort conversion after n seconds. Only available on Unix. 如果运行时间超时则退出。

然后看看-s都可以设置些什么:
PDF Parameters:
PDF device global parameters:
fontdir= a directory with additional fonts 指定字体目录, 1级参数的-F相若
font= an additional font filename 增加额外的字体文件
pages= the range of pages to convert (example: pages=1-100,210-) 指定页面范围,与1级参数的-p相若
zoom= the resolution (default: 72) 指定分辨率,默认为72dpi
languagedir= Add an xpdf language directory 增加一个xpdf的语言目录,对非西欧字符有用
multiply= Render everything at the resolution 在几倍分辨率下渲染
poly2bitmap Convert graphics to bitmaps 把其中的图形转成点阵
bitmap Convert everything to bitmaps 把所有内容转成点阵(包括字体)

SWF Parameters:

SWF layer options:
jpegsubpixels=<pixels> resolution adjustment for jpeg images (same as jpegdpi, but in pixels) jpeg
图片的分辨率

ppmsubpixels=<pixels> resolution adjustment for lossless images (same asppmdpi, but in pixels)
无损图片的分辨率
subpixels=<pixels> shortcut for setting both jpegsubpixels and ppmsubpixels
快速设置上两个参数
drawonlyshapes convert everything to shapes (currently broken)
所有都转成图形
ignoredraworder allow to perform a few optimizations for creating smaller SWFs
允许执行一些小优化
linksopennewwindow make links open a new browser window
链接打开新窗口
linktarget target window name of new links
新链接窗口的名称
linkcolor=<color) color of links (format: RRGGBBAA)
链接的颜色
linknameurl Link buttons will be named like the URL they refer to (handy for iterating through links with actionscript)
链接名称与链接URL一致
storeallcharacters don’t reduce the fonts to used characters in the output file
保存所有的字符字体
enablezlib switch on zlib compression (also done if flashversion>=7)
使用zlib压缩
bboxvars store the bounding box of the SWF file in actionscript variables
as中保存swf的区域大小
dots Take care to handle dots correctly
保存单点显示
reordertags=0/1 (default: 1) perform some tag optimizations
执行某些tag优化
internallinkfunction=<name> when the user clicks a internal link (to a different page) in the converted file, this actionscript function is called
内部链接函数,如果点击一个内部链接,将调用该actionscript函数
externallinkfunction=<name> when the user clicks an external link (e.g. http://www.foo.bar/) on the converted file, this actionscript function is called
外部链接函数,如果点击一个外部链接,将调用该actionscript函数
disable_polygon_conversion never convert strokes to polygons (will remove capstyles and joint styles)
不要将笔画转成多边形
caplinewidth=<width> the minimum thichness a line needs to have so that capstyles become visible (and are converted)
线条最低转换宽度,比这个细的线条将不转换
insertstop put an ActionScript “STOP” tag in every frame
swf的每个桢中添加stop()函数
protect add a “protect” tag to the file, to prevent loadingin the Flash editor
增加protect标签,禁止在flash中加载该swf
flashversion=<version> the SWF fileversion (6)
设置最低swf版本

framerate=<fps> SWF framerate
设置桢率
minlinewidth=<width> convert horizontal/vertical boxes smaller than thiswidth to lines (0.05)
将宽度少于某值的矩形转成线条
simpleviewer Add next/previous buttons to the SWF
使用简单的导航
animate insert a showframe tag after each placeobject (animate draw order of PDF files)
jpegquality=<quality> set compression quality of jpeg images
设置jpeg的压缩质量
splinequality=<value> Set the quality of spline convertion to value (0-100, default: 100).
设置样条曲线的转换质量
disablelinks Disable links.
禁止链接

3.文档转成PDFJava实现

这篇文档http://blog.zhaojie.me/2010/05/convert-document-to-pdf-via-openoffice.html介绍的很详细,基本上可以照着上面做。虽然是windows下的例子,但在Linux下做稍微改动即可。这里就不贴出代码,列出这部分实现的细节差别:

1) Linux下,openoffice默认安装目录到/opt/openoffice,而目录/opt/openoffice.org/basis3.3/program/classes/默认是隐藏的。

Linux下,所需相关类的路径如下:

/opt/openoffice.org/basis3.3/program/classes/unoil.jar

/opt/openoffice.org/ure/share/java/jurt.jar

/opt/openoffice.org/ure/share/java/juh.jar

/opt/openoffice.org/ure/share/java/bootstrapconnector.jar(按上述文档下载,并上传到这个目录)

2) 如果Eclipse还报找不到import com.sun.star.beans.PropertyValue,那么把/opt/openoffice.org/ure/share/java/ridl.jar也引入。我的Eclipse未报此错误,而我的同事Eclipse却报这个错误。本人猜测可能是同事安装的环境或MAINFEST.MF描述不同引起的,未进一步找出原因。

3) 考虑到多线程应用,重写初始化XCompoentContext对象方法

代码片段:

 

 

 

 

Java代码 复制代码 收藏代码
  1. /**
  2. * 创建一个XComponentContext对象
  3. *
  4. * @return
  5. * @throws Exception
  6. */
  7. private static XComponentContext createContext(int port) throws Exception {
  8. return BootstrapSocketConnector.bootstrap(HXConstants.OOSYSPATH,"localhost",port);
  9. }
/**

 * 创建一个XComponentContext对象

 * 

 * @return

 * @throws Exception

 */

private static XComponentContext createContext(int port) throws Exception {

    return BootstrapSocketConnector.bootstrap(HXConstants.OOSYSPATH,"localhost",port);

}

 

 

新增传入端口参数,可以支持打开多个openoffice,如果线程多个,需要为每个线程提供不同的端口。

 

 

新增传入端口参数,可以支持打开多个openoffice,如果线程多个,需要为每个线程提供不同的端口。

 

 

 

4) 转换类型

输入文档不同,最好选择不同的打印方式,java代码实现

 

Java代码 复制代码 收藏代码
  1. public static String getConvertType(String extension){
  2. if(extension.matches("doc|docs|txt|rtf|html|htm|xml|odt|wps|wpd")){
  3. return "writer_pdf_Export";
  4. }
  5. if(extension.matches("xls|xlsb|xlsx|ods")){
  6. return "calc_pdf_Export";
  7. }
  8. if(extension.matches("ppt|pptx|odp")){
  9. return "impress_pdf_Export";
  10. }
  11. return "writer_pdf_Export";
  12. }
public static String getConvertType(String extension){

if(extension.matches("doc|docs|txt|rtf|html|htm|xml|odt|wps|wpd")){

               return "writer_pdf_Export";

            }

            if(extension.matches("xls|xlsb|xlsx|ods")){

               return "calc_pdf_Export";

            }

            if(extension.matches("ppt|pptx|odp")){

               return "impress_pdf_Export";

            }

            return "writer_pdf_Export";

}

 

 

 

 

 

 

 

4.PDF转成SWFJava实现

代码片段

 

Java代码 复制代码 收藏代码
  1. /**
  2. * 将pdf文件转化成swf文件
  3. * @param fileName 文件的绝对路径(含文件名和扩展名)
  4. * @param destPath 目标路径 (目标文件夹,不含文件名)
  5. * @return -1:源文件不存在,-2:格式不正确,-3:发生异常,0:转化成功;1:无法打开文件(Process.exitValue())
  6. * @author dongbai
  7. */
  8. public static int convertPdfToSwf(String fileName,String destPath){
  9. if(null != fileName && fileName.length() > 0){
  10. // String destName = "";
  11. String fileExt = "";
  12. StringBuffer command = new StringBuffer();
  13. Process pro;
  14. BufferedReader buffer;
  15. fileExt = fileName.substring(fileName.lastIndexOf(".")+1, fileName.length()).toLowerCase();
  16. try{
  17. File file = new File(fileName);
  18. if(!file.exists()){//判断源文件是否存在
  19. return ERROR_FILE_NOT_EXIST;
  20. }else if(!fileExt.equals("pdf")){//判断文件是否是pdf格式的文件
  21. return ERROR_WRONG_EXT_NAME;
  22. }
  23. else{
  24. //" -Q 300"参数只在linux下有效
  25. command.append(HXConstants.PDF2SWF_PATH).append("pdf2swf").append(" -o ").append(destPath).append(" -T -z -t -f ").append(HXConstants.PDF2SWF_PATH.startsWith("/")?" -Q 300 ":"").append(fileName).append(" -s languagedir=").append(HXConstants.LANGDIR).append(" -s flashversion=9");
  26. pro = Runtime.getRuntime().exec(command.toString());
  27. buffer = new BufferedReader(new InputStreamReader(pro.getInputStream()));
  28. while(buffer.readLine()!=null);
  29. int rtstate = pro.waitFor();
  30. return rtstate;
  31. }
  32. }catch (Exception e){
  33. System.out.println(e.getMessage());
  34. return ERROR_HAS_EXCEPTION;
  35. }finally{
  36. command=null;
  37. pro=null;
  38. buffer=null;
  39. }
  40. }else{
  41. return ERROR_FILE_NOT_EXIST;
  42. }
  43. }
/** 

     * 将pdf文件转化成swf文件  

     * @param fileName 文件的绝对路径(含文件名和扩展名) 

     * @param destPath 目标路径 (目标文件夹,不含文件名)

     * @return -1:源文件不存在,-2:格式不正确,-3:发生异常,0:转化成功;1:无法打开文件(Process.exitValue())  

     * @author dongbai 

     */  

    public static int convertPdfToSwf(String fileName,String destPath){  

    if(null != fileName && fileName.length() > 0){

//          String destName = "";

            String fileExt = "";  

            StringBuffer command = new StringBuffer();  

            Process pro;

            BufferedReader buffer;

            fileExt = fileName.substring(fileName.lastIndexOf(".")+1, fileName.length()).toLowerCase();

            try{  

                File file = new File(fileName);  

                if(!file.exists()){//判断源文件是否存在   

                    return ERROR_FILE_NOT_EXIST;  

                }else if(!fileExt.equals("pdf")){//判断文件是否是pdf格式的文件                  

                  return ERROR_WRONG_EXT_NAME;  

                }  

                else{  

                  //" -Q 300"参数只在linux下有效

command.append(HXConstants.PDF2SWF_PATH).append("pdf2swf").append(" -o ").append(destPath).append(" -T -z -t -f ").append(HXConstants.PDF2SWF_PATH.startsWith("/")?" -Q 300 ":"").append(fileName).append(" -s languagedir=").append(HXConstants.LANGDIR).append(" -s flashversion=9");  

                 

                    pro = Runtime.getRuntime().exec(command.toString());  

                    buffer = new BufferedReader(new InputStreamReader(pro.getInputStream()));  

 

                    while(buffer.readLine()!=null);  

                    int rtstate = pro.waitFor();

                    return rtstate;

                }  

            }catch (Exception e){  

                System.out.println(e.getMessage());

                return ERROR_HAS_EXCEPTION;  

            }finally{

            command=null;

             pro=null;

            buffer=null;

            }

    }else{

        return ERROR_FILE_NOT_EXIST;

    }

    }  

 

 

 

代码片段说明:

(1)其中一些常量,可以自行定义,HXConstants.PDF2SWF_PATHHXConstants.LANGDIR分别定义swftool安装路径、中文支持安装路径,为了移植方便,可以配置在properties配置文件里,如:

oosyspath=C:/Program Files/OpenOffice.org 3/program/

pdf2swf=D:/SWFTools/

langdir=/usr/share/xpdf/xpdf-chinese-simplified

发布到linux环境后,修改配置文件即可。

(2)根据需要,可以追加参数,参考本文pdf2swf Tool参数详细说明。

(3) pro.waitFor()pro.exitValue()的区别,pro.exitValue可以异步处理,你可以根据需求而定。

5.Concurrent线程池实现

1)整体业务描述

(1)首先前台用户提交文档上传。

(2)后台异步处理上传文档。

(3)前台检查后台处理状态,处理完毕显示flexpaper效果,未处理完毕显示其他提示或处于加载中。

2Concurrent实现任务线程池

(1)实现抓取待处理的任务,放入BlockingQueue,避免重复抓取;

(2)实现多线程处理文档,线程从BlockingQueeu取出一个任务,处理完后把对应的文档数据置成处理完成状态。

见博客一个任务队列的BlockingQueue实现

6.FlexPaper源码初步说明及改造

1)研究历程

FlexPaper是一套开源系统,用于展示swftool生成的swf,通过参数设置能达到比较好的展示效果,FlexPaper遵循GNU GPL协议。项目地址:

http://code.google.com/p/flexpaper/

源码地址:

http://flexpaper.googlecode.com/svn/trunk/

如果你不介意FlexPaper播放的时候带有其自带的logo标签,下载trunk下的Example,里面有详细的例子。如果你要对播放器进行一些修改,比如要去掉其自带的logo,那就要对FlexPaper进行重新编译。可以看到trunk下有FlexPaper项目和FlexPaper_SDK4项目,两者的区别主要是Flex SDK版本,前者使用Flex SDK3.5,后者使用Flex SDK4及以上版本,其次FlexPaper_SDK4在我下载时还只有beta版,下载后导入4.0对应的FlexPaper_SDK4.swc编译不能通过,因此当前时间还是选择FlexPaper项目比较稳妥。在Eclipse(安装Flash Builder插件)下通过svn检出项目即可,检出后会自动成了Flex库项目,完成编译后,可以看到在目录bin下编译产生的FlexPaper.swc文件。

提示: 如果在编译过程中报错:1046: 找不到类型,或者它不是编译时常数: Vector

Flex编译器Adobe Flash Player选项选种:使用特定版本(v):10.0.0,而Flex3.5默认的设置是9.0.0

还需要在资源加入local\{local},如果编译还报local错误,那就把local直接拷贝到sdks\3.5.0\frameworks\local下。

弯路1:本人一开始以为直接生成FlexPaperViewer.swf,对检出Flex库项目很纳闷,然后就自己创建Flash web类型的项目,再通过svn检出,又手动把项目下的FlexPaperViewer.mxml设置成默认运行,这样是生成了FlexPaperViewer.swf,但打开FlexPaperViewer.swf发现只有灰色或黑色的背景。在浪费大半天时间后,在同事提醒下才搞明白原来此FlexPaperViewer.mxmlExample项目下直接编译生成的FlexPaperViewer.swf。这该死的命名,对刚接触的人来说是太容易产生联想了。

弯路2:那就自己写一个FlexPaperViewer.mxml,或者干脆不要取这个名也可以,容易产生混淆。网上找到一个,引入重新编译过的FlexPaper.swc,编译成功,打开后界面也出来了。但在加载指定的SwfFile时一直加载不出来,右上角的菊花一直在转。怀疑是不是自编译的FlexPaper.swc有问题,上官网下载官方的FlexPaper.swc,还是不行……,周末后家里的开发环境又折腾了大半天,中间还下了个flash反编译软件,打算对Example下的FlexPaperView.swf进行反编译,可惜目前大多反编译软件只有反编译成.fla.as,最终反编译也只能作罢。回到正路,终于找到比较完整的FlexPaperViewr.mxml

2) FlexPaperView.mxml的实现

完整代码:

 

Java代码 复制代码 收藏代码
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
  3. xmlns:fp="com.devaldi.controls.flexpaper.*"
  4. layout="absolute" width="100%" height="100%"
  5. applicationComplete="initApp();">
  6. <mx:Script>
  7. <![CDATA[
  8. import mx.controls.Alert;
  9. public var _aid = 0;//文档ID
  10. [Bindable]
  11. public var _Scale:Number = 1;//缩放比例
  12. [Bindable]
  13. public var _SwfFile:String = "";//SWF文件路径
  14. [Bindable]
  15. public var _ZoomTransition:String = "easeOut";
  16. [Bindable]
  17. public var _ZoomTime:Number = 0.6;
  18. [Bindable]
  19. public var _ZoomInterval:Number = 0.1;
  20. [Bindable]
  21. public var _FitPageOnLoad:Boolean = false;//加载后适合高度
  22. [Bindable]
  23. public var _FitWidthOnLoad:Boolean = false;//加载后适合宽度
  24. [Bindable]
  25. public var _PrintEnabled:Boolean = true;//是否支持打印
  26. [Bindable]
  27. public var _FullScreenAsMaxWindow:Boolean = false;//是否支付全屏
  28. [Bindable]
  29. public var _ProgressiveLoading:Boolean = false;//是否延迟加载
  30. [Bindable]
  31. public var _MinZoomSize:Number = 0.3;
  32. [Bindable]
  33. public var _MaxZoomSize:Number = 5;
  34. [Bindable]
  35. public var _SearchMatchAll:Boolean = false;
  36. [Bindable]
  37. public var _ViewModeToolsVisible:Boolean = true;
  38. [Bindable]
  39. public var _ZoomToolsVisible:Boolean = true;
  40. [Bindable]
  41. public var _NavToolsVisible:Boolean = true;
  42. [Bindable]
  43. public var _CursorToolsVisible:Boolean = true;
  44. [Bindable]
  45. public var _SearchToolsVisible:Boolean = true;
  46. [Bindable]
  47. public var _localeChain:String = "zh_CN";//语言
  48. private var isFocus:Boolean = false;
  49. //初始化参数
  50. private function initApp():void{
  51. var params:Object = Application.application.parameters;
  52. _Scale = getNumber(params, "Scale", 1);
  53. _SwfFile = getString(params, "SwfFile", "Paper.swf");
  54. _ZoomTransition = getString(params, "ZoomTransition", "easeOut");
  55. _ZoomTime = getNumber(params, "ZoomTime", 0.6);
  56. _ZoomInterval = getNumber(params, "ZoomInterval", 0.1);
  57. _FitPageOnLoad = getBoolean(params, "FitPageOnLoad", false);
  58. _FitWidthOnLoad = getBoolean(params, "FitWidthOnLoad", false);
  59. _PrintEnabled = getBoolean(params, "PrintEnabled", true);
  60. _FullScreenAsMaxWindow = getBoolean(params, "FullScreenAsMaxWindow", false);
  61. _ProgressiveLoading = getBoolean(params, "ProgressiveLoading", true);
  62. _MinZoomSize = getNumber(params, "MinZoomSize", 0.3);
  63. _MaxZoomSize = getNumber(params, "MaxZoomSize", 5);
  64. _SearchMatchAll = getBoolean(params, "SearchMatchAll", true);
  65. _ViewModeToolsVisible = getBoolean(params, "ViewModeToolsVisible", true);
  66. _ZoomToolsVisible = getBoolean(params, "ZoomToolsVisible", true);
  67. _NavToolsVisible=getBoolean(params,"NavToolsVisible",true);
  68. _CursorToolsVisible=getBoolean(params,"_CursorToolsVisible",true);
  69. _SearchToolsVisible=getBoolean(params,"_SearchToolsVisible",true);
  70. _localeChain = params["localeChain"];
  71. //注册事件监听
  72. this.addEventListener(MouseEvent.MOUSE_OVER, onMouseOver);
  73. this.addEventListener(MouseEvent.MOUSE_OUT, onMouseOut);
  74. //开放给外部(javascript)调用
  75. ExternalInterface.addCallback("hasFocus", hasFocus);
  76. //ExternalInterface.addCallback("focus", focus);
  77. ExternalInterface.addCallback("setViewerFocus", setViewerFocus);
  78. }
  79. private function onMouseOver(event:MouseEvent):void{
  80. this.isFocus = true;
  81. }
  82. private function onMouseOut(event:MouseEvent):void{
  83. this.isFocus = false;
  84. }
  85. public function hasFocus():Boolean{
  86. //Alert.show("hasFocus");
  87. return isFocus;
  88. }
  89. public function setViewerFocus(isFocus:Boolean):void{
  90. //Alert.show("setViewerFocus");
  91. this.paperViewer.setViewerFocus();
  92. }
  93. /**
  94. *
  95. * 获取String类型参数
  96. * 如果没有,则返回默认值
  97. **/
  98. private function getString(params:Object, name:String, def:String):String{
  99. if(params[name] != null){
  100. return params[name];
  101. }
  102. return def;
  103. }
  104. private function getNumber(params:Object, name:String, def:Number):Number{
  105. if(params[name] != null){
  106. return params[name];
  107. }
  108. return def;
  109. }
  110. private function getBoolean(params:Object, name:String, def:Boolean):Boolean{
  111. //Alert.show("比较:"+name);
  112. if(params[name] != null){
  113. return params[name] == "true";
  114. }
  115. return def;
  116. }
  117. ]]>
  118. </mx:Script>
  119. <!--mx:Panel x="165" y="76" width="250" height="200" layout="absolute" title="一个人">
  120. <mx:Label x="59" y="37" text="{Scale}" width="88"/>
  121. </mx:Panel-->
  122. <fp:FlexPaperViewer id="paperViewer"
  123. width="100%"
  124. height="100%"
  125. Scale="{_Scale}"
  126. SwfFile="{_SwfFile}"
  127. ZoomTransition="{_ZoomTransition}"
  128. ZoomTime="{_ZoomTime}"
  129. ZoomInterval="{_ZoomInterval}"
  130. FitPageOnLoad="{_FitPageOnLoad}"
  131. FitWidthOnLoad="{_FitWidthOnLoad}"
  132. FullScreenAsMaxWindow="{_FullScreenAsMaxWindow}"
  133. ProgressiveLoading="{_ProgressiveLoading}"
  134. MinZoomSize="{_MinZoomSize}"
  135. MaxZoomSize="{_MaxZoomSize}"
  136. SearchMatchAll="{_SearchMatchAll}"
  137. ViewModeToolsVisible="{_ViewModeToolsVisible}"
  138. ZoomToolsVisible="{_ZoomToolsVisible}"
  139. NavToolsVisible="{_NavToolsVisible}"
  140. CursorToolsVisible="{_CursorToolsVisible}"
  141. SearchToolsVisible="{_SearchToolsVisible}"
  142. />
  143. </mx:Application>
<?xml version="1.0" encoding="utf-8"?>   

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"  

                xmlns:fp="com.devaldi.controls.flexpaper.*"  

                layout="absolute" width="100%" height="100%"    

                applicationComplete="initApp();">   

    

    <mx:Script>   

        <![CDATA[   

            import mx.controls.Alert;   

            

            public var _aid = 0;//文档ID   

            

            [Bindable]   

            public var _Scale:Number = 1;//缩放比例   

            

            [Bindable]   

            public var _SwfFile:String = "";//SWF文件路径   

            

            [Bindable]   

            public var _ZoomTransition:String = "easeOut";   

            

            [Bindable]   

            public var _ZoomTime:Number = 0.6;   

            

            [Bindable]   

            public var _ZoomInterval:Number = 0.1;   

            

            [Bindable]   

            public var _FitPageOnLoad:Boolean = false;//加载后适合高度   

            

            [Bindable]   

            public var _FitWidthOnLoad:Boolean = false;//加载后适合宽度   

            

            [Bindable]   

            public var _PrintEnabled:Boolean = true;//是否支持打印   

            

            [Bindable]   

            public var _FullScreenAsMaxWindow:Boolean = false;//是否支付全屏   

            

            [Bindable]   

            public var _ProgressiveLoading:Boolean = false;//是否延迟加载   

            

            

            [Bindable]

            public var _MinZoomSize:Number = 0.3;

            

            [Bindable]

            public var _MaxZoomSize:Number = 5;

            

            [Bindable]

            public var _SearchMatchAll:Boolean = false;

            

            [Bindable]

            public var _ViewModeToolsVisible:Boolean = true;

            

            [Bindable]

            public var _ZoomToolsVisible:Boolean = true;

            

            [Bindable]

            public var _NavToolsVisible:Boolean = true;

            

            [Bindable]

            public var _CursorToolsVisible:Boolean = true;

            

            [Bindable]

            public var _SearchToolsVisible:Boolean = true;

            

            [Bindable]   

            public var _localeChain:String = "zh_CN";//语言   

            

            private var isFocus:Boolean = false;   

            

            //初始化参数   

            private function initApp():void{   

                var params:Object = Application.application.parameters;   

                _Scale = getNumber(params, "Scale", 1);   

                _SwfFile = getString(params, "SwfFile", "Paper.swf");   

                _ZoomTransition = getString(params, "ZoomTransition", "easeOut");   

                _ZoomTime = getNumber(params, "ZoomTime", 0.6);   

                _ZoomInterval = getNumber(params, "ZoomInterval", 0.1);   

                _FitPageOnLoad = getBoolean(params, "FitPageOnLoad", false);   

                _FitWidthOnLoad = getBoolean(params, "FitWidthOnLoad", false);   

                _PrintEnabled = getBoolean(params, "PrintEnabled", true);   

                _FullScreenAsMaxWindow = getBoolean(params, "FullScreenAsMaxWindow", false);   

                _ProgressiveLoading = getBoolean(params, "ProgressiveLoading", true); 

                _MinZoomSize = getNumber(params, "MinZoomSize", 0.3);   

                _MaxZoomSize = getNumber(params, "MaxZoomSize", 5);

                _SearchMatchAll = getBoolean(params, "SearchMatchAll", true);

                _ViewModeToolsVisible = getBoolean(params, "ViewModeToolsVisible", true);

                _ZoomToolsVisible = getBoolean(params, "ZoomToolsVisible", true); 

                _NavToolsVisible=getBoolean(params,"NavToolsVisible",true);

                _CursorToolsVisible=getBoolean(params,"_CursorToolsVisible",true);

                _SearchToolsVisible=getBoolean(params,"_SearchToolsVisible",true);

                

                _localeChain = params["localeChain"];   

                

                //注册事件监听   

                this.addEventListener(MouseEvent.MOUSE_OVER, onMouseOver);   

                this.addEventListener(MouseEvent.MOUSE_OUT, onMouseOut);   

                

                //开放给外部(javascript)调用   

                ExternalInterface.addCallback("hasFocus", hasFocus);   

                //ExternalInterface.addCallback("focus", focus);   

                ExternalInterface.addCallback("setViewerFocus", setViewerFocus);       

            }   

            

            

            

            private function onMouseOver(event:MouseEvent):void{   

                this.isFocus = true;   

            }   

            

            private function onMouseOut(event:MouseEvent):void{   

                this.isFocus = false;   

            }   

            

            public function hasFocus():Boolean{   

                //Alert.show("hasFocus");   

                return isFocus;   

            }   

            

            public function setViewerFocus(isFocus:Boolean):void{   

                //Alert.show("setViewerFocus");   

                this.paperViewer.setViewerFocus();   

            }   

            

            /**  

             *   

             * 获取String类型参数  

             * 如果没有,则返回默认值  

             **/  

            private function getString(params:Object, name:String, def:String):String{   

                if(params[name] != null){   

                    return params[name];   

                }   

                return def;   

            }   

            

            private function getNumber(params:Object, name:String, def:Number):Number{   

                if(params[name] != null){   

                    return params[name];   

                }   

                return def;   

            }   

            

            private function getBoolean(params:Object, name:String, def:Boolean):Boolean{   

                //Alert.show("比较:"+name);   

                if(params[name] != null){   

                    return params[name] == "true";   

                }   

                return def;   

            }   

        ]]>   

    </mx:Script>   

    <!--mx:Panel x="165" y="76" width="250" height="200" layout="absolute" title="一个人">   

    <mx:Label x="59" y="37" text="{Scale}" width="88"/>   

    </mx:Panel-->   

    

    <fp:FlexPaperViewer id="paperViewer"  

                        width="100%"    

                        height="100%"    

                        Scale="{_Scale}"    

                        SwfFile="{_SwfFile}"    

                        ZoomTransition="{_ZoomTransition}"    

                        ZoomTime="{_ZoomTime}"    

                        ZoomInterval="{_ZoomInterval}"  

                        FitPageOnLoad="{_FitPageOnLoad}"  

                        FitWidthOnLoad="{_FitWidthOnLoad}"    

                        FullScreenAsMaxWindow="{_FullScreenAsMaxWindow}"  

                        ProgressiveLoading="{_ProgressiveLoading}"

                        MinZoomSize="{_MinZoomSize}"

                        MaxZoomSize="{_MaxZoomSize}"

                        SearchMatchAll="{_SearchMatchAll}"

                        ViewModeToolsVisible="{_ViewModeToolsVisible}"

                        ZoomToolsVisible="{_ZoomToolsVisible}"

                        NavToolsVisible="{_NavToolsVisible}"

                        CursorToolsVisible="{_CursorToolsVisible}"

                        SearchToolsVisible="{_SearchToolsVisible}"

                        />   

</mx:Application>

 

 

3FlexPaper去掉logo实现

右上方的Logo修改:在FlexPaper项目的FlexPaperView.xml做修改,很容易找到;

右下方的Logo修改:在FlexPaper项目的Viewer.as,主要对成员变量_skinImgDo做注释,其中有一行代码addChildAt改成addChildAt (_paperContainer,1);

重新编译后,再次编译FlexPaperView.xml,在FlexPaperView.html传入正确的SwfFile参数,右角的转动菊花终于消失了,看到了想要的效果。

FlexPaper去logo版本,去掉了logo及打印按钮,去掉了右键的自定义菜单http://download.csdn.net/detail/klo0704/4186008

 

 

发布到正式环境问题的暴露及校正

在布署到正式环境过程中,发现两个问题

1)虽然openoffice通过rpm方式来安装都未出错,而且服务也能正常起来,但在java应用在执行调用createContext(int port)会出现退出线程的情况。查找了各种原因后,最后发现是因为测试环境安装了xwindow的原因,看来图形相关包的支持是必须的,如下:

yum install libXp

yum install libXtst

yum install libXp-devel

yum install libXau-devel

yum groupinstall "X Window System"

yum groupinstall "GNOME Desktop Environment"

yum install nc expect

yum install freenx

yum groupinstall chinese-support

2)Linux下openoffice服务需要启动

linux,安装完openoffice后,需要启动soffice服务:/opt/openoffice.org3/program/soffice -headless -accept="socket,host=127.0.0.1,port=8100;urp;"

-nofirststartwizard & 如没有启动服务,执行文档转换服务会出错。

分享到:
评论
2 楼 klo0704 2014-02-21  
这个我没有进行测试 过。
1 楼 leipan19890705 2013-07-24  
你好!请问你用OpenOffice将word等转换为pdf,会失真吗?我转的一些word文档里面有一些图表、公式,转出来就都成了空白的。你知道是什么原因吗?

相关推荐

Global site tag (gtag.js) - Google Analytics