19
26

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

RubyでExcelファイルを読み込むgem「roo」を使う

Posted at

概要

rubyからスプレッドシート形式のファイルを操作するgem、rooの使用方法。

この記事では、主にExcelファイルを扱う際に使用出来るメソッドなどを調べてみます。
基本的に、READMEから使えそうなものを紹介し、その後実際に簡単な操作をしてみることにします。

roo-rb/roo: Roo provides an interface to spreadsheets of several sorts.

動作環境

  • OS X El Capitan 10.11.6

  • ruby 2.2.6

  • roo 2.7.1

今回使用するExcelファイル

以下のようなデータを持ったExelファイルを操作します。

スクリーンショット 2017-12-07 22.03.38.png

rooのインストール

ターミナルで以下のコマンドを実行してrooのインストールを行います。
ファイル名はroo_test.xlsxです。

$ gem install roo

Excelファイルを読み込んでみる

以下のようなコードで指定したファイルを読み込むことができます。

roo_sample.rb
require 'roo'

xlsx = Roo::Excelx.new('./roo_test.xlsx')

読み込んだファイルに対して操作する

ファイル読み込み&基本情報出力

require 'roo'
xlsx = Roo::Excelx.new('./roo_test.xlsx')

puts xlsx.info
# =>
# File: roo_test.xlsx
# Number of sheets: 1
# Sheets: Sheet1
# Sheet 1:
#   First row: 1
#   Last row: 4
#   First column: A
#   Last column: D

以下、ファイルはすでに読み込まれているとします。

エクセルシートから行ごとにデータを読み出す。

xlsx.each_row_streaming do |row|
  puts row.inspect
end
# 例として1列目のデータを表示
# =>
# [
#   #<Roo::Excelx::Cell::String:0x007fd1298442f0 @link=false, @cell_value="名前", @cell_type=:string, @formula=nil, @style=0, @coordinate=#<Roo::Excelx::Coordinate:0x007fd129845268 @row=1, @column=1>, @type=:string, @value="名前">,
#   #<Roo::Excelx::Cell::String:0x007fd12983fa20 @link=false, @cell_value="国語", @cell_type=:string, @formula=nil, @style=1, @coordinate=#<Roo::Excelx::Coordinate:0x007fd12983ff98 @row=1, @column=2>, @type=:string, @value="国語">,
#   #<Roo::Excelx::Cell::String:0x007fd12983f048 @link=false, @cell_value="算数", @cell_type=:string, @formula=nil, @style=1, @coordinate=#<Roo::Excelx::Coordinate:0x007fd12983f7f0 @row=1, @column=3>, @type=:string, @value="算数">,
#   #<Roo::Excelx::Cell::String:0x007fd12983e5a8 @link=false, @cell_value="理科", @cell_type=:string, @formula=nil, @style=1, @coordinate=#<Roo::Excelx::Coordinate:0x007fd12983ee90 @row=1, @column=4>, @type=:string, @value="理科">
# ]

each_row_streamingで使用出来るオプション

デフォルトで空のセルは除外されるが、pad_cells: trueを指定することでそれらを残すことができます。

xlsx.each_row_streaming(pad_cells: true) do |row|
  puts row.inspect
end

指定した行だけをストリーミングすることができます。
offsetで最初に飛ばす行数を指定
max_rowsでストリーミングする行数を指定

xlsx.each_row_streaming(offset: 1, max_rows: 1) do |row|
  puts row.inspect
end
# max_rowsが取り出す行数はmax_rowsで指定した数+1になることに注意
# この場合、飛ばす行数1かつ取り出す行数1+1=2より山田小林の2行で処理が行われる

その他Roo::Excelxで使えそうなメソッド

p xlsx.excelx_type(4, 'A')
# 指定したセルの型を返す
# => :string

p xlsx.cell(3, 'A')
# 指定したセルの値を返す
# => "小林"

エクセルのデータを集計してみる

先ほどのExcelファイルを利用して、それぞれの合計点数を計算してみます。

calc_sum.rb
require 'roo'

xlsx = Roo::Excelx.new('./roo_test.xlsx')

xlsx.each_row_streaming(offset: 1) do |row|
  sum = 0
  row.each do |cell|
    next if cell.value.nil? || cell.cell_type[0] != :numeric_or_formula
    sum += cell.value
  end
  puts "#{row[0]}さんの合計点数は#{sum}です。"
end
# =>
# 山田さんの合計点数は190です。
# 小林さんの合計点数は140です。
# 佐藤さんの合計点数は260です。

まとめ

RubyからExcelファイルを操作できるgemであるrooを使ってみました。
ファイルを読み込み、その数値を利用し集計、出力することができました。

他にも、CSVなど他のデータ形式に変換するなど、できることはまだまだありそうなので、また機会があれば詳しく調べていきたいと思っています。

19
26
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
26

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?