PDF帳票の生成 - FastPDFGen

きれいにデザインされたPDFの帳票を出力する必要があった。帳票生成ツールはどれも高い。そこでお勧めされたのが FastPDFGen。テンプレートとして用意した PDF のフォームに文字を流し込むことで、自由なデザインの PDF を作ることができる。

1. 準備

まず、PDF の帳票を作る。Word でも PowerPoint でも PDF を作ることができさえすれば何でも良いが、今回はデザイナーさんにきれいなものを作ってもらったので Illustrator。

2. PDF に変換する

Illustrator なら、PDFに「書き出し」する。その際、最小サイズになるように。

3. Acrobat でフォームのフィールドを配置していく

項目が多いと手間がかかるが、地道に。画面上の表示と実際のフォームの位置がずれることがあるのは、Acrobat のバグなのか、FastPDFGen が情報をきちんと読み取れていないからなのか。結果を見て修正できるから致命傷ではない。フィールドのプロパティの設定に、FastPDFGen によって課される様々な制約がある。ユーザマニュアルをきちんと読んで確実に設定しておく。

4. Acrobat で最適化して保存する。

最終的に生成される PDF ファイルのサイズを小さくするため。

5. テンプレート化

FastPDFGen 付属の mkPDFTpl コマンドで、フォームを配置した PDFファイルをテンプレート化する。一ページ一ファイル。

6. アプリで動的にPDFを生成

アプリから FastPDFGen コマンドを実行してやると、テンプレート群から PDFファイルが生成される。フォームに流し込むテキスト、貼り付ける画像は、帳票生成コマンドを記述したテキストファイルを読み込ませることによって行う。つまり、この帳票生成コマンドファイルを動的に生成すれば、内容が動的に変わるPDFファイルを作ることができる。

FastPDFGenの良いところ

  • 安い。本番環境で使うランタイムライセンス1つと開発環境で使う開発ライセンス1つがセットで85,000円弱
  • 速い。名前に違わず、生成速度が速い。3ページの帳票を生成しているが、FastPDFGenの実行そのものは一瞬で終わる。
  • どんなデザインでも実現できる。元ファイルは Illustrator で凝っても良いし、Word でも良い。
  • 購入する前に、機能制限なしの FastPDFGen を一ヶ月利用することができる。シリアルも Web上に公開されているので、問い合わせなどの手間もなし。

FastPDFGenの良くないところ

  • テキストはフォームフィールドへの流し込みなので、同じフィールド内で文字の一部の大きさを変えたり、色を変えたりという細かい修飾ができない。PDFlib はできるようだが、50万円も払えないので我慢我慢。
  • 貼り付けられる画像が JPEG 限定。他にマニュアルには rgb 形式というなぞのフォーマットも記載されている。bitmap のこと?
  • デザインを変えるのに手間がかかる。デザインを変えると、PDF生成、フォームフィールドの配置、テンプレートの生成、をやり直さなくてはならない。面倒。
  • 呼び出し形式が API、ライブラリではなく、コマンド実行。別に嫌いじゃなくて、むしろ好きですが、ライブラリ形式もあっても良いのではないか。
  • マイナーなので、Web上に情報がほとんどない。といっても、ユーザマニュアルだけで充分開発できたので不満はない。シンプルなので、トラブルにも会いにくい。
  • Acrobat でフォームを変更するたびに、「名前をつけて保存」しなくてはならない。いろいろと事情があるのだろう。その流儀?を理解してからは面倒だというだけで、特別困りはしなかった。

シンプルで手軽なので、別の帳票を出力する用事が出来たら、また、使うと思う。お金があれば、PDFlib も使ってみたいけど、今の職場では機会(お金)なさそう。

mongrel + MySQL で rails を安定動作させる

先週半ばに、いろんなところが不十分ながらも時間に追われるように本番運用に投入した rails アプリ。僕にとっては、お遊びじゃない初めての rails アプリ。企画段階でしばらくペンディングしていたものが正式に中止となった後で、契約が取れたおかげで(せいで?)急にやることに決まって、実質開発期間が一か月無かった。仕様とデザインがほぼ完璧に固まっていたのが唯一の救い。土日もGWもコーディングしていた。



<p>ようやく最低限の実装が終わってサービスを提供できるようになったものの、mongrel が数十分~数時間で落ちてしまう。仕方がないので Apache mod_balance + mongrel 3プロセス + monitで30秒毎に監視、という環境にしてみた。落ちてもカバーできるようにしたつもりなのに、平均して30分に一回程度、止まる。しかも3プロセス全部、一度に。monit が復旧してくれるから、致命傷にはならないものの、このままでいいはずがない。</p>

<p>MySQL のライブラリを ruby ベースのものから Cベースのものに入れ替えたら、落ちなくなった。
<blockquote>
WARNING: You’re using the Ruby-based MySQL library that ships with Rails.
This library is not suited for production. Please install the C-based MySQL
library instead (gem install mysql).
</blockquote>
とログに出ていたのは認識していたのだけど、こんなに効果があるとは。動作も少し速くなったし、いいことずくめ。</p>

<p>これで安心して残りの機能の実装に進める。</p>

Xen の domainU のディスクを動的に増設する

<img src=”http://ecx.images-amazon.com/images/I/51g98uPCpzL.jpg” height=”120px”/ style=”float: left;”><img src=”http://ec2.images-amazon.com/images/I/51IYk4lZJUL.jpg” height=”120px”/ style=”float: left;”><img src=”http://ec2.images-amazon.com/images/I/51uK4ACymiL.jpg” height=”120px”/ style=”float: left;”><img src=”http://ecx.images-amazon.com/images/I/51ejAPsISuL.jpg” height=”120px”/ style=”float: left;”><img src=”http://ec2.images-amazon.com/images/I/51hIDIWHmYL.jpg” height=”120px”/ style=”float: left;”>




1. ディスクイメージを2つ作成する。1つでも良いが、せっかくなので2個。 <pre class='prettyprint'>[root@st1 xen]# dd if=/dev/zero of=centos5_demo_1 bs=1M count=4096
4096+0 records in
4096+0 records out
4294967296 bytes (4.3 GB) copied, 57.3006 seconds, 75.0 MB/s
[root@st1 xen]# dd if=/dev/zero of=centos5_demo_2 bs=1M count=4096
4096+0 records in
4096+0 records out
4294967296 bytes (4.3 GB) copied, 65.3232 seconds, 65.7 MB/s
</pre>2. domainU に attach する。domainU は動かしたままで良い。 <pre class='prettyprint'>[root@st1 xen]# xm block-attach demo file://var/xen/centos5_demo_1 /dev/xvd
a3 w
[root@st1 xen]# xm block-attach demo file://var/xen/centos5_demo_2 /dev/xvda4 w
</pre>3. domainU でディスクが増えていることを確認する。 <pre class='prettyprint'>[root@demo ~]# ls -l /dev/xvda*
brw-r—– 1 root disk 202, 0 Apr 18 22:33 /dev/xvda
brw-r—– 1 root disk 202, 1 Apr 18 22:33 /dev/xvda1
brw-r—– 1 root disk 202, 2 Apr 18 22:33 /dev/xvda2
brw-r—– 1 root disk 202, 3 Apr 18 22:51 /dev/xvda3
brw-r—– 1 root disk 202, 4 Apr 18 22:52 /dev/xvda4
</pre>4. domainU で pvcreate する。 <pre class='prettyprint'>[root@demo ~]# pvcreate /dev/xvda3
Physical volume “/dev/xvda3” successfully created
[root@demo ~]# pvcreate /dev/xvda4
Physical volume “/dev/xvda4” successfully created
[root@demo ~]# pvscan
PV /dev/xvda2 VG VolGroup00 lvm2 [7.88 GB / 0 free]
PV /dev/xvda3 lvm2 [4.00 GB]
PV /dev/xvda4 lvm2 [4.00 GB]
Total: 3 [15.88 GB] / in use: 1 [7.88 GB] / in no VG: 2 [8.00 GB]
</pre>5. 増設したディスクをボリュームグループに加える。 <pre class='prettyprint'>[root@demo ~]# pvs
PV VG Fmt Attr PSize PFree
/dev/xvda2 VolGroup00 lvm2 a- 7.88G 0
/dev/xvda3 lvm2 – 4.00G 4.00G
/dev/xvda4 lvm2 – 4.00G 4.00G
[root@demo ~]# vgextend VolGroup00 /dev/xvda3
Volume group “VolGroup00” successfully extended
[root@demo ~]# vgextend VolGroup00 /dev/xvda4
Volume group “VolGroup00” successfully extended
[root@demo ~]# pvs
PV VG Fmt Attr PSize PFree
/dev/xvda2 VolGroup00 lvm2 a- 7.88G 0
/dev/xvda3 VolGroup00 lvm2 a- 3.97G 3.97G
/dev/xvda4 VolGroup00 lvm2 a- 3.97G 3.97G
[root@demo ~]# vgdisplay
— Volume group —
VG Name VolGroup00
System ID
Format lvm2
Metadata Areas 3
Metadata Sequence No 5
VG Access read/write
VG Status resizable
MAX LV 0
Cur LV 2
Open LV 2
Max PV 0
Cur PV 3
Act PV 3
VG Size 15.81 GB
PE Size 32.00 MB
Total PE 506
Alloc PE / Size 252 / 7.88 GB
Free PE / Size 254 / 7.94 GB
VG UUID URWdcO-ihHU-nmvP-831K-u8cn-l844-PuQXNP
</pre>Free PE が 254 あることに注意。 6. ロジカルボリュームを拡張する。 <pre class='prettyprint'>[root@demo ~]# lvdisplay /dev/VolGroup00/LogVol00
— Logical volume —
LV Name /dev/VolGroup00/LogVol00
VG Name VolGroup00
LV UUID OYck42-akcB-g0yf-I4Pj-qKCK-a6N7-s61qwS
LV Write Access read/write
LV Status available
# open 1
LV Size 6.84 GB
Current LE 219
Segments 1
Allocation inherit
Read ahead sectors 0
Block device 253:0

[root@demo ~]# lvextend –extents=+254 /dev/VolGroup00/LogVol00
Extending logical volume LogVol00 to 14.78 GB
Logical volume LogVol00 successfully resized
[root@demo ~]# lvdisplay /dev/VolGroup00/LogVol00
— Logical volume —
LV Name /dev/VolGroup00/LogVol00
VG Name VolGroup00
LV UUID OYck42-akcB-g0yf-I4Pj-qKCK-a6N7-s61qwS
LV Write Access read/write
LV Status available
# open 1
LV Size 14.78 GB
Current LE 473
Segments 3
Allocation inherit
Read ahead sectors 0
Block device 253:0
</pre>7. ext3 ファイルシステムをオンラインで拡張する。 <pre class='prettyprint'>[root@demo ~]# df
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/mapper/VolGroup00-LogVol00
6951280 4570780 2021692 70% /
/dev/xvda1 101086 29517 66350 31% /boot
tmpfs 131156 0 131156 0% /dev/shm
[root@demo ~]# resize2fs /dev/VolGroup00/LogVol00
resize2fs 1.39 (29-May-2006)
Filesystem at /dev/VolGroup00/LogVol00 is mounted on /; on-line resizing required
Performing an on-line resize of /dev/VolGroup00/LogVol00 to 3874816 (4k) blocks.
The filesystem on /dev/VolGroup00/LogVol00 is now 3874816 blocks long.

[root@demo ~]# df
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/mapper/VolGroup00-LogVol00
15012712 4572528 9666964 33% /
/dev/xvda1 101086 29517 66350 31% /boot
tmpfs 131156 0 131156 0% /dev/shm
</pre>めでたく増えた。 ディスクを増やしたという事実はどこかに記録されていて、domU をリブートしても、増えた容量のままマウントされていた。domU の設定ファイルの disk= 行にディスクを追加しても、怒られる。 <pre class='prettyprint'>[root@st1 xen]# xm create centos5_demo
Using config file “./centos5_demo”.
Error: Device 51715 (vbd) could not be connected.
File /var/xen/centos5_demo_1 is loopback-mounted through /dev/loop0,
which is mounted in a guest domain,
and so cannot be mounted now.
</pre>

rails + MySQL on Win で "No such file or directory - /tmp/mysql.sock"

前に win で rails したときにも引っかかったのだが、また同じところで引っかかったのでメモ。

Windows で rails + MySQL なときに
<pre class="prettyprint">Errno::ENOENT in Rails/infoController#properties
No such file or directory - /tmp/mysql.sock
</pre>
と言われたら、それは database.xml で host に localhost を指定しているから。127.0.0.1 ならつながる。
<pre class="prettyprint">development:
adapter: mysql
database: inquiry
username: test
password:
host: 127.0.0.1
</pre>

MySQL の NO_AUTO_CREATE_USER

Windows版の MySQL で、GRANT で新ユーザを作成しようとしたら、
<pre class="prettyprint">mysql> grant all on inquiry.* to ‘ODBC’@’localhost’;
ERROR 1133 (42000): Can’t find any matching row in the user table
</pre>
と言われた。

Windows版では、my.ini の sql_mode に NO_AUTO_CREATE_USER が指定されていて、パスワード無しのユーザを作成できない。そんな時は、NO_AUTO_CREATE_USER をはずすか、パスワード付きでユーザを作ればいい。

<dl>
<dt>NO_AUTO_CREATE_USER をはずす</dt>
<dd>
<pre class="prettyprint">mysql> set sql_mode=””;
Query OK, 0 rows affected (0.00 sec)

mysql> grant all on inquiry.* to ‘ODBC’@’localhost’;
Query OK, 0 rows affected (0.00 sec)
</pre>
</dd>

<dt>パスワード付きでユーザを作成する</dt>
<dd>
<pre class="prettyprint">mysql> grant all on inquiry.* to ‘test2’@’localhost’;
ERROR 1133 (42000): Can’t find any matching row in the user table
mysql> grant all on inquiry.* to ‘test2’@’localhost’ identified by ‘test2’;
Query OK, 0 rows affected (0.00 sec)
</pre>
</dd>
</dl>