LoginSignup
54
45

More than 1 year has passed since last update.

[pdf.js] 手軽にPDFファイルをHTMLに埋め込めるWebComponentを作った

Last updated at Posted at 2023-02-06

PDFファイルを手軽にHTMLに埋め込みたい

PDFファイルをHTMLに埋め込む場合、従来だと<iframe>タグを使用するか、pdf.jsを使用する方法、Google Driveのプレビュー用URLを使う方法がありました。
ただし、それぞれ

  • <iframe>タグを使用する方法 → PCのみ埋め込み可、スマホ非対応❌
  • pdf.jsを使用する方法 → スマホに対応しているが、公式サイトからzipファイルを解凍し自分でサーバーに設置する必要がある(面倒)⚠️
  • Google Driveのプレビュー用URLを使う方法 → 複数のPDFを埋め込むと挙動が不安定になってしまった&公式でサポートされているものなのか不明❌

という制限がありました。
詳しくはこちらの記事によくまとめられています。

pdf.jsを使うとしても、できることなら<script>タグを一行差し込むだけで使えたら最高です。

pdf.js を WebComponent 化し、ライブラリとして配布

以上を踏まえて、<script>タグを一行差し込むだけでpdf.jsが使えるライブラリを作りました!

使い方は次のようになります。

使用例
<!-- scriptタグでライブラリを読み込み -->
<script src="https://deno.land/x/embed_pdf@v1.2.0/mod.js" type="module"></script>

<!-- src属性にpdfのファイルパスを指定する -->
<embed-pdf src="./path/to/file.pdf"></embed-pdf>

scriptタグを読み込んだ後、<embed-pdf>という名前のHTMLタグを設置することで、PDFを表示させることができます。

このHTMLファイルをブラウザで表示させると、以下のような感じでPDFファイルが埋め込まれているのが確認できます。

image.png

ライブラリの公開URLはこちら↓です。

ソースコードはGitHubで公開しています↓。

ライブラリ作成にあたっての技術選定

作成にあたって、以下の条件で技術選定しました。

条件1. npm install等なしで使えること

今回の自分のユースケースでは、導入対象のWebサイトは単純な静的ファイルサーバーであったため、npm等のツールチェーンや追加のビルド手順を(PDFを埋め込むためだけに)新たに導入したくないという事情がありました。
そのため、ライブラリはCDNからJSファイルを配信する形で提供することを検討しました。

条件2. 公開が簡単なこと

npmに公開する場合、アクセストークンの管理(数か月ごとに更新など)が必要になり、面倒なので、これ以外の選択肢を検討しました。
また、TypeScriptによる型チェックを行いながらビルド不要でリリースできる方法を検討しました。

条件3. バンドルサイズを小さくすること

今回はUI部品をライブラリ化していくので、Reactコンポーネントとして構築することも検討しました。
しかし、ライブラリのユーザーがReactを使用していない場合、このコンポーネントのためだけに追加で130KBをダウンロードさせることになってしまいます(これはVue.jsコンポーネントやPreactコンポーネントとして構築した時も同じ)。
そのため、これ以外の方法を検討しました。

条件4. 全モダンブラウザで利用可能なこと

ただしIE対応はしないことにしました。

以上の条件から、以下のような構成でライブラリを作成・配信しました。

  • Denoを使用して開発
    • ブラウザで動かすコードをそのまま型チェックにかけられる(=ビルドステップ不要)
  • https://deno.land/x で公開
    • ここに公開しておけば、ブラウザから直接scriptタグで読み込める(CDN代わりになる)
    • GitHub連携ができ、新しいリリースをGitHub上で作成すると自動で新しいバージョンがpublishされる
      • npm publishで必要だったアクセストークンの管理等は不要
    • ドキュメントも自動生成される
  • WebComponentでコンポーネント化
    • 結果、このライブラリ単独のサイズは2.8KBになったので充分許容範囲

ライブラリのサイズについては、依存関係のpdf.jsのサイズが大きいという問題があります。そこで、

  • モバイル端末の場合 → pdf.jsを使って表示
  • それ以外の場合 → ブラウザがPDF埋め込み表示に対応しているため、それを使用

という方法でロードサイズを抑えました。

まとめ

  • PDFをHTMLに(全デバイス対応で)埋め込むのは意外と面倒
  • scriptタグを1行差し込むだけでPDFが埋め込めたら最高→作った
  • https://deno.land/x/embed_pdf で公開中

おまけ:車輪の再発明

実は、同様の思想のライブラリはこれまでに結構作成されています。

しかし、6~8年前に開発が止まっている、古すぎてビルド手順が不明、最初の1ページしか表示できない、次ページボタンなどのUI要素は自分で作成する必要がある、pdf.jsは別途自分でダウンロードする必要がある、など今回のユースケースには合わなそうなものばかりでした。
そのため仕方なく自分が新たにライブラリを書いてリリースしておきました。

54
45
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
54
45