アクトインディ開発者ブログ

子供とお出かけ情報「いこーよ」を運営する、アクトインディ株式会社の開発者ブログです

Rails で LaTeX を使って帳票出力

こんにちは、tahara です。

システム開発で、もう15年くらい前からやってみたいことがありました。 Web アプリでの帳票出力に LaTeX を使うことです。 社内システムながらようやくその機会に恵まれました。

rails-latex といういい gem があり、めんどうなところは全部めんどうみてくれます。

おきまりの Gemfile

gem 'rails-latex'

platex と xdvipdfmx で PDF にするためのコマンドを作っておきます。

bin/platex_xdivpdfmx

#!/bin/sh

platex -halt-on-error -shell-escape -interaction=batchmode input && xdvipdfmx input

config/initializers/rails_latex.rb でそのコマンドを使うように指定します。

# platex のオプションは bin/platex_xdvipdfmx の中で指定している。
LatexToPdf.config.merge! :command => "#{Rails.root}/bin/platex_xdvipdfmx"

HTML と同じ感覚で ERB の使って LaTeX のコードを書きます。 レイアウも使えます。

app/views/layouts/application.pdf.erbtex

\documentclass{jsarticle}

\usepackage[T1]{fontenc}
\usepackage{textcomp}
\usepackage[utf8]{inputenc}
\usepackage{lmodern}
\usepackage[deluxe, multi]{otf}
\usepackage{tabularx}
\usepackage[dvipdfmx]{graphicx}
\usepackage{overpic}
\usepackage{float}
\usepackage{ascmac}

\pagestyle{empty}
<%= yield :preamble %>

\begin{document}

%均等割
\newcommand{\kintou}[2]{%
  \leavevmode
  \hbox to #1{%
    \kanjiskip=0pt plus 1fill minus 1fill
    \xkanjiskip=\kanjiskip
    #2}}

%セル内で中央揃えをする。
\newcolumntype{C}{>{\centering\arraybackslash}X}
%セル内で左揃え。
\newcolumntype{R}{>{\raggedright\arraybackslash}X}
%セル内で右揃え。
\newcolumntype{L}{>{\raggedleft\arraybackslash}X}

<%= yield %>
\end{document}

views/invoices/show.pdf.erb

<%# -*- latex -*- %>
<%= content_for :preamble do -%>
  \setlength{\voffset}{-33mm}
  \setlength{\textheight}{280mm}
  \setlength{\hoffset}{-10mm}
  \setlength{\textwidth}{180mm}
<% end -%>

\begin{flushleft}

  \begin{tabularx}{180mm}{|X|c|r|c|r|} \hline
    \multicolumn{1}{|c|}{契約内容} &
    掲載期間 &
    \multicolumn{1}{|c|}{単価} &
    数量 &
    \multicolumn{1}{|c|}{金額} \\ \hline
    <% @load_blancer.items.each do |item| %>
      <%=lesc item.ordered_product.name %> &
      <%=lesc range_start_end_date_with_formate(object: item, year_format_shortcuted: false) %> &
      <%=lesc number_to_currency_for_pdf(item.price) %> &
      <%=lesc number_to_currency(item.quantity, unit: '') %> &
      <%=lesc number_to_currency_for_pdf(item.quantity * item.price) %>
      \\ \hline
    <% end %>
    \multicolumn{4}{|r|}{税抜} &
      <%=lesc number_to_currency_for_pdf(@load_blancer.totaler.total_without_tax.to_i) %>
      \\ \hline
    \multicolumn{4}{|r|}{消費税(<%=lesc @load_blancer.totaler.consumption_tax %>\%)} &
      <%=lesc number_to_currency_for_pdf(@load_blancer.totaler.only_tax.to_i) %>
      \\ \hline
    \multicolumn{4}{|r|}{合計} &
      <%=lesc number_to_currency_for_pdf(@load_blancer.totaler.total_with_tax.to_i) %>
      \\ \hline
  \end{tabularx}

\end{flushleft}

そうそう HTML での h と同様に lesc で LaTeX 用のエスケープをおこなうために ApplicationHelper に lesc メソッドを作っておきます。

app/helpers/application_helper.rb

module ApplicationHelper
  def lesc(text)
    LatexToPdf.escape_latex(text)
  end
end

以上です。これで、夢が1つかないました。感謝。

最後に、弊社では デザイナーエジニア を募集しています。 まずはお話だけでも。よろしくお願いします!