移动端实现PDF文件阅读的方法

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

前言:

我们知道,Android系统本身不具备打开PDF文件的能力,因此在Android 要实现 PDF 阅读功能需要借助于第三方工具,一般而言有以下方案:

  • 使用GoogleDocs提供的在线PDF阅读功能
  • 使用第三方应用阅读本地PDF文件
  • 使用PDFBox读取编辑PDF文件内容
  • 集成第三方SDK,实现本地阅读
  • 集成Mozilla的PDF.js,在 WebView 中阅读PDF文件
  • 使用 pdf2htmlEX 将PDF 文件转换成 HTML 或者图片

一. 使用GoogleDocs提供的在线PDF阅读功能

GoogleDocs 提供了多种文本格式的阅读能力,我们只需通过 Android 的 WebView 即可实现打开在线 PDF 文档,代码如下所示:

public void setDocumentPath(final String path) {
    WebView webView = (WebView) findViewById(R.id.webview);
    webView.getSettings().setJavaScriptEnabled(true);
    webView.getSettings().setPluginsEnabled(true);
    webView.loadUrl("https://docs.google.com/viewer?url=http://10.200.180.50/dilan/carfree/downLoad/test.pdf");
}

然而这种方案的缺陷同样明显:

  • 不支持阅读本地PDF文件;
  • 国内通常情况下访问不了 Google 提供 的服务。

 

二. 使用第三方应用阅读本地PDF文件

用户手机中或多或少会装有一些带有PDF文件阅读功能的应用,例如WPS、Chrome、UC浏览器等,此时我们可以借助于这些应用达到打开PDF文件的效果,只需要具备以下两个条件:

  • PDF 文件已保存在本地;
  • 用户手机中安装了支持 PDF 阅读的应用。

实现这个方案的代码示例如下:

public void openPdfFile(File file) {
    Intent intent = new Intent("android.intent.action.VIEW");
    intent.addCategory("android.intent.category.DEFAULT");
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    Uri uri = Uri.fromFile(file);
    intent.setDataAndType(uri, "application/pdf");
    startActivity(Intent.createChooser(intent, "打开PDF文件"));
}

 

三. 使用PDFBox读取编辑PDF文件内容

PDFBox(一个BSD许可下的源码开放项目)是一个为开发人员读取和创建PDF文档而准备的纯Java类库。它提供如下特性: 提取文本,包括Unicode字符,和Jakarta Lucene等文本搜索引擎的整合过程十分简单;加密/解密PDF文档;从PDF和XFDF格式中导入或导出表单数据;向已有PDF文档中追加内容;将一个PDF文档切分为多个文档;覆盖PDF文档等。下载地址点击这里。

1. 读取PDF内容

 1     public void readPDF() {
 2         PDDocument helloDocument = null;
 3         try {
 4             helloDocument = PDDocument.load(new File(
 5                     "User/fqian/download/test.pdf"));
 6             PDFTextStripper textStripper = new PDFTextStripper("GBK");
 7             System.out.println(textStripper.getText(helloDocument));
 8 
 9             helloDocument.close();
10         } catch (IOException e) {
11             // TODO Auto-generated catch block
12             e.printStackTrace();
13         }
14     }

这种方式允许你读取PDF文件的内容,而后进行多种形式的展示,缺点也很明显,就是会失去原有的排版样式;

2. 将PDF文件转换为图片

 1 public void convert2Image() {
 2     try {
 3         PDDocument doc = PDDocument
 4                 .load("User/fqian/download/test.pdf");
 5         int pageCount = doc.getPageCount();
 7         List pages = doc.getDocumentCatalog().getAllPages();
 8         for (int i = 0; i < pages.size(); i++) {
 9             PDPage page = (PDPage) pages.get(i);
10             BufferedImage image = page.convertToImage();
11             Iterator iter = ImageIO.getImageWritersBySuffix("jpg");
12             ImageWriter writer = (ImageWriter) iter.next();
13             File outFile = new File("User/fqian/download/"
14                     + i + ".jpg");
15             FileOutputStream out = new FileOutputStream(outFile);
16             ImageOutputStream outImage = ImageIO
17                     .createImageOutputStream(out);
18             writer.setOutput(outImage);
19             writer.write(new IIOImage(image, null, null));
20         }
21         doc.close();
23     } catch (FileNotFoundException e) {
24         // TODO Auto-generated catch block
25         e.printStackTrace();
26     } catch (IOException e) {
27         // TODO Auto-generated catch block
28         e.printStackTrace();
29     }
30 }

这种方式避免了直接读取文件内容再进行显示造成的样式缺失问题,但是当文件体积较大时,生成的图片所占空间也随之暴涨,因此客户端进行请求时面对的加载时间和流量耗费问题是比较尴尬的。

 

四. 集成第三方SDK,实现本地阅读

事实上,已经存在了为数不少的免费或者付费的 PDF SDK,一般而言免费版在功能和性能等指标上与收费版可能存在一定差距。这种方式的优点是加载速度快和节约流量,缺点是会显著的增加安装包大小,例如 AndroidPdfViewer 的引入,剔除不常用的处理器架构,只保留 armeabi-v7ax86,还是会增加将近 10M 的大小。

免费版:

  • PDFium:Google 和 Foxit 合作开源的 Foxit 的 PDF 源码,作为 Chrome 浏览器的 PDF 渲染引擎组件,当然这是 C/C++ 实现的;
  • PdfiumAndroid:mshockwave 基于 PDFium 基础上适配 Android 平台的函数库;
  • AndroidPdfViewer:barteksc 基于 PdfiumAndroid 基础上实现的一个 PDF 阅读 Demo,支持常见的手势,缩放,双击等效果。
  • MuPDF: 一个轻量级的 开源 PDF 和 XPS 查看器

付费版:

  • Foxit 福昕 SDK:国内老牌的付费 PDF SDK,功能强大,如果 PDF 阅读功能在你的应用中比较常用但又不是核心功能,可以考虑接入它;
  • PlugPDF:国外的一款付费 PDF SDK,类似 Foxit SDK;

 

五. 集成Mozilla的PDF.js,在 WebView 中阅读PDF文件

PDF.js 是由Mozilla 主导推出的可以将PDF文件转换为H5页面进行展示的工具,有服务端和客户端两种集成方式来实现在 WebView 中打开 PDF 文件的功能。关于更多PDF.js的官方描述,请点击这里。

1. 服务端方式

PDF.js 提供了一套较完善的在 H5 页面中阅读 PDF 的方案,同时支持 Web 前端,Android 和 iOS WebView 加载。服务部署起来应该也比较简单,大致的方案如下:

  • 服务段创建一个HTML页面,该页面使用