Rails4 Wicked PDF導入注意点


# 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
* http://aurobindapothal.wordpress.com/2013/06/29/how-to-fix-wkhtmltopdf-error-while-loading-shared-libraries-libfontconfig-so-1-on-centosfedorarhel-server/
* http://wkhtmltopdf.org/
* http://stackoverflow.com/questions/21510153/wkhtmltopdf-table-overflow-horizontally-auto-page-break

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

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することにする

```Gemfile
#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には有名なフォントデータなどほとんど入ってない

```bash
## 
## -------------------
## 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でフォント指定

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



# Page break

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

```css
.page-break { display:block; clear:both; page-break-after:always; }
```

```html
<div class="page-break">
	１ページ目
</div>
<div class="page-break">
	２ページ目
</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
でアクセスする
```