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

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

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

我們需要顯示的 pdf 文件基本上都是電子合同相關(guān)的 pdf 文件,也就是說(shuō)基本上都包含了電子簽名只估,典型的如電子發(fā)票上的公章志群。那么怎么實(shí)現(xiàn)該功能呢?首先我們排除掉采用原生解析 pdf 文件的方式蛔钙,網(wǎng)上找了下解析 pdf 文件的第三方開(kāi)源庫(kù)锌云,這些庫(kù)都很大,動(dòng)則 20M 以上吁脱,并且穩(wěn)定性也不保障桑涎,顯然對(duì) APP 來(lái)說(shuō)是不劃算的彬向。

最后,我們采用了 pdf.js 開(kāi)源庫(kù)攻冷,通過(guò) WebView 的方式來(lái)顯示 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.運(yùn)行本地 demo

npm install
gulp server

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

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

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

//混淆壓縮
gulp minified

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

圖中紅線(xiàn)標(biāo)注的 viewer.html 就是最終我們用來(lái)加載顯示 pdf 文件的入口 html 文件。

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

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

采用 WebView 來(lái)加載本地網(wǎng)頁(yè):

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

//很重要力喷,允許 js 執(zhí)行
settings.setJavaScriptEnabled(true);
settings.setDomStorageEnabled(true);
settings.setAllowFileAccess(true);
//很重要,設(shè)置允許跨域訪(fǎng)問(wèn)
settings.setAllowFileAccessFromFileURLs(true);
settings.setAllowUniversalAccessFromFileURLs(true);

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

以上是 Android 中的例子演训,有幾點(diǎn)很重要弟孟,必須要配置好:

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

iOS 的配置與此相似没讲,這里不贅述。但是運(yùn)行后發(fā)現(xiàn)礁苗,網(wǎng)頁(yè)會(huì)報(bào)錯(cuò)爬凑,無(wú)法顯示 pdf 文件,這時(shí)候我們需要修改源碼试伙,這是因?yàn)樵创a里限制了 pdf 文件地址必須是同源的嘁信。

打開(kāi)源碼目錄下面的 web/app.js 文件,找到如下代碼疏叨,將之注釋掉

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

這句代碼對(duì) pdf 文件地址來(lái)源做了限制潘靖,如果涉及到跨域訪(fǎng)問(wèn),就會(huì)直接拋出異常蚤蔓。代碼注釋掉之后卦溢,重新 build 后再運(yùn)行,應(yīng)該就可以正常加載顯示 pdf 文件了。

3. 如何顯示電子簽章

這樣 build 出的 pdf.js 单寂,是無(wú)法顯示電子簽章的贬芥,要顯示電子簽章,還需要對(duì)源碼做出修改宣决,找到源碼目錄下的 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)建之后威沫,就可以通過(guò) WebView 正常加載顯示 pdf 文件了。

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

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末帽哑,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子叹俏,更是在濱河造成了極大的恐慌妻枕,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,204評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件粘驰,死亡現(xiàn)場(chǎng)離奇詭異屡谐,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)蝌数,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)愕掏,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人顶伞,你說(shuō)我怎么就攤上這事饵撑。” “怎么了唆貌?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,548評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵滑潘,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我锨咙,道長(zhǎng)语卤,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,657評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮粱侣,結(jié)果婚禮上羊壹,老公的妹妹穿的比我還像新娘。我一直安慰自己齐婴,他們只是感情好油猫,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,689評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著柠偶,像睡著了一般情妖。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上诱担,一...
    開(kāi)封第一講書(shū)人閱讀 51,554評(píng)論 1 305
  • 那天毡证,我揣著相機(jī)與錄音,去河邊找鬼蔫仙。 笑死料睛,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的摇邦。 我是一名探鬼主播恤煞,決...
    沈念sama閱讀 40,302評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼施籍!你這毒婦竟也來(lái)了居扒?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,216評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤丑慎,失蹤者是張志新(化名)和其女友劉穎喜喂,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體竿裂,經(jīng)...
    沈念sama閱讀 45,661評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡玉吁,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,851評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了铛绰。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片诈茧。...
    茶點(diǎn)故事閱讀 39,977評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖捂掰,靈堂內(nèi)的尸體忽然破棺而出敢会,到底是詐尸還是另有隱情,我是刑警寧澤这嚣,帶...
    沈念sama閱讀 35,697評(píng)論 5 347
  • 正文 年R本政府宣布鸥昏,位于F島的核電站,受9級(jí)特大地震影響姐帚,放射性物質(zhì)發(fā)生泄漏吏垮。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,306評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望膳汪。 院中可真熱鬧唯蝶,春花似錦、人聲如沸遗嗽。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,898評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)痹换。三九已至征字,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間娇豫,已是汗流浹背匙姜。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,019評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留冯痢,地道東北人氮昧。 一個(gè)月前我還...
    沈念sama閱讀 48,138評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像系羞,于是被迫代替她去往敵國(guó)和親郭计。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,927評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容