質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.10%

【Rails6】HTMLページをPDF化したい

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 1,212

score 1635

前提・実現したいこと

Rails6(on Alpine Linux、Docker)で htmlページをpdf化しようとしています。
ツールはwkhtmltopdfのラッパーgemであるwicked_pdfです。
ページそのものは問題ないのですが、pdf化するとWebフォントの読み込みなどCSSが適用されてない様子です。
対処法を教えてください。

<%= wicked_pdf_stylesheet_pack_tag "application" %>
<%= wicked_pdf_javascript_pack_tag "application" %>


でwicked_pdf用のJavascriptとCSSを読むはず(?)ですが、webpackerの理解が浅くそもそもどこのディレクトリに配置すればよいのかがわかりません。(多分この無知が原因?)
htmlのJavascriptとCSSはapp/javascript/packsとapp/javascript/stylesheets/下のファイルをロードできているので、レイアウトには問題ありません。

発生している問題・エラーメッセージ

このページをPDF化しようとしてます。問題なくCSSが適用されています。
HTML

結果はこうなってしまいます
PDF

コンソールでエラーもありません

Started GET "/?format=pdf" for 172.17.0.1 at 2019-12-06 02:18:46 +0000
Cannot render console from 172.17.0.1! Allowed networks: 127.0.0.0/127.255.255.255, ::1
Processing by HomeController#index as PDF
  Rendering home/index.pdf.erb within layouts/pdf.html
  Rendered home/index.pdf.erb within layouts/pdf.html (Duration: 0.1ms | Allocations: 5)
[Webpacker] Everything's up-to-date. Nothing to do
[Webpacker] Everything's up-to-date. Nothing to do
[wicked_pdf]: ["/usr/local/bundle/bin/wkhtmltopdf", "--encoding", "UTF-8", "--page-size", "A4", "file:////tmp/wicked_pdf20191206-3370-po4li.html", "/tmp/wicked_pdf_generated_file20191206-3370-1p7jnv4.pdf"]
  Rendering text template
  Rendered text template (Duration: 0.2ms | Allocations: 1)
Sent data index.pdf (55.4ms)
Completed 200 OK in 1934ms (Views: 8.6ms | ActiveRecord: 0.0ms | Allocations: 9979)

該当のソースコード

app/views/layouts/pdf.html.erb

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">  
    <title>PDF Sample</title>
    <link href="/application.css" type="text/css" rel="stylesheet">
    <%= wicked_pdf_stylesheet_pack_tag "application" %>
    <%= wicked_pdf_javascript_pack_tag "application" %>
    <%= stylesheet_pack_tag 'application' %>
    <%= javascript_pack_tag 'application' %>
  </head>

  <body>

  <%= yield %>

  </body>
</html>


うまく適用できないので、後記のapplication.scssをpublic/application.cssとして直接読み込んで試してます(効果なし)

app/views/home/index.pdf.erb

<h1>Home#index</h1>
<p>Find me in app/views/home/index.pdf.erb</p>

<p class="rounded">寿限無、寿限無、五劫の擦り切れ、海砂利水魚の、水行末・雲来末・風来末</p>
<p class="sans">寿限無、寿限無、五劫の擦り切れ、海砂利水魚の、水行末・雲来末・風来末</p>
<p class="serif">寿限無、寿限無、五劫の擦り切れ、海砂利水魚の、水行末・雲来末・風来末</p>

<H1>THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG. 1234567890</H1>
<H2>THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG. 1234567890</H2>
<H3>THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG. 1234567890</H3>
<H4>THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG. 1234567890</H4>
<H5>THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG. 1234567890</H5>
<H6>THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG. 1234567890</H6>

<h1>The quick brown fox jumps over the lazy dog. 1234567890</h1>
<h2>The quick brown fox jumps over the lazy dog. 1234567890</h2>
<h3>The quick brown fox jumps over the lazy dog. 1234567890</h3>
<h4>The quick brown fox jumps over the lazy dog. 1234567890</h4>
<h5>The quick brown fox jumps over the lazy dog. 1234567890</h5>
<h6>The quick brown fox jumps over the lazy dog. 1234567890</h6>

<h1>寿限無、寿限無、五劫の擦り切れ、海砂利水魚の、水行末・雲来末・風来末</h1>
<h2>寿限無、寿限無、五劫の擦り切れ、海砂利水魚の、水行末・雲来末・風来末</h2>
<h3>寿限無、寿限無、五劫の擦り切れ、海砂利水魚の、水行末・雲来末・風来末</h3>
<h4>寿限無、寿限無、五劫の擦り切れ、海砂利水魚の、水行末・雲来末・風来末</h4>
<h5>寿限無、寿限無、五劫の擦り切れ、海砂利水魚の、水行末・雲来末・風来末</h5>
<h6>寿限無、寿限無、五劫の擦り切れ、海砂利水魚の、水行末・雲来末・風来末</h6>

app/javascript/stylesheets/application.scss

@import url('https://fonts.googleapis.com/css?family=M+PLUS+Rounded+1c:500|Noto+Sans+JP:500|Noto+Serif+JP:500&display=swap&subset=japanese'); //フォント指定

@page {
  size: A4;
  margin: 0;
}
@media all {
  html, body {
    font-family: 'Noto Sans JP', sans-serif;
    padding: 10mm;
    width: 210mm;
    height: 297mm;
  }
}
html {  font-size:100%;}
h1 {  border-bottom: 4px solid #FF6600;}
.rounded {  font-family: 'M PLUS Rounded 1c', sans-serif;}
.sans {  font-family: 'Noto Sans JP', sans-serif;}
.serif {  font-family: 'Noto Serif JP', serif;}


app/controllers/home_controller.rb

class HomeController < ApplicationController
  def index
    respond_to do |format|
      format.html { redirect_to root_path(format: :pdf, debug: 1) }
      format.pdf do
        render pdf: "index",
          encoding: "UTF-8",
          layout: "pdf.html",
          show_as_html: params[:debug].present?,
          page_size: "A4"
      end
    end
  end
end

試したこと

以下のhtmlファイルを作り、直接wkhtmltopdfコマンドでpdf化した場合は、問題ありませんでした。なので、wkhtmltopdfには問題なさそうです。

<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <title>Sample</title>
    <link href="https://fonts.googleapis.com/css?family=Noto+Sans+JP&display=swap&subset=japanese" rel="stylesheet">
    <style type="text/css">
      body { padding: 0 20px 0 20px; font-family: 'Noto Sans JP', sans-serif; }
      @page { size: A4; margin: 0; }
      @media all { html, body { width: 210mm; height: 297mm; } }
      h1 { border-bottom: 4px solid #FF6600; }
    </style>
  </head>
  <body>
    <p class="rounded">寿限無、寿限無、五劫の擦り切れ、海砂利水魚の、水行末・雲来末・風来末</p>
    <p class="sans">寿限無、寿限無、五劫の擦り切れ、海砂利水魚の、水行末・雲来末・風来末</p>
    <p class="serif">寿限無、寿限無、五劫の擦り切れ、海砂利水魚の、水行末・雲来末・風来末</p>

    <H1>THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG. 1234567890</H1>
    <H2>THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG. 1234567890</H2>
    <H3>THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG. 1234567890</H3>
    <H4>THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG. 1234567890</H4>
    <H5>THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG. 1234567890</H5>
    <H6>THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG. 1234567890</H6>

    <h1>The quick brown fox jumps over the lazy dog. 1234567890</h1>
    <h2>The quick brown fox jumps over the lazy dog. 1234567890</h2>
    <h3>The quick brown fox jumps over the lazy dog. 1234567890</h3>
    <h4>The quick brown fox jumps over the lazy dog. 1234567890</h4>
    <h5>The quick brown fox jumps over the lazy dog. 1234567890</h5>
    <h6>The quick brown fox jumps over the lazy dog. 1234567890</h6>

    <h1>寿限無、寿限無、五劫の擦り切れ、海砂利水魚の、水行末・雲来末・風来末</h1>
    <h2>寿限無、寿限無、五劫の擦り切れ、海砂利水魚の、水行末・雲来末・風来末</h2>
    <h3>寿限無、寿限無、五劫の擦り切れ、海砂利水魚の、水行末・雲来末・風来末</h3>
    <h4>寿限無、寿限無、五劫の擦り切れ、海砂利水魚の、水行末・雲来末・風来末</h4>
    <h5>寿限無、寿限無、五劫の擦り切れ、海砂利水魚の、水行末・雲来末・風来末</h5>
    <h6>寿限無、寿限無、五劫の擦り切れ、海砂利水魚の、水行末・雲来末・風来末</h6>
  </body>
</html>

補足情報(FW/ツールのバージョンなど)

PDF を出力できる Rails アプリを作成して Heroku で動かすこちらを参考に作りました(ほぼ丸写しで、Rails6とプラットホームの違いによる差くらいです)
Ruby on Rails 6.0.1
Ruby 2.6.5
wicked_pdf 1.4.0
wkhtmltopdf-binary-edge-alpine 0.12.5.0
wkhtmltopdf 0.12.5
Alpine Linux 3.10.3

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

wicked_pdf でWebフォントを呼び出すには、
一旦 @font-face で定義してから呼び出す必要があります。

具体的な手法を調べていたら、ばっちりちょうどいい参考例があったのでどうぞ。様々なケースのHowToも含んだ解説なので、より分かりやすいと思います。↓
https://qiita.com/tanakaworld/items/18ec7ff7c7a9fadcf0ae

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/12/06 20:16

    @font-faceで定義したら、もとのHTMLページもWebフォントが適用されませんでした(もちろんPDFにも)。ローカルにフォントをダウンロードしていないせいでしょうか?(そんなはずはないと思っているのですが)
    application.scssとpdf.html.erbは以下の通りに変更しました。
    $ cat app/javascript/stylesheets/application.scss
    @font-face
    font-family: 'Noto Sans JP'
    font-style: normal
    font-weight: 400
    src: local("Noto Sans CJK JP"),
    url(//fonts.gstatic.com/ea/notosansjp/v5/NotoSansJP-Regular.woff2) format('woff2'),
    url(//fonts.gstatic.com/ea/notosansjp/v5/NotoSansJP-Regular.woff) format('woff'),
    url(//fonts.gstatic.com/ea/notosansjp/v5/NotoSansJP-Regular.otf) format('opentype')

    @import fonts

    @page { size: A4; margin: 0; }
    @media all {
    html, body {
    font-family: 'Noto Sans JP';
    padding: 10mm;
    width: 210mm;
    height: 297mm;
    }
    }

    html { font-size:100%; }
    h1 { border-bottom: 4px solid #FF6600; }
    .rounded { font-family: 'M PLUS Rounded 1c'; }
    .sans { font-family: 'Noto Sans JP'; }
    .serif { font-family: 'Noto Serif JP'; }

    $ cat app/views/layouts/pdf.html.erb
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8">
    <title>PDF Sample</title>
    <%= wicked_pdf_stylesheet_pack_tag "application" %>
    <%= wicked_pdf_javascript_pack_tag "application" %>
    <%= stylesheet_pack_tag 'application' %>
    <%= javascript_pack_tag 'application' %>
    </head>

    <body>

    <%= yield %>

    </body>
    </html>

    キャンセル

  • 2019/12/07 21:22 編集

    @font-face {
    font-family: 'Noto Sans JP';
    font-style: normal;
    font-weight: 400;
    src: local("Noto Sans CJK JP"),
    url(//fonts.gstatic.com/ea/notosansjp/v5/NotoSansJP-Regular.woff2) format('woff2'),
    url(//fonts.gstatic.com/ea/notosansjp/v5/NotoSansJP-Regular.woff) format('woff'),
    url(//fonts.gstatic.com/ea/notosansjp/v5/NotoSansJP-Regular.otf) format('opentype');
    }

    //@import fonts
    としたら、Webフォントが適用されました(参考にしたのが.sass.erbのファイルで自分のが.scssファイルの違いでした)

    しかし、依然PDF化するとCSS(多分JavaScriptも)が適用されません

    キャンセル

  • 2019/12/09 22:20

    wicked_pdfとwebpacker(rails6)の組合せは断念しました。
    仕組みがわかったので、自分でコード書くことのにしました(その代わり汎用性なし)

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.10%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る