安卓 使用pdf.js实现 在app中在线预览pdf 不用第三方软件打开

遇到个需求需要将app的使用手册能够在app中打开然后在线预览不用跳转其他第三方软件(WPS office)打开, 搜索一番后发现大部分用到的是PDF.js,也遇到了一些坑然后记录下来.

首先需要在xml中添加WebView控件
在这里插入图片描述
然后在Activity中的onCreate()方法中调用控件

  1. 如何使用

方式一 :使用mozilla部署在github pages上的Viewer

这样的好处是不用添加多余的pdf.js文件 直接调用他们给定的路径传入地址即可打开,
缺点是 不能自定义

1.设置WebView:

WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setAllowFileAccess(true);
webSettings.setAllowFileAccessFromFileURLs(true);
webSettings.setAllowUniversalAccessFromFileURLs(true);
  1. 打开pdf 传入pdf在服务器上的地址/ 也可传入pdf的本地路径
webView.loadUrl("http://mozilla.github.io/pdf.js/web/viewer.html?file=" + pdfUrl);

在这里插入图片描述

方式二: 下载PDF.js放到assets目录下

1,下载PDF.js, http://mozilla.github.io/pdf.js/getting_started/#download
进到页面后 反正我下载的是第一个
在这里插入图片描述

  1. 将解压出来的三个文件,放入到一个自定义名称的文件夹中,如文件夹命名为pdfjs
    在这里插入图片描述
    然后放到项目所在的assets资源文件夹下
    在这里插入图片描述
    然后按照方式一的设置, 只需修改一下路径即可, 这样就调用了刚才导入的文件
webView.loadUrl("file:///android_asset/pdfjs/web/viewer.html?file=" + pdfUrl);

但是这种方式默认只能打开本地的pdf路径
如果想预览服务器上的pdf文件需要自定义:
3. 打开assets->pdfjs->web->viewer.js文件
在这里插入图片描述
然后可以搜索"file origin does not match viewer's"找到下面代码所在的位置 , 然后注释掉,就可以实现跨域访问了
在这里插入图片描述

方式二中pdf不可以双指放大和缩小 如果想实现需要添加下列代码

// 双指可以放大pdf
        webView.setOnTouchListener(new View.OnTouchListener() {
            private float OldX1, OldY1, OldX2, OldY2;
            private float NewX1, NewY1, NewX2, NewY2;

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_POINTER_2_DOWN:
                        if (event.getPointerCount() == 2) {
                            OldX1 = event.getX(0);
                            OldY1 = event.getY(0);
                            OldX2 = event.getX(1);
                            OldY2 = event.getY(1);
                        }
                        break;
                    case MotionEvent.ACTION_MOVE:
                        if (event.getPointerCount() == 2) {
                            if (OldX1 == -1 && OldX2 == -1)
                                break;
                            NewX1 = event.getX(0);
                            NewY1 = event.getY(0);
                            NewX2 = event.getX(1);
                            NewY2 = event.getY(1);
                            float disOld = (float) Math.sqrt((Math.pow(OldX2
                                    - OldX1, 2) + Math.pow(OldY2 - OldY1, 2)));
                            float disNew = (float) Math.sqrt((Math.pow(NewX2
                                    - NewX1, 2) + Math.pow(NewY2 - NewY1, 2)));
                            Log.e("onTouch", "disOld=" + disOld + "|disNew="
                                    + disNew);
                            if (disOld - disNew >= 25) {
                                // 缩小
//							wv.zoomOut();
                                webView.loadUrl("javascript:PDFViewerApplication.zoomOut()");
                                Log.e("onTouch", "zoomOut");
                            } else if (disNew - disOld >= 25) {
                                // 放大
//							wv.zoomIn();
                                webView.loadUrl("javascript:PDFViewerApplication.zoomIn()");
                                Log.e("onTouch", "zoomIn");
                            }
                            OldX1 = NewX1;
                            OldX2 = NewX2;
                            OldY1 = NewY1;
                            OldY2 = NewY2;
                        }
                        break;
                    case MotionEvent.ACTION_UP:
                        if (event.getPointerCount() < 2) {
                            OldX1 = -1;
                            OldY1 = -1;
                            OldX2 = -1;
                            OldY2 = -1;
                        }
                        break;
                }
                return false;
            }
        });

如果想要禁用pdf.js自带的下载和打印功能 点击pdf.js屏蔽复制、打印、下载功能并加水印

方式三 自定义预览界面,PDF.js使用cdn的方式导入 (目前没有尝试)

1.首先写一个预览的index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport"
     content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no"/>
  <title>Document</title>
  <style type="text/css">
    canvas {
      width: 100%;
      height: 100%;
      border: 1px solid black;
    }
  </style>
  <script src="https://unpkg.com/pdfjs-dist@1.9.426/build/pdf.min.js"></script>
  <script type="text/javascript" src="index.js"></script>
</head>
<body>
</body>
</html>

2.实现预览index.js

var url = location.search.substring(1);
 
PDFJS.cMapUrl = 'https://unpkg.com/pdfjs-dist@1.9.426/cmaps/';
PDFJS.cMapPacked = true;
 
var pdfDoc = null;
 
function createPage() {
  var div = document.createElement("canvas");
  document.body.appendChild(div);
  return div;
}
 
function renderPage(num) {
  pdfDoc.getPage(num).then(function (page) {
    var viewport = page.getViewport(2.0);
    var canvas = createPage();
    var ctx = canvas.getContext('2d');
 
    canvas.height = viewport.height;
    canvas.width = viewport.width;
 
    page.render({
      canvasContext: ctx,
      viewport: viewport
    });
  });
}
 
PDFJS.getDocument(url).then(function (pdf) {
  pdfDoc = pdf;
  for (var i = 1; i <= pdfDoc.numPages; i++) {
    renderPage(i)
  }
});

3.WebView加载html

mWebView.loadUrl("file:///android_asset/index.html?" + pdfUrl);

这样我们最终放到assets目录下的就index.html和index.js两个文件,可以避免直接全部导入带来的apk体积增大的问题,如果我们对预览UI和交互有要求的话可以方便的通过修改html来实现。

遇到的问题

在直接实现预览的时候遇到显示模糊的问题,通过增大scale系数解决

var viewport = page.getViewport(2.0);//设置为2.0

pdf内容显示不完整,通过设置cMapUrl和cMapPacked解决

PDFJS.cMapUrl = 'https://unpkg.com/pdfjs-dist@1.9.426/cmaps/';
PDFJS.cMapPacked = true;

参考:https://blog.csdn.net/lh_android/article/details/91864908?

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

暴走的山交

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值