関わっている案件でElixir+Phoenixで組んでるバックエンドサーバーでPDFを作成してWeb表示する要件が出てきたので、やってみました。
試したのは以下のライブラリ
wkhtmltopdfというライブラリのWrapperということ
使用方法は超簡単だった。
手順
wkhtmltopdfをインストールする
以下の公式サイトからOSに合わせたインストーラを使用する。
筆者はMacで実施
プロジェクトの作成
> mix phx.new pdf_sample --no-ecto --no-brunch
depsの追加
mix.exs
def application do
[
mod: {PdfSample.Application, []},
extra_applications: [:logger, :runtime_tools, :pdf_generator] #<- :pdf_generator追加
]
end
defp deps do
[
{:phoenix, "~> 1.3.2"},
{:phoenix_pubsub, "~> 1.0"},
{:phoenix_html, "~> 2.10"},
{:phoenix_live_reload, "~> 1.0", only: :dev},
{:gettext, "~> 0.11"},
{:cowboy, "~> 1.0"},
{:pdf_generator, ">=0.3.7" }, #<- 追加
]
end
> mix .deps.get
コード本体
今回は試すだけだったので、モジュールを作らずにiexで実行した。
iex(1)> source_html = "<html><body><p>Hi there!</p></body></html>"
# ページサイズA5とファイル名を任意指定
iex(2)> { :ok, filename } = PdfGenerator.generate source_html, page_size: "A5",
filepath: "/Users/tsuchiro/code/samples/pdf_sample/priv/static/pdf", filename: "sample_pdf"
# 結果は作成されたファイルのフルパスがタプルで返ってくる
iex(3)> {:ok, pdf_path} = {:ok, "/var/folders/pz/2847mdrn0gz51b2tctnfqc740000gn/T/sample_pdf.pdf"}
# 静的ファイルのパスにコピーする
iex(4)> File.copy(pdf_path,"./priv/static/pdf/sample_pdf.pdf")
```
## 画面にリンクを追加
```html:/pdf_sample_web/templates/page/index.html.eex
<div class="jumbotron">
<h2><%= gettext "Welcome to %{name}!", name: "Phoenix" %></h2>
<p class="lead">A productive web framework that<br />does not compromise speed and maintainability.</p>
</div>
<div class="row marketing">
<div class="col-lg-6">
<h4>Resources</h4>
<ul>
<li>
<a href="http://phoenixframework.org/docs/overview">Guides</a>
</li>
<li>
<a href="https://hexdocs.pm/phoenix">Docs</a>
</li>
<li>
<a href="https://github.com/phoenixframework/phoenix">Source</a>
</li>
<li>
<!-- ↓ PDFファイルへのリンクを追加 -->
<a href="<%= static_path(@conn, "/pdf/sample_pdf.pdf") %>">PDF Document</a>
</li>
</ul>
</div>
<div class="col-lg-6">
<h4>Help</h4>
<ul>
<li>
<a href="http://groups.google.com/group/phoenix-talk">Mailing list</a>
</li>
<li>
<a href="http://webchat.freenode.net/?channels=elixir-lang">#elixir-lang on freenode IRC</a>
</li>
<li>
<a href="https://twitter.com/elixirphoenix">@elixirphoenix</a>
</li>
</ul>
</div>
</div>
エンドポイントにcssを追加する。
static_pathはpriv/static以下を指すが、デフォルトではアクセスできるパスに制限が掛かっているので、pdfフォルダを追加する。
plug Plug.Static,
at: "/", from: :pdf_sample, gzip: false,
only: ~w(css fonts images js pdf favicon.ico robots.txt) # <- pdfを追加
アクセスしてみる
簡単にできました。
WebKitでHTMLを描画してPDFにしているようなので、元のHTMLさえ作り込めば凝ったPDFも作れそうですね。