2015-03-02 更新文章,由於需求修改,更改了flexpaper插件,故增加第9、10、11小節,下載代碼時請注意。
先廢話幾句。最近用到文檔在線瀏覽功能,之前用的是print2flash(一個工具,文檔直接轉flash,自帶翻頁搜索等一系列功能),由於無法與js進行交互,所以改用flexpaper。
由於之前沒接觸過Flex,了解不多,所以文章難免有不合適的地方。希望各位給予指正。
首先感謝ajava.org的mark,一系列文章有很多的幫助,少走很多彎路。
開發工具:1.Adobe Flash Builder 4.5。下載地址:http://trials3.adobe.com/AdobeProducts/FLBR/4_5/win32/FlashBuilder_4_5_LS10.exe (目前已失效)
2.Flash Player Debugger 。 下載地址:http://download.macromedia.com/pub/flashplayer/updaters/11/flashplayer_11_ax_debug.exe (目前已失效)
3.Flex項目用的是Flex SDK4.5。
如果你沒有Flex基礎或不了解FlexPaper,強烈推薦你參考mark的文章。
具體修改FlexPaper的步驟就不多說了,隨便百度一下,都是一大堆,具體的可以參閱mark的文章。PDF版下載
提供編譯后的文件下載(不帶間隔時間限制)。下載
修改后的FlexPaper項目文件下載(不帶間隔時間限制)。csdn資源 (如果沒有積分可以評論留下郵箱)
FlexPaper 2.1.2版本項目的源代碼,有bug。csdn資源
FlexPaper 2.1.2Demo。下載地址:https://code.google.com/p/flexpaper/downloads/detail?name=FlexPaper_2.1.2.zip&can=2&q=
下面說說主要內容。
1.去關於、Logo和打印功能可以參照mark系列的文章或者文末的鏈接
2.我修改的打印按鈕是可通過屬性進行控制的,默認不顯示
官網demo中要修改flexpaper.js中傳遞參數的地方,加入PrintEnabled和PrintVisible屬性。

1 window[instance] = flashembed(id, { 2 src : _jsDirectory+"../FlexPaperViewer.swf", 3 version : [10, 0], 4 expressInstall : "js/expressinstall.swf", 5 wmode : _WMode 6 },{ 7 ElementId : id, 8 SwfFile : _SWFFile, 9 PdfFile : _PDFFile, 10 IMGFiles : _IMGFiles, 11 JSONFile : _JSONFile, 12 useCustomJSONFormat : config.useCustomJSONFormat, 13 JSONPageDataFormat : config.JSONPageDataFormat, 14 JSONDataType : _JSONDataType, 15 Scale : (config.Scale!=null)?config.Scale:0.8, 16 ZoomTransition : (config.ZoomTransition!=null)?config.ZoomTransition:'easeOut', 17 ZoomTime : (config.ZoomTime!=null)?config.ZoomTime:0.5, 18 ZoomInterval : (config.ZoomInterval)?config.ZoomInterval:0.2, 19 FitPageOnLoad : (config.FitPageOnLoad!=null)?config.FitPageOnLoad:false, 20 FitWidthOnLoad : (config.FitWidthOnLoad!=null)?config.FitWidthOnLoad:false, 21 FullScreenAsMaxWindow : (config.FullScreenAsMaxWindow!=null)?config.FullScreenAsMaxWindow:false, 22 ProgressiveLoading : (config.ProgressiveLoading!=null)?config.ProgressiveLoading:false, 23 MinZoomSize : (config.MinZoomSize!=null)?config.MinZoomSize:0.2, 24 MaxZoomSize : (config.MaxZoomSize!=null)?config.MaxZoomSize:5, 25 SearchMatchAll : (config.SearchMatchAll!=null)?config.SearchMatchAll:false, 26 // PrintEnabled : (config.PrintEnabled!=null)?config.PrintEnabled:false, 27 // PrintVisible : (config.PrintVisible!=null)?config.PrintVisible:false, 28 SearchServiceUrl : config.SearchServiceUrl, 29 InitViewMode : config.InitViewMode, 30 BitmapBasedRendering : (config.BitmapBasedRendering!=null)?config.BitmapBasedRendering:false, 31 StartAtPage : config.StartAtPage, 32 PrintPaperAsBitmap : (config.PrintPaperAsBitmap!=null)?config.PrintPaperAsBitmap:false, 33 AutoAdjustPrintSize : (config.AutoAdjustPrintSize!=null)?config.AutoAdjustPrintSize:false, 34 35 EnableCornerDragging : ((config.EnableCornerDragging!=null)?config.EnableCornerDragging:true), // FlexPaper Zine parameter 36 BackgroundColor : config.BackgroundColor, // FlexPaper Zine parameter 37 PanelColor : config.PanelColor, // FlexPaper Zine parameter 38 BackgroundAlpha : config.BackgroundAlpha, // FlexPaper Zine parameter 39 UIConfig : config.UIConfig, // FlexPaper Zine parameter 40 41 ViewModeToolsVisible : ((config.ViewModeToolsVisible!=null)?config.ViewModeToolsVisible:true), 42 ZoomToolsVisible : ((config.ZoomToolsVisible!=null)?config.ZoomToolsVisible:true), 43 NavToolsVisible : ((config.NavToolsVisible!=null)?config.NavToolsVisible:true), 44 CursorToolsVisible : ((config.SearchToolsVisible!=null)?config.CursorToolsVisible:true), 45 SearchToolsVisible : ((config.SearchToolsVisible!=null)?config.SearchToolsVisible:true), 46 StickyTools : config.StickyTools, 47 Toolbar : config.Toolbar, 48 DocSizeQueryService : config.DocSizeQueryService, 49 50 RenderingOrder : config.RenderingOrder, 51 52 localeChain : (config.localeChain!=null)?config.localeChain:"en_US", 53 jsDirectory : _jsDirectory, 54 cssDirectory : _cssDirectory, 55 localeDirectory : _localeDirectory, 56 key : config.key 57 });
調用的地方:

1 $('#documentViewer').FlexPaperViewer( 2 { config : { 3 DOC : escape(getDocumentUrl(startDocument)), 4 Scale : 2, 5 ZoomTransition : 'easeOut', 6 ZoomTime : 0.5, 7 ZoomInterval : 0.2, 8 FitPageOnLoad : true, 9 FitWidthOnLoad : false, 10 FullScreenAsMaxWindow : false, 11 ProgressiveLoading : false, 12 MinZoomSize : 0.2, 13 MaxZoomSize : 5, 14 SearchMatchAll : false, 15 // PrintEnabled:false, 16 // PrintVisible:true, 17 InitViewMode : 'Portrait', 18 RenderingOrder : '<%=(configManager.getConfig("renderingorder.primary") + ',' + configManager.getConfig("renderingorder.secondary")) %>', 19 20 ViewModeToolsVisible : true, 21 ZoomToolsVisible : true, 22 NavToolsVisible : true, 23 CursorToolsVisible : true, 24 SearchToolsVisible : true, 25 26 DocSizeQueryService : 'services/swfsize.ashx?doc=' + startDocument, 27 jsDirectory : 'js/', 28 29 JSONDataType : 'jsonp', 30 key : '<%=configManager.getConfig("licensekey") %>', 31 32 localeChain: 'zh_CN' 33 34 }} 35 );
3.修改搜索bug
2.1.2版本的源碼搜索中有Bug.第一次和第二次搜索的結果並存。修改后的版本修復整個文件搜索。
但是分頁加載時搜索只能搜索當前頁,官網Demo也是這樣,Flex一竅不通,不知如何修改。囧。。。
修改View.as中searchText函數中for循環部分。改為:

1 if(clearmarklist){ 2 if(_markList!=null){ 3 for(var i:int=0;i<_markList.length;i++){ 4 if(_markList[i]!=null && _markList[i].parent !=null){ 5 // for(var ic:int=0;ic<_markList[i].numChildren;ic++){ 6 // if(_markList[i].getChildAt(ic) is SearchShapeMarker){ 7 // _markList[i].removeChildAt(ic); 8 // } 9 // } 10 _markList[i].parent.removeChild(_markList[i]); 11 } 12 } 13 } 14 15 _markList = new Array(numPages); 16 }
4.修改縮略圖bug
當時遇到這問題的時候,百度了一下,說替換googlecode中的SDK3.5的swc就可以。但是失敗。
自己嘗試修改,發現把Flex項目屬性>Flex編譯器>Flex SDK版本>”使用兼容Flex 3兼容模式“,然后會報錯,再將FlexPaperViewer_Base.mxml中第9行的borderThickness="1"更改為如下四個屬性即可:
paddingBottom="0"
paddingLeft="0"
paddingRight="0"
paddingTop="0"
5.添加按鈕
修改FlexPaperViewer.mxml中<mx:HBox>節點代碼。例如我加的一個書簽按鈕。

<mx:HBox styleName="toolbarBackground" width="100%" height="26" borderStyle="solid" verticalScrollPolicy="off" horizontalScrollPolicy="off" paddingTop="2" paddingLeft="2" horizontalGap="3"> <st:GradientImageButton id="PrintButton" icon="{MenuIcons.PRINT_ICON}" styleName="toolbttn" width="20" click="printPaper(event)" toolTip="@Resource(key='Print', bundle='FlexPaper')" visible="{PrintVisible}" includeInLayout="{!ReadOnly}" enabled="{PrintEnabled}" /> <mx:Image id="PrintBar" source="{MenuIcons.BAR}" width="3" height="21" includeInLayout="{!ReadOnly}" visible="{PrintVisible}" /> <st:GradientImageButton icon="@Embed('../src/img/bookmarks.png')" styleName="toolbttn" width="20" click="paper1.bookMarks();" toolTip="@Resource(key='BookMarks', bundle='FlexPaper')" tabIndex="1" visible="{ViewModeToolsVisible}" includeInLayout="{ViewModeToolsVisible}"/>
6.javascript與Flex交互
javascript交互分兩種情況,1是Flex調js,2是js調用Flex。
可以參考:http://www.cnblogs.com/tiandi/archive/2012/06/03/2532977.html
http://wymsxty.blog.163.com/blog/static/77790858201083045541915/
http://blog.csdn.net/kunoy/article/details/7903258 這里js調用Flex的時候,javascript可能會報錯。即window.FlexPaperViewer_Instance.getApi()中FlexPaperViewer_Instance會是undefined。我沒找到什么原因。可參照上面兩種,記得引入swfobject.js。
7.去右鍵菜單
注釋掉FlexPaperViewer_Base.mxml中所有contextMenu.customItems.push()的代碼。contextMenu.clipboardMenu三行屬性都改為false.

1 contextMenu.clipboardMenu = false;//是否使用剪貼板菜單 2 contextMenu.clipboardItems.copy = false; 3 contextMenu.clipboardItems.selectAll = false;
8.書簽功能
書簽功能原理是點擊按鈕,獲取當前頁數,然后需要和Js進行交互,Js保存當前頁數。
按鈕添加在FlexPaperViewer.mxml中<mx:HBox> 節點中:

<st:GradientImageButton icon="@Embed('../src/img/bookmarks.png')" styleName="toolbttn" width="20" click="paper1.bookMarks();" toolTip="@Resource(key='BookMarks', bundle='FlexPaper')" tabIndex="1" visible="{ViewModeToolsVisible}" includeInLayout="{ViewModeToolsVisible}"/>

public function bookMarks():void{ var m:String = ExternalInterface.call("ShowCurrentPage",_currPage); trace(m); }
通過js和按鈕進行交互。
以下內容為更新內容,更新時間:2015-03-02,文中所指行數為修改代碼的行數。
9.去掉右側滾動條和工具欄文本框
由於需要增加現有需求,需要增加翻頁時間間隔功能,所以添加9和10 兩小節內容。
屏蔽右側滾動條,修改內容Viewer.as文件中createDisplayContainer 方法(1508行,_paperContainer 變量實例化之后),添加:
//屏蔽右側滾動條 _paperContainer.verticalScrollPolicy="off";
替換工具欄文本框防止翻頁,修改FlexPaperViewer.mxml中<mx:HBox/> 節點中:

<!-- 屏蔽切換頁--> <!--<st:GradientTextInput id="txtPage" visible="{NavToolsVisible}" width="45" height="21" enabled="{paper1.ViewMode == ViewModeEnum.PORTRAIT||paper1.ViewMode == ViewModeEnum.TWOPAGE||paper1.ViewMode == ViewModeEnum.SINGLEPAGE}" fontSize="9" includeInLayout="{NavToolsVisible}" keyDown="txtPageNumKeyDown(event)" tabIndex="12" text="{formatPageNumber(paper1.currPage)}" toolTip="@Resource(key='Current Page', bundle='FlexPaper')"/>--> <!-- 修改切換頁為文本--> <st:GradientLabel id="txtPage" visible="{NavToolsVisible}" width="45" height="21" paddingTop="2" enabled="{paper1.ViewMode == ViewModeEnum.PORTRAIT||paper1.ViewMode == ViewModeEnum.TWOPAGE||paper1.ViewMode == ViewModeEnum.SINGLEPAGE}" fontSize="9" includeInLayout="{NavToolsVisible}" tabIndex="12" text="{formatPageNumber(paper1.currPage)}" toolTip="@Resource(key='Current Page', bundle='FlexPaper')"/>
10.增加翻頁間隔
增加翻頁間隔,用到計時器,而且開放給外部js傳參,固定間隔時間。
- 首先在默認包中FlexPaperViewer.mxml文件中定義外部調用參數(62行)
[Bindable] public var _IntervalSecond:Number = 0;
在InitApp方法中獲取Js傳的值,默認值為5(116行).
_IntervalSecond = getNumber(params,"IntervalSecond",5);
在FlexPaperViewer_Base.mxml文件中定義變量,供傳值(141行)
[Bindable] public var IntervalSecond:Number=0;
在FlexPaperViewer.mxml文件末尾的<fp:FlexPaperViewer />中傳參給FlexPaperViewer_Base。
IntervalSecond="{_IntervalSecond}"
- 在FlexPaperViewer_Base.mxml同級目錄中的FlexPaperViewer.mxml文件中添加如下變量和方法(207行):
//計時器參數 public var pstartTime:Number = 0; public var pstarttimer:Timer; //上次閱讀到的頁數 public var lastPageNumber:Number=0; /** * 開始計時 */ public function funTimer(event:TimerEvent):void{ pstartTime++; } /** * 停止計時 並歸0 */ public function PageTimerReset():void{ pstarttimer.reset(); pstartTime = 0; pstarttimer.start(); } //上次閱讀頁數 private var _oldpage:Number=1; //是否已顯示alert private var isShowAlert:Boolean=false; // 關閉后觸發的事件 private function alertClickFirst(event:CloseEvent):void { isShowAlert=false; //跳轉指定頁 paper1.gotoPage(_oldpage); }
在initApp方法中添加計時器啟動代碼(64行):
public function initApp():void { //去除LOGO paper1.removeElementAt(2); //初始化,計時器操作 pstarttimer=new Timer(1000);//1000是指1秒 pstarttimer.addEventListener(TimerEvent.TIMER, funTimer); pstarttimer.start(); }
修改formatPageNumber方法(243行):
protected function formatPageNumber(n:Number):String { //如果已彈窗,不繼續執行 if(isShowAlert) return _oldpage.toString(); //如果當前頁面不等於上次打開的頁面,並且當前頁面大於上次打開頁面,並且時間小於設定間隔,開始提醒 if(n!=1 && n!=_oldpage && n>lastPageNumber && pstartTime<IntervalSecond) { //如果已經彈窗,就不再彈窗 if(!isShowAlert){ isShowAlert=true; Alert.show("讀書有三到,謂心到,眼到,口到。","", Alert.OK , this, alertClickFirst); } return _oldpage.toString(); } else { if(_oldpage!=n) //計時器重啟 PageTimerReset(); _oldpage=n; if(n>lastPageNumber) lastPageNumber=n; if(viewer.ViewMode == ViewModeEnum.TWOPAGE) return viewer.currPage.toString() + "-" + (viewer.currPage+1).toString(); else return n.toString(); } }
11.增加上次閱讀到xx功能
由於添加此功能,所以帶翻頁間隔的代碼中就屏蔽掉了書簽按鈕。
這里的記錄頁數,是通過Js和FlexPaper進行交互獲取,需要你自己處理保存在服務器中。
在默認包中FlexPaperViewer.mxml中定義_StartPage 變量,並在initApp方法中進行獲取Js傳的值,最后傳遞給FlexPaperViewer_Base中,同第10節定義變量。
[Bindable] public var _StartPage:Number; ... _StartPage=getNumber(params,"StartPage",1); ... StartAtPage="{_StartPage}"
在FlexPaperViewer_Base.mxml中修改viewercreationCompleteHandler(205行) 和documentLoadedHandler(426行)方法:

private function viewercreationCompleteHandler(e:FlexEvent):void{ if(_documentLoadedFirst && !_stageinitialized){ dispatchEvent(new DocumentLoadedEvent(DocumentLoadedEvent.DOCUMENT_LOADED,viewer.numPages)); if(StartAtPage!=1&&!isNaN(StartAtPage)&&StartAtPage>0){ viewer.gotoPage(StartAtPage); } //flash.utils.setTimeout(function():void{ if(StartAtPage!=1&&!isNaN(StartAtPage)&&StartAtPage>0){viewer.gotoPage(StartAtPage);StartAtPage=-1;} //},1000); } _stageinitialized = true; }

protected function documentLoadedHandler(event:Event):void{ if(_stageinitialized){ dispatchEvent(event); if(StartAtPage!=1&&!isNaN(StartAtPage)&&StartAtPage>0){viewer.gotoPage(StartAtPage);} flash.utils.setTimeout(function():void{ if(StartAtPage!=1&&!isNaN(StartAtPage)&&StartAtPage>0){viewer.gotoPage(StartAtPage);StartAtPage=-1;} },1000); }else{ _documentLoadedFirst = true; } }
在FlexPaperViewer_Base.mxml同級目錄下FlexPaperViewer.mxml中<mx:HBox />節點下增加(用於顯示提示信息):

<mx:HBox id="TitileBox" width="99%" backgroundColor="#FFF9F2" borderColor="#F6CB1E" textAlign="center"> <mx:Label id="lblTitleMsg" width="90%" buttonMode="true" click="lblTitleMsg_clickHandler()" fontSize="15" mouseChildren="false" useHandCursor="true"/> <mx:Label id="lblCloseMsg" width="20" buttonMode="true" click="lblCloseMsg_clickHandler()" fontSize="20" mouseChildren="false" text="×" toolTip="關閉提示" useHandCursor="true"/> </mx:HBox>
在FlexPaperViewer.mxml中 定義跳轉和關閉方法(282行):

protected function lblCloseMsg_clickHandler():void { TitileBox.removeAllElements(); } protected function lblTitleMsg_clickHandler():void { paper1.gotoPage(1); }
修改documentLoadedHandler 方法(114行):

protected override function documentLoadedHandler(event:Event):void{ spin1.visible = false; lblProgress.visible = false; spin1.stop(); bttnInfo.visible =false; super.documentLoadedHandler(event); if(StartAtPage==1 || isNaN(StartAtPage) || StartAtPage==0) TitileBox.removeAllElements(); else { _oldpage=StartAtPage; lblTitleMsg.text="您上次閱讀到第 "+StartAtPage+" 頁,點擊這里返回第 1 頁"; } }
帶翻頁間隔二次開發源代碼:下載
編譯過版本:下載
2015-03-02 更新內容完
另外推薦幾篇關於FlexPaper的博客:
flexPaper簡單二次開發:http://www.cnblogs.com/longjunhao00/archive/2012/11/22/2782036.html
FlexPaper閱讀器開發手冊(原創) :http://wujwmail.blog.163.com/blog/static/17055443320119532652421/
FlexPaper二次開發問題及搜索高亮顯示:http://www.cnblogs.com/zamlove/archive/2013/05/07/3065079.html
FlexPaper初步使用時遇到的問題解決:http://blog.sina.com.cn/s/blog_673c98be0101b49m.html
轉載請注明出處:http://www.cnblogs.com/xcong/p/3142155.html