美文网首页
APP中如何显示带电子签名的PDF文件

APP中如何显示带电子签名的PDF文件

作者: 云飞扬1 | 来源:发表于2019-05-31 18:32 被阅读0次

    之前碰到一个需求,需要在手机 APP 中显示 pdf 文件。经过调研发现,在电脑上的浏览器如 chrome、safari等,可以直接显示 pdf 文件。由此联想到,在 APP 中能否通过浏览器来加载显示 pdf 文件呢?最后经过测试发现:

    1. iOS 的 WebView 可以直接加载 pdf 文件并显示出来;
    2. Android 的 WebView 不支持;
    3. 在 iOS 中有电子签名的 pdf 文件,关于有电子签名的地方无法显示;

    我们需要显示的 pdf 文件基本上都是电子合同相关的 pdf 文件,也就是说基本上都包含了电子签名,典型的如电子发票上的公章。那么怎么实现该功能呢?首先我们排除掉采用原生解析 pdf 文件的方式,网上找了下解析 pdf 文件的第三方开源库,这些库都很大,动则 20M 以上,并且稳定性也不保障,显然对 APP 来说是不划算的。

    最后,我们采用了 pdf.js 开源库,通过 WebView 的方式来显示 pdf 文件。

    1. 自己构建 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
    

    构建成功后,浏览器打开地址:http://localhost:8888/web/viewer.html,可以看到里面提供的 demo。

    4.构建 pdf.js 文件

    //通用构建
    gulp generic
    
    //混淆压缩
    gulp minified
    

    我这里采用的是 gulp minified 的方式来构建,构建成功后,在 build/minified/ 目录下会输出结果,如下所示:

    图中红线标注的 viewer.html 就是最终我们用来加载显示 pdf 文件的入口 html 文件。

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

    将前面构建好的 pdf.js 相关文件拷贝到应用程序里,例如 Android 则拷贝到 assets 目录中,如下图所示:

    采用 WebView 来加载本地网页:

    // pdf 文件的 url 地址,可以是本地文件,也可以是网络文件
    String pdfUrl = "......";   
    
    //很重要,允许 js 执行
    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 能够执行;
    2. WebView 必须设置成能够跨域访问;
    3. pdf 文件地址可以是以 file:// 开头的本地文件,也可以是以 http:// 开头的网络文件;
    4. file 参数值必须 uri encode;

    iOS 的配置与此相似,这里不赘述。但是运行后发现,网页会报错,无法显示 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);
        }
    

    同样将这段代码给注释掉,看源码可以知道这里是隐藏掉电子签名了。最后再重新构建之后,就可以通过 WebView 正常加载显示 pdf 文件了。

    这种方式对 iOS、Android 都是适用的,并且能够显示 pdf 文件中的电子签名。需要注意的是,最终你需要把构建文件中的一些不必要的文件给删除掉,例如 .map 文件、.pdf 文件,这些都是多余的,最终总的文件大小约 4M 多的样子。

    相关文章

      网友评论

          本文标题:APP中如何显示带电子签名的PDF文件

          本文链接:https://www.haomeiwen.com/subject/veggtctx.html