帳票作成なら LaTeX(TeX) 一択

# タイトルどおり、帳票作成に LaTeX (TeX) がおすすめという内容です。

ここでは、何らかのプログラミング言語を扱える[^1]けれど $\LaTeX$($\TeX$) をあまり知らない人向けに、帳票作成のツールとしての観点から、$\LaTeX$($\TeX$) の紹介をしていきます（なので厳密さと詳細さは省略します）。多く使われればノウハウがフィードバックされて、私自身も得になるという動機です。
[^1]:TeXのソースの詳しい解説がなくても他の言語の経験から何となく理解できる程度の知識がある

## LaTeX のメリット
0. なんと言っても**コスト**[^2]がかからない
0. いわゆる**枯れた技術**[^3]だから安定感あり
0. パッケージ(ライブラリ)が**豊富**
0. 環境に依存しない（Linux, MacOS, Windows にて使用可能）
[^2]: コストの意味には色々（人的コスト、時間的コストなど）あるが、ここでは金銭的コストの意味
[^3]: 初版1984年。ただし $\LaTeX3$ が控えていていろいろ問題が生じる可能性があるらしい
 
## LaTeX のデメリット
0. $\TeX$ 言語(マクロ)の癖が強い(学習コストが高い)
0. フォントの扱いが難しい
0. WYSIWIG で編集ができない
0. ファイルサイズが超巨大

## そもそも [LaTeX](https://ja.wikipedia.org/wiki/LaTeX) ([TeX](https://ja.wikipedia.org/wiki/TeX)) ってなに？
テキストベースの組版処理システムです。レイアウトを HTML や XML のようなマークアップ言語で記述して、PDF[^4]を作れます。しかも、出版レベルのものができます。
[^4]:PDF を作成するためだけではないが、現状では事実上 PDF でよいでしょう。
> TeX は Donald Ervin Knuth によって開発された，フリーの「組版システム」です。
> 1994年に LaTeX の新版 LaTeX 2ε（トゥー・イー），1995年にはアスキーから日本語版 pLaTeX 2ε が出ました。
（[LaTeX入門](https://texwiki.texjp.org/?LaTeX%E5%85%A5%E9%96%80)から引用）


# ざっくり使い方
全体像の概要を掴むためですので、興味を持った方はネットで検索するか[ LaTeX2ε 美文書作成入門](https://gihyo.jp/book/2020/978-4-297-11712-2)にあたってください。

0. ソース（原稿）をテキストデータ（拡張子は.tex）で作成する→`sample.tex`
テキストなのでバージョン管理も楽
0. コマンドでタイプセット（コンパイル）する→`latexmk sample`[^5]
0. PDFができあがる→`sample.pdf`
[^5]:`uplatex sample && dvipdfmx sample`コマンドのめんどくさいを楽にしたもの

```tex:sample.tex
\RequirePackage{plautopatch}
\documentclass{jlreq} % ①
\usepackage[uplatex,deluxe,expert,jis2004]{otf} % ②
\begin{document} % ③
  \begin{center} % ④
    Hello World !!
  \end{center}
  \Huge % ⑤
  Hello World !!
\end{document}
```

- ソースの構文は HTML に類似した構造をしている。③の `\begin{document}`より前（プリアンブルと呼ばれる）が HTML での`<head>`に近い。③以降が`<body>`に相当する
- ①は文書の種類、他に jsarticle など(とりあえず jlreq でよいと思う→[日本語 LaTeX の新常識 2021](https://qiita.com/wtsnjp/items/76557b1598445a1fc9da) 参考)
- ②日本語を扱うときの便利な[パッケージ](https://www.ctan.org/pkg/japanese-otf)
- ④はセンタリングをする範囲の指定 ( `<div style="text-align:center;">`に類似 )
- ⑤フォントサイズの指定

# コツ
## ◉ できるだけ TeX言語(マクロ)は使わずに、可能な限り置換する
例えば、金額を表示するのに三桁区切りのカンマ付きで表示したい場合、数値をカンマ付きに変換するのは、$\LaTeX$ のマクロでやらずに、他のプログラム( Python とか Ruby とか)でやる。他にも、日時のフォーマット（西暦和暦変換とか）など。
つまり、ベースとなる文書を tex ファイルで作成しておき、変動する部分（差し込み印刷のようなもの）は、もっと使いやすい言語で書き換えてゆく方が、労力のコスパがよい。

rubyを使った例

```tex:template.tex
\RequirePackage{plautopatch}
\documentclass{jlreq}
\usepackage[uplatex,deluxe,expert,jis2004]{otf}
\begin{document}
\begin{center}
請求額合計（税込） ￥% ③
%_price_%% ① プレースホルダーと呼ぶことにする
円
\end{center}
\end{document}
```
$\LaTeX$ ($\TeX$) のソースでは`%`がコメントアウトの記号になっている。

```ruby:writer.rb
require 'action_view'
include ActionView::Helpers::NumberHelper

template = File.read('template.tex')
key = "price" # ②キーと呼ぶことにする
val = 123456
template.gsub!("%_#{key}_%"){number_with_delimiter(val)}
File.write("/tmp/sample.tex", template)
%x[latexmk /tmp/sample]
```

 - キー②を`%_` `_%`で囲ってプレースホルダー①にすることで、プレースホルダーが万が一置換されなくてもただのコメントとして残るからコンパイルエラーにはならない(左側で十分だが、見栄えのために右側も。アンダースコアは見やすいようにしただけで必須ではなく、コメントアウトと区別しやすくしているだけ)
 - ソースの改行はスペースに変換されてしまうので、①③のようにそれを阻止したい場所では行末に`%`をつけておく
 - プレースホルダーのある行は（行頭に）そのプレースホルダーだけにしておくことで（①)、メンテナンス（プレースホルダー一覧を取得）しやすくする（`grep -o -e '^%_.*_%' template.tex`など）

## ◉ フォントのバリエーションは諦める[^6]
[^6]:あるいは処理速度と引き換えに（2〜3倍遅いらしい）LuaLaTeX（LuaTeX）をエンジンにするか

フォントの仕組み・構造を知らないと扱いこなせなず（私もなんとなくしかわからない）、帳票作成が目的であれば読めればよいので、フォントの美麗には目をつぶる。
なので選択肢は、IPAフォントかNoto（源ノ〇〇）フォント[^7]の明朝体かゴシック体に限られる[^8]。
[^7]: 実際には原の味フォント
[^8]: とはいえ、より多くの人に読みやすいPDFを苦労せず作りたいので、UDフォント[^9]が簡単に（パッケージ化されてインストールするだけで）使えるようになるといいなとは思ってる。
[^9]: ユニバーサル・デザインフォント、文字どおりフォントの視認性に垣根をなくす目的に設計されているもの

我慢するとはいえ、以下の例のように、日本語文章(和文フォント)中に半角の(英)数字（欧文フォント）が組まれると（和欧混植）、[グリフ](https://www.morisawa.co.jp/culture/dictionary/1913)のバランス（見た目）は悪いと感じてます。（主観）

![ipaex_o.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/69840/3496c54e-f65e-3af1-8cc1-0a3c4b5579db.png)

IPAフォントやNotoフォントに限らず、当然といえば当然ですがやはり和文フォントに合わせてデザインされた欧文（従属欧文[^10]）フォントの方が統一感があると感じます。`\usepackage[ipaex,alphabet]{pxchfon}`を使うと下のようになりますが……
[^10]: 日本語フォントに付属する英数字をさす組版の用語（term）。日本語の文章に欧文が何文字か混ざる際に違和感が少ないようにデザインされたもの。日本語中に混ざる欧文の量により綺麗に見えたり、見えなかったり……

![ipaex_a+.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/69840/a27218bf-1cec-6449-5d5d-4997ad5bf734.png)

実は上の例は、従属欧文と和文の間にスペースを入れて見た目を調整してます。何もしないと、下のように文字が重なる場合がでてきます。

![ipaex_a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/69840/7550dd66-344f-2b4c-5e11-824f6fa5728d.png)

下は、Google Chromeで表示した場合（欧文フォントが違う理由を知りません）
![ipaex_c.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/69840/b3cc2e93-4e78-8687-7546-529ec6d69000.png)



## ◉ WYSIWIG で編集ができない
Markdown 記法でドキュメントを作成するのと同様です。いちいちタイプセット（コンパイル）して確かめるしかありません。ただし、VSCode にはリアルタイムでコンパイルする[プラグイン](https://marketplace.visualstudio.com/items?itemName=James-Yu.latex-workshop)があるらしい。あとは開発マシンが速ければ、タイプセットの時間も短縮できます。

## ◉ ファイルサイズが超巨大
初めは、TeX Live という $\TeX$ のディストリビューションをインストールして使い始めることになると思いますが、フルセットで5GB(！)くらいあります。もちろんサブセットにする、使わないものをインストールしない、などダイエットすることはできます。（が、実働を優先して時間やリソースが足りなければダイエットは後回し。）しかも、パッケージ管理ツールはありません。

## ◉ これを知っていると便利なパッケージ
- [geometry](https://ctan.org/pkg/geometry)（ jlreq は別で geometry を使わない）
余白の設定を直截にできる(CSS の margin のように）なります。デフォルトの余白もかなり癖があるので……

- [pxchfon](https://ctan.org/pkg/pxchfon)
フォント設定を簡単にできるようになります。デフォルトのフォント設定は……

- [tabularx](https://www.ctan.org/pkg/tabularx) と [xltabular](https://ctan.org/pkg/xltabular)（日本人は罫線付きの表が大好きなので）
LaTeX の表組みは tabular 環境[^11]で作るのが原則です。が、tabularx を使うと表全体の幅とセルの幅をいい感じに調整できるようになります。セルの中での改行もしやすくなります。xltabular は複数ページにわたる表組みができる tabularx という立ち位置です。
他に [tabularray](https://ctan.org/pkg/tabularray)というのもあります。かなり柔軟な表を作成できるようになります。究極の tabular 環境と言っていいかもしれません。ただし、最大のウィークポイントはタイプセットが尋常でないほど遅い。tabularx より複雑な表組み、凝った表組みを作りやすい反面、そんな表組みを作るほど遅くなるという副作用が……
[^11]:「環境」というのはLaTeXで使われる用語（term）です。さまざまな役割がある文書のブロックのようなもので、HTML だと \<table> \<ul> などと類似しています。

- [ifthen](https://ctan.org/pkg/ifthen)、[etoolbox](https://ctan.org/pkg/etoolbox)
条件分岐や繰り返しをより簡単に使えるようになります。マクロは可能な限り使わない方針ですが、それでも必要な場合があったり、$\TeX$ ソースを簡潔に作りたい場合がでてきます。
```tex:sample.tex
\RequirePackage{plautopatch}
\documentclass{jlreq}
\usepackage{etool}
\begin{document}
\ifblank{%
%_date_%%
}{令和　　年　　月　　日}{%
%_date_%%
}
\end{document}
```
特定の日付が置換されなかったときは、日付欄を出力する例（プログラム側で場合分けをした方が良さそうなので、あまりよい例ではないです）

- [xstring](https://ctan.org/pkg/xstring)
文字列の操作がある程度できるようになります。そもそも LaTeX では Python などの言語でできるような文字列の操作（先頭からn文字を抜き出すとか、文字数を数えるとか）が**簡単には**できません。
例えば、金額が負の数なら赤字、それ以外なら黒字にしたい場合はこのように使えます。(プログラム側でキーの値を`\textcolor{red}{-999}`にして置換するのもありです。)
```tex:sample.tex
\RequirePackage{plautopatch}
\documentclass{jlreq}
\usepackage{xcolor}
\usepackage{xstring}
\newcommand{\amount}[1]{\IfBeginWith{#1}{-}{\textcolor{red}}{}{#1}} %①
%\IfBeginWith{#1}{-}{\textcolor{red}}{\textcolor{black}}{#1}
\begin{document}
\amount{%
%_price_%%
}
\end{document}
```
①引数 \#1 が - から始まっているときははじめのカッコをつかい、そうでないときは次のカッコをつかうというマクロ（コマンド）

- [pos-at](https://ctan.org/pkg/pos-at)
ページ上の絶対位置に文字を配置できるパッケージです。TeX のタイプセットは、ラインプリンタのようにページの左上から順番に文字を置いていくようなものです。しかし、あらかじめ様式・フォーマットが印刷してある用紙に、文字を上書きしたい場合など、位置決めを座標でやりたい場合に使えます。
例えば、官製葉書の郵便番号欄の位置に数字を出力するなど

# 結語

こうしてざっくりみると、処理環境のスペック（CPUの速度など）が強力であれば　$\LaTeX$（$\TeX$）の弱点など恐るるに足りない、と。
あとは、かなりクセの強い $\TeX$ 言語（マクロ）をどの程度まで利用するか、くらいのようです。
なので、やはり**帳票作成なら $\LaTeX$($\TeX$) 一択**といえるでしょう。