相關專題鏈接
前言:上一篇中介紹了上傳的文件轉PDF,主要是一些常用的文檔格式轉換為PDF;這一篇主要介紹如何把PDF轉換為SWF,為下一步文件在線瀏覽做准備;
PDF在線瀏覽的主要以下幾種方式:
1、PDF瀏覽器插件
這種方式依賴PDF閱讀器廠商提供的瀏覽器插件,主流的PDF閱讀器如Adobe、福昕在安裝本地客戶端的時候都會附帶安裝這種控件,直接把本地的PDF文件拖到瀏覽器即可看到效果,如下:
如上圖所示,不同閱讀器的插件功能差異較大,不同的瀏覽器效果也有不同,無法保證有一個統一的展現效果,而且這種方式必須依賴客戶機安裝上述軟件,有很大的局限性;
2、使用Jquery插件
這種方式大部分都依賴html5技術,鑒於目前國內的瀏覽器市場占比,這種方式顯示極其小眾,這里就不再介紹了,有興趣的可以參考:8個實現在線瀏覽PDF文件的實用jQuery插件
3、通過轉換為SWF來實現
雖然html5技術正在興起,但在目前flash依然受支持比較廣泛的技術,通過Flash控件也保證了不同瀏覽器相同的展示效果,一些開源的前端控件也提供很好的SWF在線瀏覽體驗,所以這里我們就重點介紹這種實現方式;
PDF轉SWF
這里采用開源軟件swftools,它支持把PDF、圖片、聲音等文件轉換為SWF文件,並且提供windows和linux版本,可以在linux環境部署;
swftools下載地址:http://www.swftools.org/download.html
下載安裝后就可以通過命令行的方式進行調用,pdf2swf提供很多的參數來進行配置,常用的如-p設置打開pdf的密碼,-z使用Flash 6的zlib壓縮機制,-s設置更信息的參數(可以通過pdf2swf -s help來獲取更詳細的參數信息),-o輸出swf文件位置等:
下面就通過Java代碼啟動系統進程的方式來調用pdf2swf命令進行轉換,Java在啟動進程成功后就會返回,而實際上我們希望等待文件轉換成功后程序再返回,此時就需要用到Process
類了,在Java文檔提到“ProcessBuilder.start() 和 Runtime.exec 方法創建一個本機進程,並返回 Process 子類的一個實例,該實例可用來控制進程並獲得相關信息”,利用這一點我們可以獲取文件轉換的信息並可以讓程序再系統進程結束后再返回,代碼中的dealWith方法就是對Process,詳細轉換代碼如下:
/** * 把pdf轉換為swf * @param pdfPath pdf文件路徑 * @throws Exception */ public static boolean convert2SWF(String pdfPath) throws Exception { String swfFile = pdfPath.substring(0, pdfPath.lastIndexOf(".")) + ".swf"; File outFile = new File(swfFile); if (outFile.exists()) { return true; } File pdfFile = new File(pdfPath); if (!pdfFile.exists()) { return false; } //創建調用swftools命令list List<String> command = new ArrayList<String>(); command.add("c:\\SWFTools\\pdf2swf");//pdf2swf命令路徑 command.add("-z"); command.add("-s"); command.add("flashversion=9"); command.add("-s"); command.add("languagedir=C:\\xpdf\\xpdf-chinese-simplified");//添加xpdf解決轉換時出現的字符集問題 command.add(pdfPath); command.add("-o"); command.add(swfFile); /** * java啟動系統進程時,啟動成功后就直接返回了,並不會等待系統進程執行結束,這里我們需要等待系統進程調用結束后java方法再返回 */ try { //創建系統進程 ProcessBuilder processBuilder = new ProcessBuilder(); processBuilder.command(command);//設置系統進程要執行的系統程序和參數 Process process = processBuilder.start();//使用此進程生成器的屬性啟動一個新進程 dealWith(process); try { process.waitFor();// 等待子進程的結束,子進程就是系統調用文件轉換這個新進程 } catch (InterruptedException e) { throw new Exception(e.getMessage()); } } catch (IOException e) { throw new Exception(e.getMessage()); } return true; } /** * 處理進程的IO防止出現阻塞、死鎖等情況 * @param pro * @throws */ private static void dealWith(final Process pro) { // 下面是處理堵塞的情況 try { //啟動單獨線程來清空pro.getInputStream()的緩沖區 new Thread() { public void run() { BufferedReader br1 = new BufferedReader( new InputStreamReader(pro.getInputStream())); try { String text; while ((text = br1.readLine()) != null) { System.out.println(text); } } catch (IOException e) { e.printStackTrace(); } } }.start(); } catch (Exception e) { e.printStackTrace(); } try { //不要忘記處理出理時產生的錯誤信息,不然會堵塞不前的 new Thread() { public void run() { BufferedReader br2 = new BufferedReader( new InputStreamReader(pro.getErrorStream())); String text; try { while ((text = br2.readLine()) != null) { System.err.println(text); } } catch (IOException e) { e.printStackTrace(); } } }.start(); } catch (Exception e) { e.printStackTrace(); } }
上面的代碼中在創建swftools命令行時使用了參數 -s languagedir=C:\\xpdf\\xpdf-chinese-simplified,這里的地址對應的是另外一個工具xpdf,swftools本身會支持一些字體,但是當pdf中存在它不支持的字體時就會報錯,如下圖,此時我們就需要用到xpdf,Xpdf 是一個開源的PDF文件瀏覽器,通過語言包可以很好的支持中文,並且提供了windows和linux版本,可以跨平台部署
xpdf:ftp://ftp.foolabs.com/pub/xpdf/xpdfbin-win-3.04.zip
語言包:ftp://ftp.foolabs.com/pub/xpdf/xpdf-chinese-simplified.tar.gz
xpdf解壓放到C盤根目錄即可,語言包解壓放到xpdf的根目錄中,修改xpdf-chinese-simplified的文件add-to-xpdfrc,添加需要的字體目錄和要展示的具體字體,然后在swftools命令中通過參數指定語言包目錄即可
相關文件下載:
PDF解決方案demo: http://pan.baidu.com/s/1i3mmwux
swftools、xpdf:http://pan.baidu.com/s/1dDu1Yoh(注:解壓放在C盤根目錄即可)