JAVA常用API或編程工具003--實現pdf線上閱讀功能之pdf.js__Js

來源:互聯網
上載者:User

pdf.js簡介

PDF.js 是基於開放的 HTML5 及 JavaScript 技術實現的開源產品。簡單說就是一個 PDF 解析器。運用HTML5JavaScript(即pdf.js僅使用安全的web語言,不包含任何攻擊者可以用的本地代碼塊)的PDF閱讀器pdf.js,直接在標準的HTML頁面上傳入和渲染PDF檔案, 還可以提高安全性(不需要安裝第三方外掛程式,安全性由瀏覽器保證),瀏覽器所做的安全措施已經為pdf.js提供了安全的運行環境。其對IE和 FireFox瀏覽器的要求是IE9+, FireFox19+。

線上樣本: http://jsbin.com/pdfjs-helloworld-v2/1/edit   , http://jsbin.com/pdfjs-prevnext-v2/1/edit

源碼:https://github.com/mozilla/pdf.js

官網:http://mozilla.github.io/pdf.js/


pdf.js VS 傳統瀏覽器讀取pdf

一般來說,PDF檔案格式都是在瀏覽器中由外掛程式來描繪,通常是Adobe自己的PDF reader或來自其他供應商的描繪工具,但這些外掛通常無法充分運用PDF的特點,而且由於含有大量的受信任代碼,使得Google Chrome瀏覽器必須運用SandBox沙箱原理,來檢查PDF描繪工具是否遭到未知病毒感染。

使用adobe,必須在本地安裝軟體才能使用,而pdf.js不依賴環境、渲染速度快(測試過,確實很快)、安全性高。


pdf.js渲染PDF檔案

pdf.js渲染PDF檔案的流程:Fetch pdf (url / buffer) ——> canvas ——> 渲染

如果要深入pdf的渲染,需要去研究pdf.js原始碼。pdf.js可通過pdf檔案的地址或pdf資料流擷取pdf,具體實現是調用介面函數 PDFJs.getDoc(url/buffer)將pdf載入html,通過canvas處理, 然後渲染pdf檔案。網上給出的都是通過url來擷取pdf的例子,而我在做項目的時候,後台(Python)要求是發pdf的資料流給前台,前台接收pdf的buffer,然後通過pdf.js來渲染。當然最初嘗試buffer出現了很多問題,具體問題總結如下:

1)如何通過$.ajax接收後台發給前台的buffer資料;

2)如何將buffer傳給pdf.js來處理(這裡我使用了viewer.js, 所以需要考慮的是如何將buffer傳給viewer.js來處理);

3)如何將pdf.js轉換成pdf.js可以接收的buffer格式;

(對應問題解決見代碼注釋)

註:viewer.js是pdf.js的擴充,其將列印、翻頁、縮放等功能進行了實現,且介面非常好看。也就是說如果你引入了viewer.js,pdf的渲染和渲染之後的功能介面都已經幫你實現了,你不用自己去寫介面。


先從官網:http://mozilla.github.io/pdf.js/ 下載代碼,然後使用檔案viewer.html , 我的html就是在viewer.html 的基礎上修改的,下面我給出buffer的例子:

<!DOCTYPE html>
<html dir="ltr" mozdisallowselectionprint moznomarginboxes>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
    <meta name="google" content="notranslate">
    <title>線上預覽</title>
    {% load static %}{% get_static_prefix as STATIC_URL %}
    <link href="{{STATIC_URL}}css/preview.css" rel="stylesheet" type="text/css" />
    <link rel="stylesheet" href="{{STATIC_URL}}pdfjs/web/viewer.css"/>
    <script type="text/javascript" src="{{STATIC_URL}}pdfjs/web/compatibility.js"></script>
    <link rel="resource" type="application/l10n" href="{{STATIC_URL}}pdfjs/web/locale/locale.properties"/>
    <script type="text/javascript" src="{{STATIC_URL}}pdfjs/web/l10n.js"></script>
    <script type="text/javascript" src="{{STATIC_URL}}pdfjs/build/pdf.js"></script>
    <script type="text/javascript" src="{{STATIC_URL}}pdfjs/web/debugger.js"></script>
    <script src="{{STATIC_URL}}js/jQuery-1.8.3.js" type="text/javascript"></script>
    <script type="text/javascript">

          //convertDataURIToBinary()

         //不知道什麼原因如果後台直接將pdf的資料流發給前台,得到的是亂碼,將資料轉換成 Uint8Array始終不成功

         //所以就讓後台將發送之前的資料流做 了base64編碼發給前台,前台再解碼得到的資料就不是亂碼了。   

          var BASE64_MARKER = ';base64,';

          var preFileId = {{mark}};

          //viewer.js全域變數,傳入buffer,回答問題2
          var DEFAULT_URL 
          
          $(document).ready(function(){
             $.ajax({
                type:"post",
                async: false,

                  //ajax接收pdf資料流,注意dataType值的設定是否有錯,如果不指定,jQuery將自動根據HTTP包MIME資訊返回

                 //responseXML或responseText .      回答問題1
                contentType:"application/pdf;charset=utf-8", 
                url:"{% url netPan.File.views.browserFuf%}",
                data:{
                    id: preFileId
                },
                success:function(data){
                    var pdfAsDataUri = data;

                    //如果引入了viewer.js , 處理方法
                    var pdfAsArray = convertDataURIToBinary(pdfAsDataUri);
                    DEFAULT_URL = pdfAsArray;

                          //  只引入了pdf.js, 未引入viewer.js, 處理方法

                          // var pdfAsArray = convertDataURIToBinary(pdfAsDataUri);

                          // PDFJS.getDocument(pdfAsArray).then();  自己寫pdf的處理函數

                }
            });
          });


        function convertDataURIToBinary(dataURI) {   //編碼轉換,回答問題3

          var base64Index = dataURI.indexOf(BASE64_MARKER) + BASE64_MARKER.length;
          var base64 = dataURI.substring(base64Index);
          var raw = window.atob(base64);
          var rawLength = raw.length;

          //轉換成pdf.js能直接解析的Uint8Array類型,見pdf.js-4068
          var array = new Uint8Array(new ArrayBuffer(rawLength));  

          for(i = 0; i < rawLength; i++) {
            array[i] = raw.charCodeAt(i);
          }
          return array;
     }
    </script>


    <!--先設定全域變數DEFAULT_URL 的值,所以要後調入viewer.js -->
    <script type="text/javascript" src="{{STATIC_URL}}pdfjs/web/viewer.js"></script>
  </head>

 <body>

  省略內容

</body>

</html>


相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.