APP中如何顯示帶電子簽名的PDF文件

之前碰到一個需求,需要在手機 APP 中顯示 pdf 文件。經(jīng)過調(diào)研發(fā)現(xiàn),在電腦上的瀏覽器如 chrome、safari等,可以直接顯示 pdf 文件。由此聯(lián)想到,在 APP 中能否通過瀏覽器來加載顯示 pdf 文件呢?最后經(jīng)過測試發(fā)現(xiàn):

  1. iOS 的 WebView 可以直接加載 pdf 文件并顯示出來;
  2. Android 的 WebView 不支持;
  3. 在 iOS 中有電子簽名的 pdf 文件,關(guān)于有電子簽名的地方無法顯示;

我們需要顯示的 pdf 文件基本上都是電子合同相關(guān)的 pdf 文件,也就是說基本上都包含了電子簽名,典型的如電子發(fā)票上的公章。那么怎么實現(xiàn)該功能呢?首先我們排除掉采用原生解析 pdf 文件的方式,網(wǎng)上找了下解析 pdf 文件的第三方開源庫,這些庫都很大,動則 20M 以上,并且穩(wěn)定性也不保障,顯然對 APP 來說是不劃算的。

最后,我們采用了 pdf.js 開源庫,通過 WebView 的方式來顯示 pdf 文件。

1. 自己構(gòu)建 pdf.js

pdf.js源碼地址

1.下載源碼到本地:

git clone https://github.com/mozilla/pdf.js.git
cd pdf.js

2.安裝 gulp 工具

npm install -g gulp-cli

3.運行本地 demo

npm install
gulp server

構(gòu)建成功后,瀏覽器打開地址:http://localhost:8888/web/viewer.html,可以看到里面提供的 demo。

4.構(gòu)建 pdf.js 文件

//通用構(gòu)建
gulp generic

//混淆壓縮
gulp minified

我這里采用的是 gulp minified 的方式來構(gòu)建,構(gòu)建成功后,在 build/minified/ 目錄下會輸出結(jié)果,如下所示:

圖中紅線標注的 viewer.html 就是最終我們用來加載顯示 pdf 文件的入口 html 文件。

2. 如何在 WebView 中加載 pdf 文件

將前面構(gòu)建好的 pdf.js 相關(guān)文件拷貝到應用程序里,例如 Android 則拷貝到 assets 目錄中,如下圖所示:

采用 WebView 來加載本地網(wǎng)頁:

// pdf 文件的 url 地址,可以是本地文件,也可以是網(wǎng)絡文件
String pdfUrl = "......";   

//很重要,允許 js 執(zhí)行
settings.setJavaScriptEnabled(true);
settings.setDomStorageEnabled(true);
settings.setAllowFileAccess(true);
//很重要,設置允許跨域訪問
settings.setAllowFileAccessFromFileURLs(true);
settings.setAllowUniversalAccessFromFileURLs(true);

webView.loadUrl("file:///android_asset/pdfjs/web/viewer.html?file=" + Uri.encode(pdfUrl));

以上是 Android 中的例子,有幾點很重要,必須要配置好:

  1. 必須允許 js 能夠執(zhí)行;
  2. WebView 必須設置成能夠跨域訪問;
  3. pdf 文件地址可以是以 file:// 開頭的本地文件,也可以是以 http:// 開頭的網(wǎng)絡文件;
  4. file 參數(shù)值必須 uri encode;

iOS 的配置與此相似,這里不贅述。但是運行后發(fā)現(xiàn),網(wǎng)頁會報錯,無法顯示 pdf 文件,這時候我們需要修改源碼,這是因為源碼里限制了 pdf 文件地址必須是同源的。

打開源碼目錄下面的 web/app.js 文件,找到如下代碼,將之注釋掉

  if (origin !== viewerOrigin && protocol !== 'blob:') {
    throw new Error('file origin does not match viewer\'s');
  }

這句代碼對 pdf 文件地址來源做了限制,如果涉及到跨域訪問,就會直接拋出異常。代碼注釋掉之后,重新 build 后再運行,應該就可以正常加載顯示 pdf 文件了。

3. 如何顯示電子簽章

這樣 build 出的 pdf.js ,是無法顯示電子簽章的,要顯示電子簽章,還需要對源碼做出修改,找到源碼目錄下的 src/core/annotation.js 文件,找到如下代碼:

    // Hide signatures because we cannot validate them, and unset the fieldValue
    // since it's (most likely) a `Dict` which is non-serializable and will thus
    // cause errors when sending annotations to the main-thread (issue 10347).
    if (data.fieldType === 'Sig') {
       data.fieldValue = null;
       this.setFlags(AnnotationFlag.HIDDEN);
    }

同樣將這段代碼給注釋掉,看源碼可以知道這里是隱藏掉電子簽名了。最后再重新構(gòu)建之后,就可以通過 WebView 正常加載顯示 pdf 文件了。

這種方式對 iOS、Android 都是適用的,并且能夠顯示 pdf 文件中的電子簽名。需要注意的是,最終你需要把構(gòu)建文件中的一些不必要的文件給刪除掉,例如 .map 文件、.pdf 文件,這些都是多余的,最終總的文件大小約 4M 多的樣子。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容