Ruby から Apache FOP の機能を呼び出して PDF ファイルを生成してみる

Apache FOP を用いて,Ruby で PDF ファイルを生成してみる.そのために,次のことを行う.Windows での手順であるが、Linux 等でも類似の手順になると思います.

Apache FOP のインストール (Windows の場合)

Windows を使用する場合は,次のように操作する.

  1. Apache FOP の Web ページを開く http://xmlgraphics.apache.org/fop/
  2. Download」をクリック
  3. Binary Download」をクリック
  4. FOP Distribution mirror」をクリック
  5. ミラーサイトの選択
  6. binaries」をクリック
  7. ファイルの選択
  8. ダウンロードしたファイルの解凍

    展開(解凍)すると次のようなファイルができる

  9. 解凍して出来たファイルは丸ごと分かりやすいディレクトリにコピー

    C:\Program Files\fop にコピーしたものとして、以下の説明を続ける

  10. 環境変数 PATH と CLASSPATH の設定
    • PATH: C:\Program Files\fop追加
    • CLASSPATH: C:\Program Files\fop\build\fop.jar追加

フォントファイルからフォントメトリクスファイル(XML 形式)の生成

Apache FOP の動作のために,フォントファイルと,フォントメトリクスファイルが必要.フォントファイルは Windows の場合は,Windows に付属の ttc ファイル,Linux などの場合にはフリーのフォントを使うことにする.

フォントメトリクスファイルについては、次の手順を踏むことにします.

その作業手順を解説した優れた Web ページが簡単に見つかります. その成果を有難く使うことにして, ここでは、Ruby のプログラムを使って、上記の作業を楽に行いたいと考えました.

* 使い方

#! 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 ファイルが出来ていることを確認