Rails
PDF
font
wicked_pdf

wicked_pdf で カスタムフォントを使う

Wicked PDFでカスタムフォントを使う.

フォントファイルをCDNからで読み込む場合

スタイルシートで @font-face を定義し,wicked_pdf_stylesheet_link_tag で読み込むだけ.

app/assets/stylesheets/fonts.sass.erb
@font-face
  font-family: 'Noto Sans JP'
  font-style: normal
  font-weight: normal
  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')

.custom-font
  font-family: "Noto Sans JP"
  font-weight: normal
  font-style: normal

ローカルに"Noto Sans CJK JP"がなければWebフォントの"Noto Sans JP"を利用するCSSの指定方法 のようにローカルに存在しないときにのみ、CDNから読み込むようにもできる.

app/assets/stylesheets/application.sass
/*
 *= require_self
 */
@import fonts
app/assets/views/layouts/pdf.html.slim
doctype html
html lang='ja'
  head
    meta charset="utf-8"
    = wicked_pdf_stylesheet_link_tag 'application'
  body
    .custom-font
      = yield

フォントファイルをプロジェクトに追加するパターン

フリーのIPAフォントなどをダウンロードしプロジェクトに追加する.
image.png

app/assets/stylesheets/fonts.sass.erb
@font-face
  font-family: 'IPAex Gothic'
  font-style: normal
  font-weight: normal
  src: url('<%= font_path('ipaexg.ttf') %>') format('truetypee')

@font-face
  font-family: 'IPAex Mincho'
  font-style: normal
  font-weight: normal
  src: url('<%= font_path('ipaexm.ttf') %>') format('truetype')

.custom-font
  font-family: 'IPAex Gothic' // or 'IPAex Mincho' 使いたい方を指定
  font-weight: normal
  font-style: normal

他は,CDNで読み込む場合と同じ.

CDNで読み込んだcssファイル内のフォントが設定されない問題

例えばfontawesomeを = stylesheet_link_tag 'https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css' のように読み込んでいるケースで,Trouble with FontAwesome Iconsのようにアイコンが表示されない問題が発生する.
この問題はfont-awesome-railsを使っていれば解決される.

依存ライブラリ内で、フォントファイルの読み込みがエラーになる問題

例えば,uikit-sass-railsを読み込んでいる場合にPDF生成すると,次のようなエラーが発生する.

vendor/assets/stylesheets/extra/font-awesome.scss
//= depend_on_asset "fontawesome-webfont.eot"
//= depend_on_asset "fontawesome-webfont.otf"
//= depend_on_asset "fontawesome-webfont.svg"
//= depend_on_asset "fontawesome-webfont.ttf"
//= depend_on_asset "fontawesome-webfont.woff"
//= depend_on_asset "fontawesome-webfont.woff2"

@font-face {
  font-family: "FontAwesome";
  src: font-url('fontawesome-webfont.eot');
  src: font-url('fontawesome-webfont.eot?#iefix') format('embedded-opentype'), font-url("fontawesome-webfont.otf") format("opentype"), font-url('fontawesome-webfont.woff2') format('woff2'), font-url('fontawesome-webfont.woff') format('woff'), font-url('fontawesome-webfont.ttf') format('truetype'), font-url('fontawesome-webfont.svg?#fontawesomeregular') format('svg');
  font-weight: normal;
  font-style: normal;
}

これらの読み込みはPDF以外のページだと, asset pipeline で依存関係が解決され正常に読み込まれるのだが,PDFページで読み込む際に public/assets/ からフォントを探そうとして404エラーになってしまっていた.
show_as_html オプションでHTML表示して確認した.

image.png

今回はForkして暫定対応した.

vendor/assets/stylesheets/extra/font-awesome.scss
@import url(//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css);

この対応でPDF上にfont-awesomeが表示されるようになった.

ちなみに, uikit-sass-rails 内でエラーが出ている状態で,自プロジェクト内の application.sass 内で @import url(//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css); を読み込むと, show_as_html オプションでHTML表示したときは表示されるようになるが,PDFページではfont-awesomeが表示されなかった.