首页 > 编程学习 > PDF在线阅读开发经验(FlexPaper+SWFTools+SaveAsPDFandXPS)
20106 月28

PDF在线阅读开发经验(FlexPaper+SWFTools+SaveAsPDFandXPS)

1、使用SaveAsPDFandXPS将office文档转换成PDF

http://www.microsoft.com/downloads/details.aspx?FamilyID=4d951911-3e7e-4ae6-b059-a2e79ed87041&displaylang=en

微软原计划让Office 2007直接支持保存为PDF格式,但引起了Adobe的不满,并被指责为垄断,最终被迫放弃,改为以插件的形式予以支持,插件大家都知道怎么回事儿,默认不装,要用你的自己找来装上。不过微软针对这件事情也做出了一个回应:发布XPS, XPS则是微软自己利用XML技术开发的新型文档格式。

该插件支持Office 2007的8个组件,包括Word、Excel、Access、PowerPoint、InfoPath、OneNote、Publisher和Visio。安装插件后,用户即可在上述组件中将相应文档存储为PDF格式或XPS格式,还可以方便地将文档保存为PDF/XPS格式的E-mail附件。

2、下载 SWFTools

SWFTools 是一组用来处理 Flash 的 swf 文件的工具包,包括:

1. 合并工具 swfcombine
2. 抽取工具 swfextract
3. PDF/JPEG/PNG/AVI/TTF/WAV 到 SWF 的转换工具 :pdf2swf, jpeg2swf, png2swf, avi2swf, font2swf, and wav2swf|
4. 文本解析工具 swfstrings
5. SWF 解析器 swfdump
6. SWF 读写库 rfxswflib

其中把pdf转成swf的工具就是pdf2swf了。在命令行中运行pdf2swf src.pdf des.swf一般能满足需求。而命令行参数可以通过pdf2swf -f得到:

-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 6的zlib压缩机制
-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图片的质量,从0到100,默认值是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. 如果运行时间超时则退出。

3、java程序,实现上传PDF自动转换成SWF文件

//ajax方法,先解密传过来的文件名,根据判断生成SWF文件后跳转至FLASH页面

if (ajaxAction.equals("exeflash"))   //把PDF成SWF
        {
            String fn = DecodeUtil.Decrypt(StringUtil.null2String(request.getParameter("fn")).trim()).toLowerCase();
            try {
                if (!"".equals(fn) && fn.indexOf("/") > -1 && fn.indexOf(".pdf") > -1) {
                    Map webfileupmap = (Map) Globals.SYS_UPLOAD_CONFIG.get("webfile");
                    String webfilepath = StringUtil.null2String(webfileupmap.get("path")).replace("\\", "\\\\");
                    fn = fn.substring(fn.lastIndexOf("/") + 1);//aa.pdf
                    webfilepath = webfilepath + fn;
                    File f = new File(webfilepath);
                    if (!f.exists()) {
                        return "error";
                        //如果PDF文件不存在则退出
                    }
                    Map webupmap = (Map) Globals.SYS_UPLOAD_CONFIG.get("web");
                    String webpath = StringUtil.null2String(webupmap.get("path")).replace("\\", "\\\\");
                    String urlpath = StringUtil.null2String(webupmap.get("urlpath"));
                    String wname = fn.substring(0, fn.indexOf(".")) + ".swf";
                    webpath = webpath + wname;
                    String wurl = urlpath + wname;
                    boolean issc = false;
                    File f2 = new File(webpath);
                    if (!f2.exists()) {
                        issc = true;
                        //如果文件不存在则生成
                    }
                    if (issc) {
                        String cmd = "C:\\SWFTools\\pdf2swf " + webfilepath + " -o " + webpath + " -T 9";
                        if (StringUtil.executeCmdFlash(cmd) == false) {
                            return "error";
                        }
                        System.out.println("cmd::::::" + cmd);
                    }

                    File f1 = new File(webpath);
                    if (f1.exists()) {
                        ajaxstr = DecodeUtil.Encrypt(wurl);
                    }

                } else {
                    return "error";
                }
            } catch (Exception e) {
                Globals.Logger("发生错误:" + e, 2);
            }

        }

注意:

String cmd = “C:\\SWFTools\\pdf2swf ” + webfilepath + ” -o ” + webpath + ” -T 9″;

加 “-T 9” 参数,设置输出版本为flash9,解决PDF文件只有一页,生成的swf不能播放的问题。

另外,若PDF内表格元素过多,在转换时会抛出一堆异常错误。似乎还没有好的解决办法?

//java调用cmd命令行方法

/**
     * 运行可执行文件
     *
     * @param cmd
     * @return String
     */
    public static synchronized boolean executeCmdFlash(String cmd) {

        try {
            final Process process = Runtime.getRuntime().exec(cmd);
            Runtime.getRuntime().addShutdownHook(new Thread() {
                public void run() {
                    process.destroy();
                }
            });
            InputStreamReader inputstreamreader = new InputStreamReader(process.getInputStream());
            char c = (char) inputstreamreader.read();
            if (c != '\uFFFF')
                stdout.append(c);
            while (c != '\uFFFF') {
                if (!inputstreamreader.ready()) {
                    System.out.println(stdout);
                    try {
                        process.exitValue();
                        break;
                    }
                    catch (IllegalThreadStateException _ex) {
                        try {
                            Thread.sleep(100L);
                        }
                        catch (InterruptedException _ex2) {
                        }
                    }
                } else {
                    c = (char) inputstreamreader.read();
                    stdout.append(c);
                }
            }
            try {
                inputstreamreader.close();
            }
            catch (IOException ioexception2) {
                System.err.println("RunCmd : Error closing InputStream " + ioexception2);
                return false;
            }
        } catch (Throwable e) {
            e.printStackTrace();
            Globals.Logger("发生错误:" + e, 2);
            return false;
        }

        return true;
    }

4、利用FlexPaper展示

FlexPaper是一个被设计用来与PDF2SWF一起使用,开源轻量级的在浏览器上显示各种文档的组件, 使在Flex中显示PDF成为可能,而这个过程并无需PDF软件环境的支持。它可以被当做Flex的库来使用。也可以通过将一些例如Word、PPT等文档转成PDF,然后实现在线浏览。

SwfFile : escape(host+"/upload/web/2010-05-24-10-21-51139.swf"),
      Scale : 0.6,
      ZoomTransition : "easeOut",
      ZoomTime : 0.5,
        ZoomInterval : 0.1,
        FitPageOnLoad : false,
        FitWidthOnLoad : true,
        PrintEnabled : false,
        FullScreenAsMaxWindow : true,
        localeChain: "zh_CN" //设置为中文
      };

5、演示地址

http://www.4th-games.org.cn/sis/public/info.html?doAction=scsg&bsdxid=1009&cdate=all

本文地址:https://wizzer.cn/archives/50 , 转载请保留.

49 Responses to “PDF在线阅读开发经验(FlexPaper+SWFTools+SaveAsPDFandXPS)”

  1. #1 leopoincare 回复 | 引用 Post:2010-07-31 15:37

    在jsp中如何调用啊,我尝试了一下,怎么加载不进去啊

    • #2 Wizzer 回复 | 引用 Post:2010-07-31 17:11

      1、检查swf文件是否生成成功本地可播放;2、检查路径是否正确。

  2. #3 openfans 回复 | 引用 Post:2010-09-08 20:10

    已经有个基于这套组合,做了一个网站OPEN开源文档http://doc.open-open.com。把各种文档转成flash还有另外一个工具叫Macromedia Flash Paper。也挺不错的。

    • #4 Wizzer 回复 | 引用 Post:2010-09-08 21:37

      看起来不错。:) 国内很多网站都是在此基础上开发的。~

  3. #5 涉古 回复 | 引用 Post:2010-10-08 16:38

    有没有碰到这样的问题,转换后,用flexpaper打开后,选中语句后,会选中很多空白的部分,尤其是字的上方,找了好久没有解决这个问题

  4. #7 姗姗来迟 回复 | 引用 Post:2010-11-19 15:47

    我在jsp中可以正常播放通过SWFTools生成的swf文件,我想知道,在jsp中能否通过js来控制swf文件的播放

    • #8 Wizzer 回复 | 引用 Post:2010-11-19 15:49

      本来就是JS控制的啊……不理解你的需求……(⊙_⊙)?

  5. #9 aq_li90 回复 | 引用 Post:2010-11-26 14:55

    我要做这样一个在线阅读器!
    但我下载flexpager后,连它的静态例子都打不开!
    这是为什么啊 ?

    页面上给的提示是:Can’t see the document? Running FlexPaper from your local directory? Make sure you have added FlexPaper as trusted. You can do that at Adobe’s website.

    • #10 Wizzer 回复 | 引用 Post:2010-11-28 03:24

      这个提示只有在本地运行的时候显示,意思是说本地运行要设置flash权限什么的,你放在网站上访问就不会提示了。

  6. #11 迷糊 回复 | 引用 Post:2010-12-03 18:57

    PrintEnabled设置为false右键仍然显示打印菜单,如何解决。谢谢

    • #12 Wizzer 回复 | 引用 Post:2010-12-04 10:52

      应该不会显示的,是否版本不对?你可以看下演示地址里的flash,已屏蔽打印,右击也没显示打印菜单。

  7. #15 低调求生存 回复 | 引用 Post:2011-03-23 15:33

    1楼的,你是用1.4.1版本对吧?这个版本我也无法禁用,但是下载1.4版本就可以.

  8. #16 leopoincare 回复 | 引用 Post:2011-04-11 12:47

    我的swf可以用ie打开,但是用flexPager载入后,就不能显示正确的页数了,我的swf是用swftool生成的,不知道哪个参数不对,就是不能正确显示,还有,我想把swf放在其他盘符中,在页面如何引用swf文件呢?

  9. #17 mumu 回复 | 引用 Post:2011-04-20 17:15

    这样的实现能够完成,随着滑动条实现只加载某几页这样的功能么!

    • #18 Wizzer 回复 | 引用 Post:2011-04-21 09:46

      估计要修改FLEX源码~

      • #19 大力水手 回复 | 引用 Post:2011-05-03 23:06

        我用的Flexpaper,用IE6.0打不开,傲游打开正常,不知道怎么回事?烦请赐教

  10. #21 changer 回复 | 引用 Post:2011-05-08 00:06

    Macromedia Flash Paper转换后有些swf文件flexpaper无法播放

  11. #23 benben 回复 | 引用 Post:2011-06-01 19:04

    LZ你好,我想用FLEXPAPER加载远程服务器端的SWF该怎么做?
    我已经用load加载到了页面中的SWF并可以用SWFLoader播放了。

    • #24 Wizzer 回复 | 引用 Post:2011-06-01 23:15

      记得当初研究过,好像同一个主机下可以加载,你可以尝试用不同的端口进行映射。

      • #25 benben 回复 | 引用 Post:2011-06-02 11:24

        hi Wizzer:很高兴你回帖这么迅速。
        paper有没有什么方法能加载数据流中的SWF吗?只能读取文件吗?我最终目的是想加载其它服务器上的SWF,我没用过端口映射,所以就用了URLload把服务器端的SWF给读过来了,读完了后我想文件应该是在内存里呢,我看paper现在只能是传给它一个本地路径才能读取到。我想请问有什么办法能让它读数据流中的SWF或者是让它支持URL路径?
        已经尝试的办法:
        1.loadSWF相关测试,只能读取本地文件。
        2.SWFfile相关测试,只能读取本地文件,并且不能用脚本代码设置该属性。??
        3.各种add测试,可以从数据流中把文件封装到group中然后用addchild加载进入paper。但无法对其进行任何操作。

        • #26 Wizzer 回复 | 引用 Post:2011-06-02 11:39

          我们的项目早已结束,没有更深入的研究,你可以到官网下载源码看看。

  12. #27 fxy 回复 | 引用 Post:2011-06-18 09:28

    -T 9 这个好 解决了我不能显示最后一页的问题 谢谢了哈

  13. #28 数据人生 回复 | 引用 Post:2011-07-07 16:39

    博主,我想请教一下,pdf2swf是否能够转换远程主机上的PDF文件,我试过一次,程序出错了,我不明白是否还需要其他的参数

  14. #30 BBCBBL 回复 | 引用 Post:2011-07-14 11:36

    请问我在查看源代码时候 可以获得swf的文件名 通过次路径可以单独访问改swf文件 怎么可以阻止单独访问swf文件?

    • #31 Wizzer 回复 | 引用 Post:2011-07-14 16:21

      囧,就算你隐藏了文件地址,在IE临时文件夹里还是存在的啊,偶没好的方法,你可以研究下?分享下。。

  15. #32 host 回复 | 引用 Post:2011-09-05 10:16

    escape里面的host是什么?

  16. #34 #33 回复 | 引用 Post:2011-09-27 14:31

    请问下excel转换成pdf的了,然后用swf播放,excel的行太多,然后就竖着往下显示,请问怎么控制让它横着显示呢?

  17. #35 ruby 回复 | 引用 Post:2012-04-27 16:20

    openfans :已经有个基于这套组合,做了一个网站OPEN开源文档http://doc.open-open.com。把各种文档转成flash还有另外一个工具叫Macromedia Flash Paper。也挺不错的。

    有类似问题啊。%>_<%

  18. #36 ruby 回复 | 引用 Post:2012-04-27 16:21

    涉古 :有没有碰到这样的问题,转换后,用flexpaper打开后,选中语句后,会选中很多空白的部分,尤其是字的上方,找了好久没有解决这个问题

    有同样问题啊,%>_<%

  19. #37 DuanHaisi 回复 | 引用 Post:2012-06-20 13:44

    嗨:我的项目使用java语言,tomcat服务器,我在jsp中加入了swf显示功能,但是swf文件在,服务器的某个文件下,请问怎么通过IP获取到,你:“escape里面的host是什么?囧 IP地址,如果是本地用相对路径就可以了。”能详细的举个例子吗?我调试了很久,但都失败,读取不到,IE显示一致在加载!

    • #38 Wizzer 回复 | 引用 Post:2012-06-20 14:58

      路径不对嘛~~相对路径不行就用绝对路径~有木有加端口号~

      • #39 DuanHaisi 回复 | 引用 Post:2012-06-20 15:06

        我是这样写的:
        SwfFile : escape(‘http://10.110.3.213:8080/upload/web/hibernate.swf’);你看一下这样可以么,麻烦帮修改一下;
        Tomcat配置虚拟目录,图片都可以加载到,你有具体的例子么,就是利用ip加载外部文件的;

        • #40 Wizzer 回复 | 引用 Post:2012-06-20 15:11

          你这个地址打不开吧,到官网 http://flexpaper.devaldi.com/?ref=FlexPaper 有例子。

          • #41 DuanHaisi 引用 Post:2012-06-20 15:14

            在IE中直接访问这个:http://10.110.3.213:8080/upload/web/hibernate.swf 是可以访问到的,官网的例子我下了,他的SWF文件是在工程下的,我想要将SWF文件放到系统的某个盘符下,你能帮修改一下上面的地址么?

          • #42 Wizzer 引用 Post:2012-06-20 15:20

            囧,不放在服务下面别人能访问么?host 是个JS变量可随便赋值,不要陷在这里。

          • #43 DuanHaisi 引用 Post:2012-06-20 15:18

            SwfFile : escape(host+”/upload/web/2010-05-24-10-21-51139.swf”)中:你说吧host换成IP,怎么换啊,写个具体的例子吧,非常感谢!

      • #44 DuanHaisi 回复 | 引用 Post:2012-06-20 15:26

        不管我是把IP定义成变量,还是写死,还是不好使。。。。。

      • #45 DuanHaisi 回复 | 引用 Post:2012-06-20 16:21

        帅哥,还在吗,我想通过IP读取到SWF文件,按你的写法都试过了,不行,IE一只在加载,还有没有别的方法了!

      • #46 DuanHaisi 回复 | 引用 Post:2012-06-21 14:03

        帅!我的问题已经解决,我把用来播放的SWF文件也通过IP的形式获取,就可以了,我感觉,这是adoba对文件信任度的处理,播放SWF文件和被播放的SWF文件放到一起就OK!希望碰到此类问题的哥们能看到!

        • #47 rongyimaohan 回复 | 引用 Post:2012-09-25 14:06

          DuanHaisi :
          帅!我的问题已经解决,我把用来播放的SWF文件也通过IP的形式获取,就可以了,我感觉,这是adoba对文件信任度的处理,播放SWF文件和被播放的SWF文件放到一起就OK!希望碰到此类问题的哥们能看到!

          请问你是怎么解决的?我没明白。我的生成的swf文件都是放在别的盘下的,有没有什么办法可以打开呢?

  20. #48 rongyimaohan 回复 | 引用 Post:2012-09-25 14:17

    我是用java作一个在线预览功能,现在的状况是,打开WebRoot下的已经存在的swf文件可以正常显示,但是我往WebRoot下传进新的swf文件时,就显示一直加载(找不到文件?),然后我刷新一下工程里的WebRoot(让那个swf文件刷新出来,显示在WebRoot下后),就可以打开并且显示。不知道这样的情况怎么解决。
    还有,如果我的swf文件放在了工程外面的话,有办法通过SwfFile:打开吗?

发表评论