Ruby から Apache FOP の機能を呼び出して PDF ファイルを生成してみる
Apache FOP を用いて,Ruby で PDF ファイルを生成してみる.そのために,次のことを行う.Windows での手順であるが、Linux 等でも類似の手順になると思います.
- Apache FOP のインストール
- フォントファイルからフォントメトリクスファイル(XML 形式)の生成
Apache FOP のインストール (Windows の場合)
Windows を使用する場合は,次のように操作する.
- Apache FOP の Web ページを開く http://xmlgraphics.apache.org/fop/
- 「Download」をクリック
- 「Binary Download」をクリック
- 「FOP Distribution mirror」をクリック
- ミラーサイトの選択
- 「binaries」をクリック
- ファイルの選択
- ダウンロードしたファイルの解凍
展開(解凍)すると次のようなファイルができる
- 解凍して出来たファイルは丸ごと分かりやすいディレクトリにコピー
C:\Program Files\fop にコピーしたものとして、以下の説明を続ける
- 環境変数 PATH と CLASSPATH の設定
- PATH: C:\Program Files\fopを追加
- CLASSPATH: C:\Program Files\fop\build\fop.jarを追加
フォントファイルからフォントメトリクスファイル(XML 形式)の生成
Apache FOP の動作のために,フォントファイルと,フォントメトリクスファイルが必要.フォントファイルは Windows の場合は,Windows に付属の ttc ファイル,Linux などの場合にはフリーのフォントを使うことにする.
フォントメトリクスファイルについては、次の手順を踏むことにします.
- 1つのフォントファイルに,複数のフォントが入っていることがあるので,まずは,フォントファイルからフォント名(複数ありえる)を取得する
Apache FOP を使って行うことができる.
- 次に,フォントファイルとフォント名を使って,フォント名1つに対応して,フォントメトリクスファイルを1つずつ生成する
これも、Apache FOP を使って行うことができる.引数に「-ttcname」オプションを含める.
その作業手順を解説した優れた Web ページが簡単に見つかります. その成果を有難く使うことにして, ここでは、Ruby のプログラムを使って、上記の作業を楽に行いたいと考えました.
* 使い方
- fop.bat のありかを、FOP_BAT に設定
- FONT_FILES のフルパスでのファイル名を FONT_FILES に設定
- 実行
- fop.bat と同じディレクトリに XML 形式のフォントメトリクスファイルができる
#! ruby -Ks # coding: windows-31j require 'pp' require 'jcode' require 'tmpdir' require 'fileutils' # fop.bat の在りかを設定して、使ってください. FOP_BAT="C:/Program Files/fop/fop.bat" # フォントファイル FONT_FILES = ["C:/WINDOWS/Fonts/MSMINCHO.TTC", "C:/WINDOWS/Fonts/MSGOTHIC.TTC"] def fop_jar_files(fop_bat) # fop.jar とそれに関係する jar ファイルのファイル名を、文字列の配列の形で得る jar_files = Dir.glob( File.dirname( fop_bat ) + "/*.jar" ) + Dir.glob( File.dirname( fop_bat ) + "/build/*.jar" ) + Dir.glob( File.dirname( fop_bat ) + "/lib/*.jar" ) return jar_files end def get_font_list_using_TTFReader(ttc_file_name) # xml ファイル名は適当に設定(できた XML ファイルは使わないので) xml_file_name = File.basename(ttc_file_name, ".ttc") + ".xml" # TTFReader の結果は、一時的なディレクトリに格納したい tmpdir = Dir.mktmpdir("TTFReader") stdout_file_name = tmpdir + "/ttcopen.log" stderr_file_name = tmpdir + "/ttcopen.error" # jar ファイルを取得の後 java コマンドを使って TTFReader を起動。標準出力に出てきた結果をあとで使いたい jar_files = fop_jar_files(FOP_BAT) system("java -classpath #{jar_files.map{|e| "\"" + e + "\""}.join(';')} org.apache.fop.fonts.apps.TTFReader #{ttc_file_name} #{xml_file_name} > #{stdout_file_name} 2> #{stderr_file_name}") # 標準出力に出てきた結果は、いま、ファイルに入っている。そこからフォント名のリストを取得する。 File.open(stdout_file_name) do |f| message = f.read message.gsub(/\n/,",").gsub(/\s/," ").scan(/Containing the following fonts: ,(.+)/) end return $1.split(",") end def gen_xml_file_using_TTFReader(ttc_name, ttc_file_name, xml_file_name) # TTFReader を呼び出して、フォントメトリクス(XML 形式)を生成させる # TTFReader の結果は、一時的なディレクトリに格納したい tmpdir = Dir.mktmpdir("TTFReader") stdout_file_name = tmpdir + "/ttcopen.log" stderr_file_name = tmpdir + "/ttcopen.error" # jar ファイルを取得の後 java コマンドを使って TTFReader を起動。 jar_files = fop_jar_files(FOP_BAT) system("java -classpath #{jar_files.map{|e| "\"" + e + "\""}.join(';')} org.apache.fop.fonts.apps.TTFReader -ttcname #{"\"" + ttc_name + "\""} #{ttc_file_name} #{"\"" + xml_file_name + "\""} > #{stdout_file_name} 2> #{stderr_file_name}") end # まずは、必要な jar ファイルのファイル名の取得 jar_files = fop_jar_files(FOP_BAT) # フォントメトリクスファイルの生成 FONT_FILES.each do |e| print "TTC FONT FILE: ", e, "\n" font_list = get_font_list_using_TTFReader(e) font_list.each do |f| print " TTC FONT NAME: ", f, "\n" xml_file_name = File.dirname( FOP_BAT ) + "/" + f.gsub(/\s/,"") + ".xml" print " XML FILE NAME: ", xml_file_name, "\n" gen_xml_file_using_TTFReader(f, e, xml_file_name) end end # fop/userconfig.xml の <FONT> 部分を生成 print"<configuration>\n" print"<fonts>\n" FONT_FILES.each do |e| font_list = get_font_list_using_TTFReader(e) font_list.each do |f| xml_file_name = File.dirname( FOP_BAT ) + "/" + f.gsub(/\s/,"") + ".xml" print "<font metrics-file=\"#{xml_file_name.gsub(/\//,'\\')}\" kerning=\"yes\" embed-file=\"#{e.gsub(/\//,'\\')}\">\n" # print" <font-triplet name=\"#{f}\" style=\"normal\" weight=\"normal\"/>\n" print" <font-triplet name=\"#{f}\" style=\"normal\" weight=\"bold\"/>\n" print" <font-triplet name=\"#{f}\" style=\"italic\" weight=\"normal\"/>\n" print" <font-triplet name=\"#{f}\" style=\"italic\" weight=\"bold\"/>\n" # 空白文字を消す print" <font-triplet name=\"#{f.gsub(/\s/,"")}\" style=\"normal\" weight=\"normal\"/>\n" print" <font-triplet name=\"#{f.gsub(/\s/,"")}\" style=\"normal\" weight=\"bold\"/>\n" print" <font-triplet name=\"#{f.gsub(/\s/,"")}\" style=\"italic\" weight=\"normal\"/>\n" print" <font-triplet name=\"#{f.gsub(/\s/,"")}\" style=\"italic\" weight=\"bold\"/>\n" # 空白文字を「-」に置き換える print" <font-triplet name=\"#{f.gsub(/\s/,"-")}\" style=\"normal\" weight=\"normal\"/>\n" print" <font-triplet name=\"#{f.gsub(/\s/,"-")}\" style=\"normal\" weight=\"bold\"/>\n" print" <font-triplet name=\"#{f.gsub(/\s/,"-")}\" style=\"italic\" weight=\"normal\"/>\n" print" <font-triplet name=\"#{f.gsub(/\s/,"-")}\" style=\"italic\" weight=\"bold\"/>\n" # 半角を全角に置き換える print" <font-triplet name=\"#{f.gsub(/\s/,"").gsub("Mincho","明朝").gsub("Gothic","ゴシック").tr("a-zA-Z","a-zA-Z")}\" style=\"normal\" weight=\"normal\"/>\n" print" <font-triplet name=\"#{f.gsub(/\s/,"").gsub("Mincho","明朝").gsub("Gothic","ゴシック").tr("a-zA-Z","a-zA-Z")}\" style=\"normal\" weight=\"bold\"/>\n" print" <font-triplet name=\"#{f.gsub(/\s/,"").gsub("Mincho","明朝").gsub("Gothic","ゴシック").tr("a-zA-Z","a-zA-Z")}\" style=\"italic\" weight=\"normal\"/>\n" print" <font-triplet name=\"#{f.gsub(/\s/,"").gsub("Mincho","明朝").gsub("Gothic","ゴシック").tr("a-zA-Z","a-zA-Z")}\" style=\"italic\" weight=\"bold\"/>\n" print "</font>\n" end end print"</fonts>\n" print"</configuration>\n"
* 実行結果の例(Result Example)
Ruby プログラムを実行.結果を適当なファイルに保存しておく.

UTF-8 に変換

<configuration> から </configuration> までを C:\Program files\fop\userconfig.xml に置く

テスト実行
サンプルファイルをコピー

fop を実行

PDF ファイルが出来ていることを確認
