今天来聊聊如何在Android APP应用内浏览pdf文件,不用跳转到第三方软件。采用的方法是在WebView中使用pdf.js浏览PDF文件。可能很多人都不太了解,因此小编总结了以下内容,希望大家根据这篇文章能够有所收获。
pdf.js可以实现在线预览pdf文件。这种方案局限性小(除非github上的PDF.js没了)。
PDF插件源码地址:https://github.com/mozilla/pdf.js/
WebSettings webSettings = mWebView.getSettings();
webSettings.setJavaScriptEnabled(true);//支持js
webSettings.setAllowFileAccess(true);
webSettings.setAllowFileAccessFromFileURLs(true);
webSettings.setAllowUniversalAccessFromFileURLs(true); // 允许加载本地文件
方式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目录下
①、若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大小问题,则推荐使用方式三。