Android中浏览PDF文件

今天来聊聊如何在Android APP应用内浏览pdf文件,不用跳转到第三方软件。采用的方法是在WebView中使用pdf.js浏览PDF文件。可能很多人都不太了解,因此小编总结了以下内容,希望大家根据这篇文章能够有所收获。

pdf.js可以实现在线预览pdf文件。这种方案局限性小(除非github上的PDF.js没了)。

PDF插件源码地址:https://github.com/mozilla/pdf.js/

1、WebView配置:

WebSettings webSettings = mWebView.getSettings();
webSettings.setJavaScriptEnabled(true);//支持js
webSettings.setAllowFileAccess(true);
webSettings.setAllowFileAccessFromFileURLs(true);
webSettings.setAllowUniversalAccessFromFileURLs(true); // 允许加载本地文件

 2、实现方式

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

String pdf_url = "https://www.gjtool.cn/pdfh5/git.pdf";
webView.loadUrl("http://mozilla.github.io/pdf.js/web/viewer.html?file=" + pdf_url);

这种方式和使用google docs是差不多的,重要的是国内可以直接访问,但是会遇到跨域的问题。

方式2:下载pdf.js放到assets目录下

Android中浏览PDF文件_第1张图片

 ①、若pdf文件不能跨域访问可以使用这种方式,先把文件下载到本地,然后传入本地文件路径预览pdf:

// path: /storage/emulated/0/pictures/bzyy/
String baseFilePath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getPath() + "/bzyy/"; 
String pdf_url = "file:///" + baseFilePath  + "试题A.pdf";
webView.loadUrl("file:///android_asset/pdfjs/web/viewer.html?file=" + pdf_url);

②、若pdf文件需要进行跨域访问,会加载失败,错误信息为:file origin does not match viewer's。解决方案也简单:直接注释掉web/viewer.js中的这三行,不去判断跨域即可。即:

// 注释掉这三行,不去判断跨域
if (fileOrigin !== viewerOrigin) {
    throw new Error('file origin does not match viewer\'s');
}

若地址为流的方式,则需要编码一下:

注意:Android中不能直接使用encodeURIComponent() 方法。则可使用Uri.encode()代替。

即:js中的方法:encodeURIComponent() 等价于Android中的:Uri.encode();

String pdf_url = "https://www.gjtool.cn/pdfh5/git.pdf?token=xxx&time=xxx";
webView.loadUrl("http://mozilla.github.io/pdf.js/web/viewer.html?file=" + Uri.encode(pdf_url));

注意:由于pdf.js库比较大,全部放到本地的话,apk会增大5M左右。因此可以考虑把pdf.js部署到服务端或者使用cdn的方式。

方式3:pdf.js使用cdn的方式导入,需自定义预览界面

①、编写预览的页面:index.html



    
        
        
        Document
        
        
        
    
    
    

②、实现预览的index.js

var url = location.search.substring(1);

PDFJS.cMapUrl = 'https://unpkg.com/[email protected]/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);//设置为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)
  }
});

③、使用WebView加载html

String pdf_url = "https://www.gjtool.cn/pdfh5/git.pdf";
webView.loadUrl("file:///android_asset/index.html?" + pdf_url);

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

注意:当cdn服务器访问慢的时候,会出现加载缓慢的问题。可能还会出现不能跨域访问的问题。

④遇到的问题:

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

 var viewport = page.getViewport(2.0);

b、pdf内容显示不完整问题,通过设置cMapUrl和cMapPacked解决,即

PDFJS.cMapUrl = 'https://unpkg.com/[email protected]/cmaps/';
PDFJS.cMapPacked = true;

以上就是在Android APP内使用pdf.js预览pdf文件的实现方法。推荐使用第二种方式。若考虑到apk大小问题,则推荐使用方式三。

你可能感兴趣的:(Android,android)