pure ruby の各種フォーマット対応Spreadsheetパーサ(xlsx対応!)
2009-08-12


roo - rubyforge プロジェクトページ

OOo, Google Document, Excel(2007の新フォーマット対応)と、幅広いフォーマットへの対応を謳う、スプレッドシートのパーサ

ドキュメントの更新が追い付いていないようですが、最新版は1.3.9

(セルに値を設定するメソッドまでは全てのフォーマットに対して実装されているようですが)

xlsxなファイルを扱う必要があって、自前でなんとでもなりそうだったけど、既存のライブラリを見付けたのでメモ。

ちなみにxlsも対応していることになっていますが、Spreadsheetに丸投げなので、 xlsだけの対応で良い場合は、Spreadsheetを直接利用するべきだと思います。

(Spreadsheet方が高機能で、実装の筋も良い)

また、rooではGoogle Spreadsheet以外ではファイルの更新に対応していませんが、Spreadsheet.open(filename) とか無造作にやっているので、 Spreadsheetのデフォルト値'rb+'が採用されてファイルにロックがかかります。

--- /lib/ruby/gems/1.8/gems/roo-1.3.9/lib/roo/excel.rb.old
+++ /lib/ruby/gems/1.8/gems/roo-1.3.9/lib/roo/excel.rb
@@ -126,7 +126,7 @@
       unless File.file?(@filename)
         raise IOError, "file #{@filename} does not exist"
       end
-      @workbook = Spreadsheet.open(filename)
+      @workbook = Spreadsheet.open(filename, 'rb')
       @default_sheet = self.sheets.first
     ensure
       #if ENV["roo_local"] != "thomas-p"

ぐらいしておくと良いかも。

インストール

rubyforgeにgemがあります。

$ sudo gem install roo

ファイルを開く

require 'rubygems'
require 'roo'

spreadsheet = Openoffice.new("myspreadsheet.ods")      # Openoffice Spreadsheet
spreadsheet = Excel.new("myspreadsheet.xls")           # Excel(xls)
spreadsheet = Google.new("myspreadsheetkey_at_google") # Google Spreadsheet
spreadsheet = Excelx.new("myspreadsheet.xlsx")         # Excel(xlsx)

の個別のクラスを直接利用する他

spreadsheet = Roo::Spreadsheet.open("myspreadsheet.xlsx")

でファイルの拡張子から前述のクラスを自動で判別してもらうことができます。

値の参照

Spreadsheetライブラリとは異なり、Worksheet(やrow, cell)を抽象化したクラスはありません。 GenericSpreadsheetクラスを継承した、Openoffice, Google, Excel, Excelxといったクラスに #cell(row, col, sheet=nil)のアクセサがあります。

spreadsheet.cell(2, 1)
spreadsheet.cell(2, 'A')
spreadsheet.cell(2, 'a')
spreadsheet.cell('A', 2)

これらは同じセルの値を参照します。 数値は1 orignです。(表計算ソフトの画面との整合性を優先したのでしょうが、ちょっと好きになれない)

ワークシートの選択は3つめの引数に、シートの名称を与えます。

spreadsheet.cell('A', 2, 'Sheet 1')

省略した場合は #default_sheet に設定されたシート名が使用されます。 シート名の一覧は #sheets で得られます。

spreadsheet.sheets #=> ["Sheet 1", "Sheet 2", "Sheet 3"]
spreadsheet.default_sheet = spreadsheet.sheets.first #=> "Sheet 1"

問題点

いくつか問題点が存在すると思っています。

名前空間の汚染

Openoffice, Google, Excel, Excelxといったクラス名が、グローバルに定義されています。 module Roo 配下になっているのは、前述のRoo::Spreadsheet.openメソッドと Roo::VERSION 定数だけです。

そもそも、OOoのSpreadsheetアプリのデータファイルのパーサ に Openofficeのクラス名を与えるセンスは許せない気がします。

アクセサがださい

ワークブック(ワークシート)に対するアクセサには、セル値を参照する #cell, セルの値の型を参照する #celltype, セルの内容が式である場合にその式を取り出す #formula の他、限定的なサポートのようですが、書式を参照する #font などもありますが、そのいずれも Enumerableではありません。

Enumerableなメソッドが一つもありません


続きを読む

[Ruby]

コメント(全0件)
コメントをする


記事を書く
powered by ASAHIネット