POIを使ったExcel帳票の出力は、システムエンジニアにとっては日常茶飯事、おちゃのこサイサイであります。
Excel方眼紙を支える技術
takezoen先生による2015年版はこちらになります。
[]
(http://www.slideshare.net/takezoe/exceljava2015)
ここで紹介されている、S式からExcel方眼紙を出力するライブラリaxebomber-cljは、こちらをご覧ください。
特筆すべきはaxebomber-cljでは、Excelにありがちな文字切れが起こらないというところです。そもそもExcel方眼紙は、入力文字列が自動改行されない制約を設けて、利用者が意図的な位置で改行をコントロールするために発明されたフォーマットであります。しかし、その特異な見た目が災いし、単に敬遠される存在にとどまっております。axebomber-cljは、文字幅とセル幅を計算し、文字切れしない位置で自動的に改行するようにしています。これにより、Excel方眼紙の文字切れしにくさを活かしつつ、煩わしさを消しているわけです。
(render sheet {:x 2 :y 12 :data-width 6}
"長い文字列は自動的に改行されます。非常に便利ですね!")
文字列が長くても… 以下のとおり、決められたサイズを超えると自動で改行されるわけです。
自動改行のために
等幅フォントならまだ簡単ですが、見栄えのするExcel方眼紙はやはりプロポーショナルを使ったものです。
(defn string-width [s font]
(if (> (.length (str s)) 0)
(let [layout (TextLayout. (.getIterator (make-attributed-string (str s) font))
font-render-context)]
(.. layout getBounds getWidth))
0))
java.awt.TextLayoutを使って、実際のフォントで文字列幅を計算し、セル幅と比較しながら改行を入れていくことで、自動改行が実現できます。
正確な方眼を作る
由緒正しいExcel方眼紙は、セルが正方形であることが条件ですが、セル幅はフォントサイズによって変わってきます。
POIを使ってみる/横幅の設定 http://irof.hateblo.jp/entry/20100316/p1に横幅の難しさは説明されていますが、試行錯誤の結果、以下のようにフォントサイズによって、オフセットを不規則に変化させると正方形のセルが手に入るようになりました。
(def font-offset
{ 8 200,
9 200,
10 200,
11 160,
12 160,
13 200,
14 180,
15 180,
16 160,
17 160,
18 160,
19 180,
20 160,
22 160,
24 140,
26 160,
28 150,
36 140})
(defn to-grid [sheet]
(let [font-size (.. sheet
getWorkbook
(getFontAt (short 0))
getFontHeightInPoints)]
(doseq [col-index (range 256)]
(.setColumnWidth sheet col-index (+ (get font-offset font-size 180) (* 256 2)))))
sheet)
excelebration
excelebrationはaxebomber-cljのコマンドラインラッパーです。
https://github.com/kawasima/excelebration (まだドキュメントがありません )
納品用の表紙を出力したり、テンプレートをもとに方眼紙を出力したりが簡単にできるようになります。
MarkdownからExcel方眼紙へ
Markdownで設計書を書くという野望を、システムエンジニアの半数は持っているけれども、Excel方眼紙帝国の力に屈服し、ひらすらマス目を埋める"設計"作業をしている、と聞きます。
そういうときはexcelebrationを使いましょう。
こういうMarkdownが…
lein run -- -i test.md -o test.xlsx
コマンド一発で、Excel方眼紙に早変わりです。
まとめ
まだまだS式からのExcel方眼紙出力はすでに実用化済みですが、MarkdownからのExcel方眼紙は、まだまだこれからの技術です。当然ながらjagridを使ったHTML方眼紙への出力も視野に入れております。
Excel方眼紙を支える技術が、2016年どういう進歩を遂げるのか楽しみですね!