指定したURLのWebページをPDF、PNG化してくれるAPIサーバー「URL to PDF Microservice」の使い方

公開日:2020/03/23 更新日:2020/03/23
指定したURLのWebページをPDF、PNG化してくれるAPIサーバー「URL to PDF Microservice」の使い方のサムネイル
Photo by Christopher Gower on Unsplash

はじめに

特定のWebページをPDF化したりPNG化してダウンロードしたい場合に使える「URL to PDF Microservice」というリポジトリが公開されており、実際に使ってみたのでその手順をまとめます。「URL to PDF Microservice」は自分のサーバーにインストールして使用できます。

URL to PDF Microserviceについて

URL to PDF Microserviceは、GUIを持ったWebアプリではなく、APIサーバーです。すなわちWebアプリやモバイルアプリ等のフロントエンド側からHTTPリクエストを投げることで指定したURLをPDF化、もしくはPNG化してダウンロードできるようになります。 URL to PDF MicroserviceはPupetterというブラウザ操作のためのライブラリを使用しています。以下のような機能があります。

  • URLを指定、もしくはHTMLファイルを直接PDF、PNG、JPEGに変換可能
  • Herokuに簡単にインストール可
  • トークン認証をサポート

詳細については以下のURL to PDF MicroserviceのGitHubリポジトリを見てみてください。

github.com

Web page PDF rendering done right. Microservice for rendering receipts, invoices, or any content. Packaged to an easy API.

この記事では、URL to PDF MicroserviceをUbuntuにインストールして使う手順をまとめます。URL to PDF Microservicesへのアクセスにトークン認証を設定する方法もまとめます。 なお、URL to PDF Microserviceをパブリックに公開しないよう注意してください。公式リポジトリにも注意書きがありますが、URL to PDF Microserviceを動作させているサーバー内のファイルを外部から取得される可能性があります。ローカル内で使用するか、もしくはプロキシの後ろで使用するなど各自対応が必要です。

前提と環境

以下の通りとなります。Node.js環境が構築済であることが前提となります。

  • OS : Ubuntu 18.04
  • Node.js : 12.14.0(最低8以上)

URL to PDF MicroserviceをUbuntuにインストールする

まず公式リポジトリをGitでローカルにクローンします。ここでは、ホームディレクトリ直下にクローンします。

~/
$ git clone git@github.com:alvarcarto/url-to-pdf-api.git
$ cd url-to-pdf-api

その後、npmでインストールします。

~/url-to-pdf-api
$ npm install

以上でインストールが完了です。

設定ファイルを編集する

URL to PDF Microserviceの設定ファイルを用意します。デフォルトでは、.env.sampleという環境編集用のファイルが用意されているのでこれを使用します。

~/url-to-pdf-api
$ cp .env.sample .env

中身は以下のようになっています。

~/url-to-pdf-api/.env
# Guide:
#
# 1. Copy this file to .env
#
#    cp .env.sample .env
#
# 2. Fill the blanks

NODE_ENV=development
PORT=9000
ALLOW_HTTP=true

# Warning: PDF rendering does not work in Chrome when it is in headed mode.
DEBUG_MODE=false

URL to PDF Microserviceが待ち受けるポート番号などを変更したい場合は上記を編集します。 ここではデフォルトのままでいきます。

URL to PDF Microserviceを起動する

以下で起動します。

~/url-to-pdf-api
$ npm start

これでURL to PDF Microserviceに対してHTTPリクエストを投げれば指定したURLをPDFやPNGにしてレスポンスしてくれます。

指定したURLをPDFに変換してダウンロードする

URL to PDF Microserviceが起動した状態で以下のGETリクエストをターミナルから送信します。

~/url-to-pdf-api
$ curl -o google.pdf http://localhost:9000/api/render?url=http://google.com

ここではローカルのUbuntu上で動かしているため、HTTPリクエストの送信先をhttp://localhost:9000としています。URL to PDF Microserviceはデフォルトでは/api/renderというパスでリクエストを待ち受けます。 見て分かる通り、クエリでPDF化するURLを指定しています。 上記を実行すると、上記のcurlコマンド実行時のディレクトリにgoogle.pdfという名前でPDFがダウンロードされます。

なお、POSTリクエストでも可能でおそらくこちらのほうが使うことが多いと思います。以降では全てPOSTリクエストで説明します。

~/url-to-pdf-api
$ curl -o google-post.pdf -XPOST -d'{"url": "http://google.com"}' -H"content-type: application/json" http://localhost:9000/api/render

指定したURLをPNGに変換してダウンロードする

outputオプションを指定することでPNG、またはJPGとして指定したURLをダウンロードできます。

~/url-to-pdf-api
$ curl -o google.png -XPOST -d'{"url": "http://google.com", "output": "screenshot", "screenshot": { "type": "png" } }' -H"content-type: application/json" http://localhost:9000/api/render

上記を見てわかる通り、以下のようなデータをPOSTリクエストで送信しています。

~/url-to-pdf-api
{
  url: "https://google.com",
  output: "screenshot",
  screenshot: {
    type: "png"
  }
}

上記で指定できるオプションはかなり豊富で公式リポジトリ内のドキュメントに記載されています。

なお、例えばフロントエンド側からaxiosを使用してPOSTリクエストを送信し、そのレスポンスとしてPDFをダウンロードしたい場合は以下のようなリクエストになると思います。

~/url-to-pdf-api
import axios from 'axios'

    const pdfOptions = {
      url: 'http://google.com',
      // 以下のようにPDFの大きさやマージンなども指定可能
      pdf: {
        width: '1600px',
        height: '1200px',
        margin: {
          top: '0',
          right: '0',
          bottom: '0',
          left: '0'
        }
      }
    }
    await axios
      .post(
        'http://localhost:9000/api/render',
        pdfOptions,
        {
          responseType: 'blob'
        }
      )
      .then((response) => {
        // レスポンスに対する処理。以下は例
        const blob = new Blob([response.data], { type: 'application/pdf' })
        const link = document.createElement('a')
        link.href = window.URL.createObjectURL(blob)
        link.download = 'test.pdf'
        link.setAttribute('target', '_blank')
        link.style.display = 'none'
        document.body.appendChild(link)
        link.click()
        document.body.removeChild(link)
      })
      .catch((error) => {
        // error時の処理
      })
      .finally(() => {
        // finally 処理
      })

URL to PDF Microserviceへのアクセスをトークン認証する

以下のように.envファイル内にAPI_TOKENSを指定することで、トークン認証できます。

~/url-to-pdf-api/.env
# Guide:
#
# 1. Copy this file to .env
#
#    cp .env.sample .env
#
# 2. Fill the blanks

NODE_ENV=development
PORT=9000
ALLOW_HTTP=true
API_TOKENS='yourtoken' # 追加

# Warning: PDF rendering does not work in Chrome when it is in headed mode.
DEBUG_MODE=false

そしてHTTPリクエストを送信する側で以下のようにx-api-keyをヘッダで指定します。

~/url-to-pdf-api
    await axios
      .post(
        'http://localhost:9000/api/render',
        pdfOptions,
        {
          headers: {
            'x-api-key': 'yourtoken' // .envで指定したAPI_TOKENを渡す
          },
          responseType: 'blob'
        }
      )
      .then((response) => {
 // 省略

認証が必要なWebページをPDF化したい場合

認証が必要なWebページをPDF化したい場合は、そのWebページの認証情報を別途HTTPリクエストに組み込む必要があります。ただ、執筆時点では認証が必要なWebページの認証情報を組み組むためのオプションが用意されていないようでした。 これについてはAdded ability to setExtraHTTPHeaders #78でもリクエストが出されており、実際にこちらでプルリクエストが出されています。

このプルリクエストはまだマージされていませんが、もし認証が必要なWebページをPDF化したい場合は各自で記述してしまえばできると思います。私はまさにJWT認証をしているWebページをPDF化する必要があったため、上記のプルリクエストにある通りに修正して使っています。上記のプルリクエスト通りに修正後、以下のようにオプションを追加することで認証をパスできます。

~/url-to-pdf-api
    const authHeader = {
      Authorization: `Bearer yourjwttoken`
    }
    const pdfOptions = {
      url: rootState.user.apiurl + '/lessons/' + lessonid + '/certificate.pdf?debug=true',
      setExtraHTTPHeaders: authHeader
    }

まとめ

指定したURL簡単にPDF化したりPNGしたりできるURL to PDF Microserviceのインストール手順と使い方をまとめました。

関連記事

開発アプリ

nanolog.app

毎日の小さな出来事をなんでも記録して、ログとして残すためのライフログアプリです。