RailsアプリでPDFファイルを出力することがあってそのときにハマったことをメモする
対象バージョン
wicked_pdf (2.1.0) wkhtmltopdf-binary (0.12.6.5)
HTMLファイルでデバッグ的な何かをする
PDFでデザイン崩れを修正するのは一苦労なので、render時に show_as_html
を渡す。
そうするとHTMLでデザインが見れるのでブラウザのdev toolsでCSSをいじって微調整ができる。
ただし!あくまでもブラウザで見えるだけであり、実際のPDFとはまた見え方が違うので過信しすぎてはいけない
respond_to do |format| format.pdf do render pdf: name, template: template, show_as_html: params[:debug].present? && !Rails.env.production? end end
Flexboxを使うときにはベンダープレフィックスが必要
タイトルの通りFlexboxを使うときはベンダープレフィックスが必要となる。これはwkhtmltopdfが古いブラウザエンジンを使っているため。
例えばこういう書き方が必要となってくる
.flex-row-container{ display: flex; justify-content: space-between; align-items: center; display: -webkit-box; -webkit-box-pack: justify; -webkit-box-align: center; }
.flex-column-container { display: flex; flex-direction: column; display: -webkit-box; -webkit-box-orient: vertical; }
画像を埋め込む
Base64で埋め込むことになる。理由としては、画面から見えるときはいつもの癖で <img src="http://localhost:3000/some_image.jpg">
みたいにしてもできることはできるが、sidekiqなどの非同期処理で画像を埋め込むことを考慮すると(http://localhost:3000
しても画像はみえないため)Base64で埋め込んだほうが良い。wicked_pdfがヘルパーを作っているので、assetからは以下のようにして読み出せる。
<%= image_tag wicked_pdf_asset_base64("some_image") %>
wicked_pdfではwebpacker用のヘルパーもあるが、上記の理由で使ってはいない。SGVファイルを埋め込むヘルパーがチームで用意されていたのでそれを使っている。
<%= embedded_svg(asset_pack_path("some_image.svg")) %> def embedded_svg(filename, options = {}) File.open("public/#{filename}", 'rb') do |file| doc = Nokogiri::HTML::DocumentFragment.parse file.read svg = doc.at_css 'svg' svg['class'] = options[:class] if options[:class].present? doc.to_html.html_safe end end
マシンパワーで頑張ってもらう
ローカル環境で開発するときはやはり遅いのでマシンパワーで頑張ってもらう