Help us understand the problem. What is going on with this article?

ElixirでPDFファイルを生成しPhoenixで静的ファイルとしてホスティングする

More than 1 year has passed since last update.

関わっている案件でElixir+Phoenixで組んでるバックエンドサーバーでPDFを作成してWeb表示する要件が出てきたので、やってみました。

試したのは以下のライブラリ

https://github.com/gutschilla/elixir-pdf-generator

wkhtmltopdfというライブラリのWrapperということ
使用方法は超簡単だった。

手順

wkhtmltopdfをインストールする

以下の公式サイトからOSに合わせたインストーラを使用する。

https://wkhtmltopdf.org/downloads.html

筆者は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を追加

アクセスしてみる

http://0.0.0.0:4000/

image.png

http://0.0.0.0:4000/pdf/sample_pdf.pdf

image.png

簡単にできました。

WebKitでHTMLを描画してPDFにしているようなので、元のHTMLさえ作り込めば凝ったPDFも作れそうですね。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした