HTML

【サンプルあり】jsPDFとhtml2canvasを併用して HTML画面をPDF化しよう!

みなさん、こんにちは。どんぶラッコです。

本日は、 jsPDFhtml2canvas という2つのライブラリを使ってWebページをPDFで保存できる機能を作ってみましょう!

グランくん
グランくん
すごく便利な機能ではあるのですが、万能ではないということは先に言っておきますね。仕組みとしては html2canvasを使ってHTML要素を画像化→それをPDFに貼り付けるという流れなので、CSSが意図通りに表示されなかったりします。。

どんぶラッコ
どんぶラッコ
あとは、画像として貼り付けるので文章が文章として認識されないですね。OCR対応をしてくれるライブラリと組み合わせればあるいは…という感じもしますが、それにしても二度手間になってしまいますね。

グランくん
グランくん
ただ、ブラウザ側の技術だけでPDF化処理が完了するというのは魅力的ではあります。筆者もたまにお仕事で使っています!

サンプル

See the Pen jsPDFとhtml2canvasを使ってHTMLページをPDF化する by cha1ra (@cha1ra) on CodePen.

グランくん
グランくん
「PDFとして保存」ボタンを押すと実際の挙動が確認できるよ!

改めて、今回使ったライブラリをご紹介します。

まずは jsPDF 。 PDF化処理を担うライブラリです。

次に html2canvas。HTML要素をcanvas化して画像にしてくれるライブラリです。

ライセンスはどちらも MIT です(2020年11月12日現在)。

コード解説

では実際のコードをみていきましょう。まずはHTMLから。

<div id="capture">
  <p>
    id <code>capture</code> の中身を画像化してPDFにするサンプル
  </p>
  <div>
    <button id="btn">
      PDFとして保存
    </button>
  </div>
</div>

今回は id="capture"の要素内をPDF化する、という設定で記述しているので、captureが付与された <div>タグで囲っています。

続いてJavaScript。

// If you install via npm ... 
// import { jsPDF } from 'jspdf'
// import * as html2canvas from 'html2canvas'

const button = document.getElementById('btn')

button.addEventListener('click', (event) => {
  const source = document.getElementById('capture')
  html2canvas(source).then(capture => {
    const imgData = capture.toDataURL('image/png')
    const doc = new jsPDF()
    const width = doc.internal.pageSize.width
    doc.addImage(imgData, 'PNG', 10, 10, width * 0.9, 0)
    doc.save("sample.pdf")
  })
})

関数化せずにだらだら書いてしまっているので、機能ごとに分解してみていきましょう。

まずはボタンのクリックイベントを取得しています。

const button = document.getElementById('btn')

button.addEventListener('click', (event) => {
  // 中略
})

これはわかりやすいですね。続いてHTML要素の画像化処理を実施しています。

const button = document.getElementById('btn')

button.addEventListener('click', (event) => {
  // ここから追記
  const source = document.getElementById('capture')
  html2canvas(source).then(capture => {
    const imgData = capture.toDataURL('image/png')
    // 中略
  })
})

定数sourceid="capture"のDOM要素を格納し、それを html2canvas() に食わせています。

html2canvasはPromiseオブジェクトを返すので、そのまま .then でつなげて記載します

グランくん
グランくん
非同期処理ってやつだね!

続いて、jsPDFの処理です。

const button = document.getElementById('btn')

button.addEventListener('click', (event) => {
  const source = document.getElementById('capture')
  html2canvas(source).then(capture => {
    const imgData = capture.toDataURL('image/png')
    // ここから追記
    const doc = new jsPDF()
    const width = doc.internal.pageSize.width
    doc.addImage(imgData, 'PNG', 10, 10, width * 0.9, 0)
    doc.save("sample.pdf")
  })
})

doc.internal.pageSize.width で PDFの横幅を取得しています。そして、doc.addImage()でPDFに画像を貼り付ける処理をしています。


手順を分解すると結構簡単ですよね!

ちなみに、npmyarnを使ってインストールした場合(モジュールとして読み込みたい場合)、import文の書き方は下記の通りです。

import { jsPDF } from 'jspdf'
import * as html2canvas from 'html2canvas'

また、PDFの2ページ目に貼り付けたい場合、doc.addPage()と記載するだけでOKです!

みなさんも試してみてください〜

ABOUT ME
どんぶラッコ
ECコンサルタント、システムエンジニアを経て、quintet株式会社CTOに就任。普段はNuxt.jsやLaravelを使用しています。

\面白いと思ったら/

記事のシェア & Twitter のフォロー をお願いします!

@proglearn
RELATED POST

COMMENT

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です