業務アプリでは、PDFを閲覧したいという要件が多いようです。Webブラウザを使えばPDFを閲覧することはできますが、何度も繰り返し見るドキュメントの場合、サイズの大きいPDFを毎回ダウンロードするのは少し面倒です。

そこで今回はオフラインでも使えるPDFリーダーアプリの作り方を紹介します。

利用するプラグインについて

今回は以下のプラグインを使います。

  • File
    (公式提供) アプリローカルにあるファイルを読み書きします。
  • FileTransfer
    (公式提供)オンライン上のファイルをダウンロードしてローカルに保存します。
  • Cordova Document Viewer Plugin
    サードパーティ製。PDFに限らずドキュメントの閲覧ができるビューワープラグインです。
    執筆時点のバージョン(0.9.10)ではAndroidで正常に動作しませんでした。よって今回はiOSを対象としてアプリを作成します。

なぜプラグインを使うのか

MonacaアプリのUIを描画しているWebViewではPDFも閲覧できますが、アプリ上でPDFを表示すると元のアプリの画面に戻れなくなります。また、InAppBrowser(アプリ内ブラウザ)を使うこともできますが、これはWeb上の外部ファイルにのみ対応しており、オフライン利用ができません。そこでプラグインを組み合わせてPDFファイルの保存と閲覧を行います。

検証環境

今回の検証環境は下記の通りです。

  • Cordovaバージョン:7.1.0
  • Cordova Document Viewer Pluginプラグインバージョン:0.9.10
  • 検証端末:iPhone SE (iOS 12.1.2)

上記の検証環境以外では、本記事に掲載されている通りに動作しない可能性があります。あらかじめご了承ください。

コードの解説

ではここからコードを解説します。

ディレクトリの取得

まずアプリから読み書きをする対象のローカルディレクトリを取得します。Fileプラグインの cordova.file.applicationStorageDirectory でディレクトリが取得できます。iOSではアプリ内のDocumentsディレクトリのみ読み書き可能となっています。

// ディレクトリを取得
const getDir = async () => {
  return new Promise((res, rej) => {
    const dir = `${cordova.file.applicationStorageDirectory}/Documents/`;
    resolveLocalFileSystemURL(dir, res, rej);
  });
}

ファイルの一覧を取得する

ローカルディレクトリを取得したら、そのディレクトリ内にあるファイル一覧を取得します。これは同じくFileプラグインの DirectoryReader を使います。

// ローカルのファイル一覧を取得
const getFiles = async (dir) => {
  return new Promise((res, rej) => {
    const reader = new DirectoryReader(dir.toURL());
    reader.readEntries(res, rej);
  });
}

ファイルを一覧表示

ファイルの一覧表示はOnsen UIを使っています。DirectoryReader で取得した情報にはディレクトリも入ってきますので、ディレクトリの場合は除外し、ファイルだけを表示するようにしています。また、PDFファイルの内容を表示する処理に備えて、ons-list-itemdata-path プロパティにファイルのパス file.nativeURL を代入しています。

// ファイル一覧を表示
const showFiles = (files) => {
  const ary = [];
  for (const file of files) {
    // ディレクトリは無視
    if (!file.isFile) continue;
    ary.push(`
      <ons-list-item class="file" data-path="${file.nativeURL}" tappable>
        ${file.name}
      </ons-list-item>
    `);
  }
  $('#files').empty().html(ary.join(''));
}

オンライン上のPDFファイルをダウンロード

PDFファイルのダウンロードはFileTransferプラグインで行います。今回はオンライン上のファイル名をそのままローカルにダウンロードしています。FileTransferは同名の既存ファイルがあると上書きしますので、実際に実装する際はユニークな名前を付けた方が良さそうです。

// オンライン上のPDFファイルを取得して保存
const getFile = async (url, dir) => {
  return new Promise((res, rej) => {
    const fileTransfer = new FileTransfer();
    const fileName = url.replace(/.*\/(.*?\.pdf)/, "$1");
    fileTransfer.download(url, `${dir.toURL()}/${fileName}`, res, rej);
  });
}

PDFを表示する

PDFを表示する処理はCordova Document Viewer Pluginで行います。cordova.plugins.SitewaertsDocumentViewer.viewDocument にPDFファイルのパスとMime Typeを指定して実行します。ファイルのパスはファイル一覧表示の際に設定した data-path から取得します。

// PDFファイルを表示するイベント
$(document).on('click', '.file div', (e) => {
  const path = $(e.target).parent('.file').data('path');
  // ドキュメントビューワーで表示
  cordova.plugins.SitewaertsDocumentViewer.viewDocument(path, 'application/pdf');
});

動作イメージ

以下が画面キャプチャです。オンライン上のPDFファイルをダウンロードし、それをアプリ内で閲覧できます。

Cordova Document Viewer Pluginは、PDFリーダーとしても多機能です。


Cordova Document Viewer PluginはPDF以外のフォーマットにも対応していますので、オフィスドキュメントを閲覧したり、画像ビューワーとしても利用できます。オンライン上にあるデータをダウンロードして、オフラインで見せる機能はさまざまな場面で活用できるでしょう。発展的な利用方法として、電子書籍アプリを実装することも可能です。今回のコードを参考に実装してみてください。

今回のコードはgoofmint/MonacaPDFReaderにアップロードしてあります。
また、プロジェクトはこちらのURLで公開しています。実装の参考にしてください。

今回ご紹介したCordovaプラグインは、サードパーティ製であるためアプリストア版のMonacaデバッガーでは動作しません。動作検証の際にはProプラン以上で利用可能なカスタムビルドデバッガーをご利用ください。