Edited at

RailsでExcelを扱うGemまとめ

More than 5 years have passed since last update.

RailsにはExcelを扱うGemがいくつかあり、それぞれ特徴があるのでまとめてみる。

ついでに簡単なテストコードも載せてみる。

テストで扱うデータはこんな感じ。

もちろんしかるべきところには計算式を入れてある。

新規作成の場合はこれを作成する。

読み込みの場合はこのデータを読み込んで表示、さらに編集・書き出しが可能な場合には牛肉の単価を500円(和牛)に変更する。

品名
単価
数量

にんじん
80
1
80

たまねぎ
50
2
100

じゃがいも
40
2
80

牛肉
200
1
200

カレー粉
150
1
150


610


spreadsheet

zdavatz/spreadsheet



  • TheRubyToolboxによると、一番多く使われているらしい


  • .xlsx, .xlsmは扱えない

  • 新規作成、読み込み、書き出しが可能

  • セルの書式設定は面倒そう

# 新規作成

book = Spreadsheet::Workbook.new
sheet = book.create_worksheet(name: 'curry')

# いろいろな方法でデータを入れられる
# 計算式は入力できない
sheet.row(0).concat %w{品名 単価 数量 計}

sheet[1,0] = 'にんじん'
sheet[1,1] = 80
sheet[1,2] = 1
sheet[1,3] = 80

row = sheet.row(2)
row.push 50
row.push 2
row.push 100
row.unshift 'たまねぎ'

sheet.row(3).replace [ 'じゃがいも', 40, 2, 80 ]

sheet.row(4).push '牛肉', 1, 200
sheet.row(4).insert 1, 200

sheet.update_row 5, 'カレー粉', 150, 1, 150

sheet[6,2] = '総計'
sheet[6,3] = 610

book.write('test.xls')

# 読み込み                                                                                                   

book = Spreadsheet.open(filepath)
sheet = book.worksheet('curry')
sheet.each do |row|
# 数式が入っているセルは .value で値を取得
puts "#{row[0]} #{row[1]} #{row[2]} #{row[3].instance_of?(Spreadsheet::Formula) ? row[3].value : row[3]}"
end


axlsx

randym/axlsx


  • 扱う拡張子は.xlsx

  • 新規作成専用で、既存ファイルの読み込みは不可

  • セルの書式設定はやりやすい印象

  • セルに画像を貼ったり、グラフを表示したりもできるっぽい(未検証)

# 新規作成

package = Axlsx::Package.new
sheet = package.workbook.add_worksheet(name: 'curry')

sheet.add_row(['品名', '単価', '数量', '計'])
sheet.add_row(['にんじん', 80, 1, '=B2*C2'])
sheet.add_row(['たまねぎ', 50, 2, '=B3*C3'])
sheet.add_row(['じゃがいも', 40, 2, '=B4*C4'])
sheet.add_row(['牛肉', 200, 1, '=B5*C5'])
sheet.add_row(['カレー粉', 150, 1, '=B6*C6'])
sheet.add_row(['', '', '総計', '=SUM(D2:D6)'])

package.serialize('test.xlsx')


roo

Empact/roo



  • .xls.xlsxが扱える(他にも.ods.csvや google spreadsheet も扱えるらしい)

  • 読み込み専用で、新規作成、書き出しは不可

# 読み込み                                                                      

s = Roo::Excel.new(filepath) # .xlsx を読み込むときは Roo::Excelx.new
s.default_sheet = 'curry'
s.first_row.upto(s.last_row) do |row|
puts "#{s.cell(row, 1)} #{s.cell(row, 2)} #{s.cell(row, 3)} #{s.cell(row, 4)}"
end


rubyXL

weshatheleopard/rubyXL



  • .xlsx.xlsmが扱えるが、.xlsmにマクロが含まれているとデータが壊れる…


    • もしマクロ入り.xlsmを壊さずに扱える方法をご存じの方がいれば教えて下さい!



  • 新規作成、読み込み、書き出しが可能

  • セルの書式設定はやりやすい印象

# 新規作成

book = RubyXL::Workbook.new
sheet = book[0] # 最初からシートが1つある
sheet.sheet_name = 'curry'
sheet.add_cell(0, 0, '品名')
sheet.add_cell(0, 1, '単価')
sheet.add_cell(0, 2, '数量')
sheet.add_cell(0, 3, '計')

sheet.add_cell(1, 0, 'にんじん')
sheet.add_cell(1, 1, 80)
sheet.add_cell(1, 2, 1)
sheet.add_cell(1, 3, '', 'B2*C2')

# 中略

sheet.add_cell(6, 2, '計')
sheet.add_cell(6, 3, '', 'SUM(D2:D6)')

book.write("test.xlsx")

# 読み込み                                                                

book = RubyXL::Parser.parse(filepath)
sheet = book['curry']
sheet.each do |row|
puts "#{row[0].value} #{row[1].value} #{row[2].value} #{row[3].value}"
end

# 編集
sheet[4][1].change_contents(500)

# 書き込み
book.write(filepath)


まとめ

使い分けとしては、



  • .xlsでもいいからネット上の情報が豊富なやつを使いたい -> spreadsheet

  • システムのみでリッチな.xlsxファイルを作りたい -> axlsx


  • .xlsxファイルを読み出すだけでいいから気軽に扱いたい -> roo

  • テンプレートの.xlsxファイルがあって、それにデータを書き込んで保存したい -> rubyXL

といった感じかな…。

ちなみにどのGemでもマクロが含まれていると扱えなかった。