pure Ruby の Excelファイル操作ライブラリ - Spreadsheet2009/07/29

SpreadsheetはRubyからExecelファイルを操作するライブラリです。 MS-Officeには依存していないので、MS-Officeのインストールされていない環境(要はLinux環境)でも動作します。

Office2007形式(拡張子がxlsxのもの)には対応していないようです。(0.6.4現在)

以前は、

  • ParseExcel xlsファイルをパースしてruby objectにする
  • Spreadsheet/Excel Excelのワークブックの書き出し(パース機能は無い)

に分かれていたライブラリが統合されたことになっていますが、Spreadsheet/Excel側のAPIが変更されているので、 Spreadsheet/Excel前提のプログラムには修正が必要です。

ちなみに、作者はParseExcel側の Hannes Wyss氏です。

インストール

例によって

gem install spreadsheet

require

require 'spreadsheet'

require 'parseexcel'や、require 'spreadsheet/excel' 等の旧形式互換の記述が、1.0.0までは移行期間として有効です。

Spreadsheet.client_encoding

スクリプトで使用するエンコードを指定します。デフォルト値は'UTF-8'。 xlsファイル自体のエンコーディングには影響しません。

必要に応じて

Spreadsheet.client_encoding = 'cp932'

等します。

既存ファイルのオープンとワークシートの選択

book = Spreadsheet.open('filename.xls', 'rb')
sheet = book.worksheet(0)
sheet = book.worksheet('some sheet')

デフォルトのアクセスモードが 'rb+' なので、読み込みだけで良い場合は明示的に'rb'を指定するべきです。 ワークシートはindexかシート名でアクセスできます。 適切なワークシートが見付からなかった場合は nil が返却されます。

新規ファイルの作成

book = Spreadsheet::Workbook.new
sheet = book.create_worksheet
sheet.name = 'some sheet'

Spreadsheet/Excelと互換性がないので注意が必要です。 Workbook#add_worksheet は既に存在するWorksheetのインスタンスをWorkbookに登録するメソッドになりました。

セル要素へのアクセス

単一セル

sheet[row, col]
sheet[row, col] = value

戻り値はセルの値によって、数値(Fixnum, Float)だったり、Stringだったりします。 代入する時もこのあたりのクラスなら適当に入れられます。

行アクセス

row = sheet.row(2) # 戻り値はSpreadsheet::Row(かSpreadsheet::Excel::Row)
row.replace(['foobar', 'hoge', 'piyo'])
sheet.update_row(2, ['foobar', 'hoge', 'piyo'])

Spredshet::Row はEnumerable がMix-inされているので、いろいろ操作できます。 Spredshet::Row#insert, Spredshet::Row#push 等のメソッドもあります。

列アクセス

col = sheet.column(2) # 戻り値はSpreadsheet::Column(かSpreadsheet::Excel::Column)

Spreadsheet::Column は Enumerable がMix-inされていますが、列方向への一括アップデートのメソッドは定義されていません。 (互換性に関連の記述があります)

#単一セルに対応するクラスが用意されていないのは不思議な感じ。

ファイルの更新

book.write('filename.xls')

ファイル名は省略できません

互換性

前述の通り、Spreadsheet/ExcelとはAPIレベルで互換性がありません。 ただし、1.0.0までは移行期間として

require 'spreadsheet/excel'

として require することが許され、この場合は、Spreadsheet/Excel 互換のAPIが使えるようになります。

具体的には

ファイルの作成と保存について

book = Spreadsheet::Excel.new(filename)
book.close

といった記述が通るようになり、

Spreadsheet::Workbook.add_worksheet

の挙動がSpreadsheet/Excel互換(新規ワークシートのインスタンスを作成してワークブックに追加)に変更される他、

Spreadsheet::Worksheet#write
Spreadsheet::Worksheet#write_column
Spreadsheet::Worksheet#write_row

などの更新系のメソッドが使えるようになります。

特に Spreadsheet::Worksheet#write_column は通常のAPIには相当の機能が無いので悩ましいところですが、 これから新規に書き起こすプログラムでは使用するべきではないでしょう。

蛇足

互換性の問題を解決するトリックのため、RDocにpublicとして載っているメソッドが無いことがあるのと、 class_evalで定義されているメソッドが沢山ありこれらがRDocに記載されないので、RDocがまるで信用できません。

どうにかなりませんかね……。

あと、書式についても扱えるような気がするのですが、良く判りません。 書式の設定関係のメソッドも更新系のメソッドと同様、Spreadsheet/Excel互換モードでしか利用できないものがあるようで、 調べるのが面倒になりました。

気が向いたらちゃんと調べます。