最近在項目中遇到文檔預覽的需求,和PM商討了幾種解決方案,最終還是選中了轉爲SWF的方式。下面就稍微記錄一下自己的學習成果。
工具:pdf2swf 下載地址:http://www.swftools.org/download.html
安裝完成後,在安裝目錄下可以看到N個單獨可以運行的exe文件:
提供了多種格式轉swf的功能,不過這裏我只用了pdf2swf這一個,在我的項目裏有一個service會將上傳的文件直接轉成pdf保存一個副檔,需要預覽的時候,直接獲取這個pdf的副檔就OK。
下面看C#代碼:
public class PDF2Swf { #region //根目錄 private static string ROOT_PATH = AppDomain.CurrentDomain.BaseDirectory; //pdf轉swf private static string PDF2SWF_PATH = "Shells\\SWFTools\\pdf2swf.exe"; //合併swf private static string SWFCOMBINE_PATH = "Shells\\SWFTools\\swfcombine.exe"; //導航 private static string SWFVIEWER_PATH="Shells\\SWF\\rfxview.swf"; private static string SWFTEMP_PATH = "Shells\\SWF\\temp.swf"; //保存轉成功的swf文件 public static string SAVE_SWF_PATH = "Shells\\SWF\\preview.swf"; //保存FLM上的PDF文檔 public static string SAVE_PDF_PATH = "Shells\\PDF\\preview.pdf"; //語言包路徑 private static string XPDF_LANG_PATH = ConfigReader.ReadValue<string>("XPDF_LANG_PATH"); public static string PREVIEW_PAGE_PATH = "Shells\\SWF\\preview.html"; #endregion ///<summary> /// swf格式文件播放 ///</summary> ///<param name="url"></param> ///<param name="width"></param> ///<param name="height"></param> ///<returns></returns> public static string AddSwf(string url) { System.Text.StringBuilder sb = new System.Text.StringBuilder(); sb.Append("<OBJECT codeBase='http://active.macromedia.com/flash5/cabs/swflash.cab#version=8,0,0,0'"); sb.Append(" height='100%' width='100%' classid='clsid:D27CDB6E-AE6D-11cf-96B8-444553540000'>"); sb.Append("<PARAM NAME='Movie' VALUE='" + url + "'>"); sb.Append("<PARAM NAME='Play' VALUE='true'>"); sb.Append("<PARAM NAME='Loop' VALUE='true'>"); sb.Append("<PARAM NAME='Quality' VALUE='High'>"); sb.Append("<PARAM NAME='FLASHVARS' VALUE='zoomtype=3'>"); sb.Append("<embed src='" + url + @"' height='100%' height='100%' play='true' ALIGN='' loop='true' quality='high' pluginspage='http://www.macromedia.com/go/getflashplayer' type='application/x-shockwave-flash' flashvars='zoomtype=3'>"); sb.Append("</embed>"); sb.Append("</OBJECT>"); return sb.ToString(); } ///<summary> /// 傳入PDF的文件路徑,以及輸出文件的位置,執行pdf2swf的命令 ///</summary> ///<param name="strPDFPath"></param> ///<param name="strSwfPath"></param> public static bool DoPDF2Swf(string strPDFPath, string strSwfPath) { bool isSuccess = false; //如果PDF不存在 if (!File.Exists(strPDFPath)) { return false; } #region 清理之前的記錄 if (File.Exists(strSwfPath)) { //已經存在,刪除 File.Delete(strSwfPath); } if (File.Exists(GetPath(SWFTEMP_PATH))) { File.Delete(GetPath(SWFTEMP_PATH)); } #endregion //將pdf文檔轉成temp.swf文件 string strCommand = String.Format("{0} -T 8 -s languagedir={3} {1} -o {2}", GetPath(PDF2SWF_PATH),strPDFPath, GetPath(SWFTEMP_PATH),XPDF_LANG_PATH); double spanMilliseconds = RunShell(strCommand); //第一步轉檔失敗,則返回 if (!File.Exists(GetPath(SWFTEMP_PATH))) { return false; } //將temp.swf加入到rfxview.swf加入翻頁的導航 strCommand = String.Format("{0} {1} viewport={2} -o {3}", GetPath(SWFCOMBINE_PATH),GetPath(SWFVIEWER_PATH),GetPath(SWFTEMP_PATH),strSwfPath); spanMilliseconds = RunShell(strCommand); if (File.Exists(strSwfPath)) { isSuccess = true; } return isSuccess; } ///<summary> /// 獲取文件全路徑 ///</summary> ///<param name="path"></param> ///<returns></returns> public static string GetPath(string path) { //HttpContext.Current.Server.MapPath(path); return String.Format("{0}{1}", ROOT_PATH, path); } ///<summary> /// 運行命令 ///</summary> ///<param name="strShellCommand">命令字符串</param> ///<returns>命令運行時間</returns> private static double RunShell(string strShellCommand) { double spanMilliseconds = 0; DateTime beginTime = DateTime.Now; Process cmd = new Process(); cmd.StartInfo.FileName = "cmd.exe"; cmd.StartInfo.UseShellExecute = false; cmd.StartInfo.CreateNoWindow = true; cmd.StartInfo.Arguments = String.Format(@"/c {0}", strShellCommand); cmd.Start(); cmd.WaitForExit(); cmd.Close(); DateTime endTime = DateTime.Now; TimeSpan timeSpan = endTime - beginTime; spanMilliseconds = timeSpan.TotalMilliseconds; return spanMilliseconds; } ///<summary> /// 根據DownLoadURL從FLM獲取資料,保存PDF文檔到指定位置,返回文件的路徑 ///</summary> ///<param name="strDownLoadUrl"></param> ///<returns></returns> public static string SavePDF(string strDownLoadUrl) { try { //截取FLM的FileID string strFileID = strDownLoadUrl.Substring(strDownLoadUrl.LastIndexOf('=')+1); string strFileName = ""; AttachService service = new AttachService(); byte[] pdfBuffer = service.GetFileByte(strFileID, ref strFileName, "Y",Utility.GetProfile().englishName); string strPhysicalPDFPath = GetPath(SAVE_PDF_PATH); //如果已經有存在則先刪掉 if (File.Exists(strPhysicalPDFPath)) { File.Delete(strPhysicalPDFPath); } //建一個PDF文檔,將文件流寫入文件保存 FileStream fs = new FileStream(strPhysicalPDFPath, FileMode.Create, FileAccess.Write); fs.Write(pdfBuffer, 0, pdfBuffer.Length); fs.Close(); return strPhysicalPDFPath; } catch (Exception ex) { throw new Exception("保存PDF文檔失敗:"+ex.Message); } } ///<summary> /// 保證當前的文件名唯一 ///</summary> ///<returns></returns> private static string GetPDFName() { return DateTime.Now.ToLongTimeString().Replace(':','_')+DateTime.Now.Millisecond; } }
使用的時候調用DoPDF2Swf(string strPDFPath, string strSwfPath)傳入pdf以及輸出的swf路徑,
任務會先調用pdf2swf.exe將pdf文檔轉成temp.swf文件:
pdf2swf [-options] file.pdf -o file.swf
然後再調用swfcombine.exe合併tmep.swf以及rfxview.swf文件,輸出到preview.swf文件:
swfcombine.exe rfxview.swf viewport={tmep.swf} -o {preview.swf}
最後在頁面中呈現。
1 <html> 2 3 <body style="padding: 0px; margin: 0px"> 4 5 <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" 6 width="100%" 7 height="100%" 8 9 codebase="http://active.macromedia.com/flash5/cabs/swflash.cab#version=8,0,0,0"> 10 11 <param name="MOVIE" value="preview.swf"> 12 13 <param name="PLAY" value="true"> 14 15 <param name="LOOP" value="true"> 16 17 <param name="QUALITY" value="high"> 18 19 <param name="FLASHVARS" value="zoomtype=3"> 20 21 <embed src="preview.swf" width="100%" 22 height="100%" 23 play="true" ALIGN="" loop="true" quality="high" 24 type="application/x-shockwave-flash" 25 26 flashvars="zoomtype=3" 27 pluginspage="http://www.macromedia.com/go/getflashplayer"> 28 29 </embed> 30 </object> 31 </body> 32 </html>
最終頁面呈現效果:
第二篇 此文所參考 文章
前幾天使用PDF2SWF實現了項目中的一個預覽的小功能,後期遇到中文內容無法成功顯示的Bug,困擾的不輕,網上也搜到不少資料,但是當時是在公司裏處理問題,很多網上資源被公司屏蔽,導致遲遲不能奏效,最後折騰了大半天,才實現功能,下面詳細總結一下。
準備資料:
1.xpdfbin-win-3.03.zip、xpdf-chinese-simplified.tar.gz
下載地址:http://www.foolabs.com/xpdf/download.html
2.兩個中文字體文件:gkai00mp.ttf、Gbsn00lp.ttf
下載地址:http://code.google.com/p/atyu30/downloads/detail?name=gbsn00lp.ttf.tar.gz&can=2&q=
http://download.csdn.net/detail/blackjack2007u/1841186(不要罵我,被逼無奈好不容易在CSDN找到這個下載地址)
3.加上PDF2SWF工具http://www.swftools.org/download.html
首先安裝SWFTools,不考慮中文的情況下,一個pdf2swf.exe已經足夠我們使用轉換任務。
下面集中精力解決中文字符的問題。
1.解壓縮xpdfbin-win-3.03.zip到指定目錄(C:\xpdf)
2.解壓縮xpdf-chinese-simplified.tar.gz 到上面的目錄下(C:\xpdf\xpdf-chinese-simplified)
3.拷貝兩個字體文件gkai00mp.ttf、Gbsn00lp.ttf到CMap目錄下(C:\xpdf\xpdf-chinese-simplified\CMap)
4.修改C:\xpdf\xpdf-chinese-simplified下的add-to-xpdfrc文件<注意相關路徑配置>
在普通的pdf2swf -o {0} -t {1} 形式的命令後,加上一個-s 指定languagedir,就可以成功解決中文PDF2SWF的問題啦!