RubyスクリプトのExe化

Postgresのデータを印刷必要があったので調べて見た。

要件としては

  • 取り込むレコードは決まっているので選択の必要なし
  • 使用環境を選びたくない(使用するパソコンの環境はWindows98〜XPまで様々)
  • 不要なソフト(cygwinやランタイムの類)はインストールしたくない
  • 印刷する際に書式設定等は行ないたくないが、データの操作はしたい

という内容。


データの取得についてはrubyでpostgresに接続した経験がないので、いつも使っているサーバーサイドのphpでtab区切りのcsv形式に加工。クライアント側ではhttp経由でcvsを取り込み、Win32OLEを使用してExcelファイルを作成(印刷時の書式設定も付加)する。その後にExerbを使用してExeファイルに変換。見事にExeになり、希望通りの物ができた。

しかし、いろいろなパソコンで実行してみたら固まったり、エラーを出したり*1で使い物にならない。その後に他の変換するソフトを探して見たらRubyScript2Exeを発見。早速変換してみたところ、問題なく実行できる。追加のdllも必要ないし、アイコンの変更(Resource Hackerがインストールされている必要有り)もできるし申し分無し。

メモ程度に変換方法を記録しておく。参考になれば。なお、アイコンの変更は、対象のファイル名の.icoファイルを用意する必要有り。

C:\> wget http://www.erikveen.dds.nl/rubyscript2exe/download/rubyscript2exe.rb
C:\> cat rb2exe.rb
#!ruby -Ks

#http://lightson.dip.jp/blog/seko/342
require 'win32ole'
require 'net/http'

xlapp = WIN32OLE.new('Excel.Application')
xlapp.visible = true
xlapp.Workbooks.add()
sheet = xlapp.Sheets(1)

s = 'response'
Net::HTTP.version_1_2 # おまじない
Net::HTTP.start('www.example.com', 80) {|http|
response = http.get('/foo/bar/index.php')
s = response.body
}
sheet.Application.ScreenUpdating = 0

i = 1
s.each_line do |line|
array = line.strip.split(/\t/)
sheet.Range("A" + i.to_s + ":I" + i.to_s).value = array
i += 1
end

sheet.Columns("A:A").ColumnWidth = 3.5 * 3
sheet.Columns("B:B").ColumnWidth = 1.39 * 3
sheet.Columns("C:C").ColumnWidth = 6 * 3
sheet.Columns("D:D").ColumnWidth = 3.3 * 3
sheet.Columns("E:E").ColumnWidth = 3.5 * 3
sheet.Columns("F:F").ColumnWidth = 10.6 * 3
sheet.Columns("G:G").ColumnWidth = 2.3 * 3
sheet.Columns("H:H").ColumnWidth = 2.87 * 3
sheet.Columns("I:I").ColumnWidth = 6.7 * 3
sheet.Columns("J:J").ColumnWidth = 2.3 * 3
sheet.Columns("K:K").ColumnWidth = 2.3 * 3

sheet.Range("A1:K" << i.to_s).Select
sheet.Application.Selection.RowHeight = 17.25
sheet.Application.Selection.Borders(5).LineStyle = -4142
sheet.Application.Selection.Borders(6).LineStyle = -4142
sheet.Application.Selection.Borders(7).LineStyle = 1
sheet.Application.Selection.Borders(7).Weight = 2
sheet.Application.Selection.Borders(7).ColorIndex = -4105
sheet.Application.Selection.Borders(8).LineStyle = 1
sheet.Application.Selection.Borders(8).Weight = 2
sheet.Application.Selection.Borders(8).ColorIndex = -4105
sheet.Application.Selection.Borders(9).LineStyle = 1
sheet.Application.Selection.Borders(9).Weight = 2
sheet.Application.Selection.Borders(9).ColorIndex = -4105
sheet.Application.Selection.Borders(10).LineStyle = 1
sheet.Application.Selection.Borders(10).Weight = 2
sheet.Application.Selection.Borders(10).ColorIndex = -4105
sheet.Application.Selection.Borders(11).LineStyle = 1
sheet.Application.Selection.Borders(11).Weight = 1
sheet.Application.Selection.Borders(11).ColorIndex = -4105
sheet.Application.Selection.Borders(12).LineStyle = 1
sheet.Application.Selection.Borders(12).Weight = 1
sheet.Application.Selection.Borders(12).ColorIndex = -4105
sheet.Application.ActiveSheet.PageSetup.PrintTitleRows = ""
sheet.Application.ActiveSheet.PageSetup.PrintTitleColumns = ""
sheet.Application.ActiveSheet.PageSetup.PrintArea = ""
sheet.Application.ActiveSheet.PageSetup.LeftHeader = ""
sheet.Application.ActiveSheet.PageSetup.CenterHeader = ""
sheet.Application.ActiveSheet.PageSetup.RightHeader = ""
sheet.Application.ActiveSheet.PageSetup.LeftFooter = ""
sheet.Application.ActiveSheet.PageSetup.CenterFooter = ""
sheet.Application.ActiveSheet.PageSetup.RightFooter = ""
sheet.Application.ActiveSheet.PageSetup.PrintHeadings = 0
sheet.Application.ActiveSheet.PageSetup.PrintGridlines = 0
sheet.Application.ActiveSheet.PageSetup.PrintComments = -4142
sheet.Application.ActiveSheet.PageSetup.CenterHorizontally = 0
sheet.Application.ActiveSheet.PageSetup.CenterVertically = 0
sheet.Application.ActiveSheet.PageSetup.Orientation = 2
sheet.Application.ActiveSheet.PageSetup.Draft = 0
sheet.Application.ActiveSheet.PageSetup.PaperSize = 9
sheet.Application.ActiveSheet.PageSetup.FirstPageNumber = -4105
sheet.Application.ActiveSheet.PageSetup.Order = 1
sheet.Application.ActiveSheet.PageSetup.BlackAndWhite = 0
sheet.Application.ActiveSheet.PageSetup.Zoom = 100
sheet.Application.ActiveSheet.PageSetup.LeftMargin = sheet.Application.InchesToPoints(0.41)
sheet.Application.ActiveSheet.PageSetup.RightMargin = sheet.Application.InchesToPoints(0.3)
sheet.Application.ActiveSheet.PageSetup.TopMargin = sheet.Application.InchesToPoints(0.59)
sheet.Application.ActiveSheet.PageSetup.BottomMargin = sheet.Application.InchesToPoints(0.32)
sheet.Application.ActiveSheet.PageSetup.FooterMargin = sheet.Application.InchesToPoints(0.2)
sheet.Application.ActiveSheet.PageSetup.FitToPagesWide = 1
sheet.Application.ActiveSheet.PageSetup.FitToPagesTall = 1
sheet.Range("A1").Select
sheet.Application.ScreenUpdating = 1

C:\> ruby rubyscript2exe.rb rb2exe.rb

Exerbより簡単。

*1:msvcr71が必要とかその他もろもろ