jrubyからApache POIを使う超手抜きモジュール
rubyからExcelファイルを読み書きするのは、Spreadsheet(pure ruby)とかwin32oleを使う方法がある。
たまたま、とあるExcelテンプレートファイルを読んで、ごにょごにょ編集して、別ファイルに出力するという機会があった。
この処理をLinux上で動かしたかったため、Spreadsheetを試してみたが、運悪くそのテンプレートファイルには
シートの保護がなされていて、出力したExcelファイルがどうしても壊れてしまう。
このへんは、Spreadsheetが対応できていないようだ。
ほかに似たようなライブラリがないか探してみたが、どうにも見つからない。
仕方がないので、実績のあるApache POIをjrubyから使ってみることにした。
さすがにPOI。難なくやりたいことができてしまった。
それにしてもこのPOI、値をセットするときは型を気にする必要はないが、
取得するときはいちいちセルの型を調べないといけないのがちょっと面倒…
poi_workbook.rb:
require 'java' require './poi-3.7-20101029.jar' require './poi-ooxml-3.7-20101029.jar' java_import java.io.FileInputStream java_import java.io.FileOutputStream java_import org.apache.poi.ss.usermodel.WorkbookFactory java_import org.apache.poi.ss.usermodel.DataFormatter class Workbook def initialize(path) @fis = FileInputStream.new(path) @book = WorkbookFactory::create(@fis) end def self.open(path, &block) book = Workbook.new(path) return book unless block_given? yield book ensure book.close end def write(path) fos = FileOutputStream.new(path) @book.write(fos) ensure fos.close end def close @fis.close end def select_sheet_at(index) @sheet = @book.get_sheet_at(index) @sheet.set_force_formula_recalculation(true) end def []=(row_idx, col_idx, value) @sheet.create_row(row_idx) if @sheet.get_row(row_idx).nil? row = @sheet.get_row(row_idx) row.create_cell(col_idx) if row.get_cell(col_idx).nil? row.get_cell(col_idx).set_cell_value(value) end def [](row, col) return nil if (row = @sheet.get_row(row)).nil? or (cell = row.get_cell(col)).nil? return DataFormatter.new.format_cell_value(cell) end end if __FILE__ == $0 # sample usage Workbook.open('template.xls') do |book| book.select_sheet_at(0) book[0, 0] = book[0, 0] + ' new value' book.write('new.xls') end end
※細々としたセルの値に対応していません。