More than 1 year has passed since last update.

Goal

* Rails4でPDF出力したい
* htmlでレイアウトしたドキュメントを出力したいため、htmlベースのpdf生成ツールを採用する
* => Wicked PDFを採用

* pdfで日本語出力したい
* pdfでページブレイク(pdfで次のページから表示するやつ)をやりたい
* htmlでbackground画像を指定したいpdfにも表示したい

Notice

* wkhtmltopdfというhtml=>pdf変換ツールがあり、Wicked PDFはこれをRails用にラップしてるようなイメージ
** そのため、wkhtmltopdfがインストールされていないとWicked PDFを動かすことができない
** wkhtmltopdfは細かいバグがちょこちょこあるらしく、最新版を使ったほうがいい
** 2014/04現在、gemでインストールできるwkhtmltopdfは最新版ではない
*** 自分が試したところでは、gemの最新版ではページブレイクができないバグがあった
** 環境差分が問題になることが間違いないのが歯がゆいけど、wkhtmltopdfはgemを使わず、サーバに直接インストールしてパスを通す
*** (一旦gemでwkhtmltopdfインストールしてみて、バグが再現したらgemパッケージをあきらめてサーバにインストールする方法でもいいかもしれない)

Server Info

$ uname -a
Linux *** 2.6.32-431.el6.x86_64 #1 SMP Fri Nov 22 03:15:09 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux

$ cat /etc/issue
CentOS release 6.5 (Final)
Kernel \r on an \m

$ head Gemfile
source 'https://rubygems.org'
ruby '2.1.1'
gem 'rails', '4.0.2'

Setup Manual

# root user
cd /usr/local/src
pwd

Install wkhtmltopdf

References
## 
## 依存?するパッケージをインストールしておく
## 

yum install libXext  libXrender  fontconfig  libfontconfig.so.1

## 
## ----------------------
## wkhtmltopdf pre build package install
## ----------------------
## http://wkhtmltopdf.org/
## http://wkhtmltopdf.org/downloads.html
## このURLのstableから探す
## 

wget "http://sourceforge.net/projects/wkhtmltopdf/files/0.12.0/wkhtmltox-linux-amd64_0.12.0-03c001d.tar.xz/download?use_mirror=jaist" -O wkhtmltox-linux-amd64_0.12.0-03c001d.tar.xz
tar xvf wkhtmltox-linux-amd64_0.12.0-03c001d.tar.xz
mv -i wkhtmltox /usr/local/

cd ${work_dir}
/usr/local/wkhtmltox/bin/wkhtmltopdf http://google.com google.pdf
ls -l google.pdf
  # googleのホームページがpdf出力されることを確認
  # 表示の問題があったとき、原因切り分けのデバッグにも使えそう

/usr/local/wkhtmltox/bin/wkhtmltopdf -V | head
  # Name:
  #   wkhtmltopdf 0.12.0 03c001de254b857f08eba80b62d4b6490ffed41d

Install Wicked PDF

wicked_pdfだけgemでinstallすることにする

#gem 'wkhtmltopdf-binary'
gem 'wicked_pdf'

Setup Rails Initializers, Controllers, ...

config/initializers/wicked_pdf.rb
WickedPdf.config = {
  :exe_path => '/usr/local/wkhtmltox/bin/wkhtmltopdf'
}
app/controllers/reports_controller.rb
  # show.pdf.erbという名前で(中身はhtml)ファイルを用意するとpdf出力できる
  # /controller/action(/parameters).pdfのURLでアクセスする
  # マルチバイト文字を出力したい場合はencodingを指定する
  # 背景画像をPDFにも出力したい場合はno_background: falseを指定する
  def show
    respond_to do |format|
      format.pdf do
        render pdf: 'show',
          layout: 'report_pdf.html',
          encoding: 'UTF-8',
          no_background: false
      end
    end
  end

Fonts

http://ipafont.ipa.go.jp/ipaexfont/download.html
* 日本語のフォントとしてIPAフォントというのがよく使われるようだったのでとりあえずこれをinstall
* stylesheetで指定しているフォントを使いたい場合は、ttfファイルだけぬきとって、この手順どおりに反映させればできるはず
http://qiita.com/metheglin/items/c7ba32edb1987202e65d
* microsoftコアフォントをインストールしたい場合は上記を参照(欧文系の有名なやつのみ)

Font Install

  • PDFをサーバ側で生成する場合、サーバ側にフォント情報がなければいけないのでinstallする
  • CentOSには有名なフォントデータなどほとんど入ってない
## 
## -------------------
## ttf download
## -------------------
## http://ipafont.ipa.go.jp/ipaexfont/download.html
## このURLから探す
## 

wget "http://ipafont.ipa.go.jp/ipaexfont/IPAexfont00201.php" -O IPAexfont00201.zip
unzip  IPAexfont00201.zip
ls -l IPAexfont00201/*ttf

## 
## ttfをフォントディレクトリに移動
## 

mkdir -p /usr/share/fonts/japanese/TrueType
mv -i IPAexfont00201/*ttf /usr/share/fonts/japanese/TrueType/
ls -l /usr/share/fonts/japanese/TrueType/

## 
## サーバに反映
## 

fc-cache -fv
  # /usr/share/fonts: caching, new cache contents: 0 fonts, 2 dirs
  # /usr/share/fonts/default: caching, new cache contents: 0 fonts, 1 dirs
  # /usr/share/fonts/default/Type1: caching, new cache contents: 35 fonts, 0 dirs
  # /usr/share/fonts/japanese: caching, new cache contents: 0 fonts, 1 dirs
  # /usr/share/fonts/japanese/TrueType: caching, new cache contents: 2 fonts, 0 dirs
  # /usr/share/X11/fonts/Type1: skipping, no such directory
  # /usr/share/X11/fonts/TTF: skipping, no such directory
  # /usr/local/share/fonts: skipping, no such directory
  # /root/.fonts: skipping, no such directory
  # /var/cache/fontconfig: cleaning cache directory
  # /root/.fontconfig: not cleaning non-existent cache directory
  # fc-cache: succeeded

## 
## 確認
## 
fc-list  | grep IPA
  # IPAexゴシック,IPAexGothic:style=Regular,Regulare
  # IPAex明朝,IPAexMincho:style=Regular

Stylesheetでフォント指定

/* 
  @font-faceで指定したやつは反映されなかった.
  ふつうにbodyなどに指定する.
  ※この場合、Arialがインストールされてる必要がある.
*/
body {
  font-family: 'Arial' !important;
}

Page break

http://stackoverflow.com/questions/5806943/rails-wickedpdf-page-breaks
* 冒頭で書いたようにgemパッケージのwkhtmltopdfだとこれがうまくいかなかった
* いろんなパターンでできると思うけど、とりあえず以下のcss,htmlで動くことは確認

.page-break { display:block; clear:both; page-break-after:always; }
<div class="page-break">
    1ページ目
</div>
<div class="page-break">
    2ページ目
</div>

Background Image

https://github.com/mileszs/wicked_pdf/issues/124

  • まず、デフォルトではwicked pdfの設定で背景画像を表示しない設定になっている!
  • 表示するためには、出力時にno_background: falseを指定する
  • CSSで画像のパスを指定するときは、wicked_pdf_メソッドは使わない
  • かわりに、asset pipelineでpdf.css.scss.erbのようにerb形式にして、下記例のように力技でパスを書き込む
  • background: url(!!!この部分にサーバの絶対パスが指定されるように記述する!!!)
  • 例); background: url(/vagrant/shared/sample_app/app/assets/images/report/background.jpg)
  • 上のURLに背景画像はjpgじゃないとだめってかいてあったけど、自分の環境ではgifでもいけた
app/assets/stylesheets/pdf.css.scss.erb
background:url(<%= Rails.root.join('app', 'assets', 'images', 'report', 'background.jpg').to_s %>) no-repeat;
app/controllers/reports_controller.rb
  def show
    respond_to do |format|
      format.pdf do
        render pdf: 'show',
          layout: 'report_pdf.html',
          encoding: 'UTF-8',
          no_background: false
      end
    end
  end

pdfで出力されるときのhtmlをDebugする

show_as_html: params[:debug].present?
app/controllers/reports_controller.rb
  def show
    respond_to do |format|
      format.pdf do
        render pdf: 'show',
          layout: 'report_pdf.html',
          show_as_html: params[:debug].present?,
          encoding: 'UTF-8',
          no_background: false
      end
    end
  end
http://<url>.pdf?debug=true
でアクセスする