Rails

【Rails】Excelデータを読み込むことができるgem「roo」のREADMEを読んでみる

Rails

 

今回はExcelデータを読み込むことができるgem「roo」のREADMEを読んでみたので、翻訳しつつその内容を備忘録としてまとめました。

このREADMEの内容は2022/06/19時点のものになります。

Roo

Rooはあらゆるスプレッドシートタイプの読み取り機能を実装しています。

以下を扱うことができます:

  • Excel 2007-2013形式(xlsx、xlsm)
  • LibreOffice / OpenOffice.org形式(ods)
  • CSV
  • roo-xls gem(xls、xml)使用時 → Excel 97、Excel 2002 XML、およびExcel 2003 XML形式
  • roo-google使用時 → Googleスプレッドシートの読み取り/書き込み

インストール

gemとしてインストールします。

$ gem install roo

 

もしくは以下をGemfileに追加します。

gem "roo", "~> 2.9.0"

使い方

スプレッドシートを開く

require 'roo'

xlsx = Roo::Spreadsheet.open('./new_prices.xlsx')
xlsx = Roo::Excelx.new("./new_prices.xlsx")

# Use the extension option if the extension is ambiguous.
xlsx = Roo::Spreadsheet.open('./rails_temp_upload', extension: :xlsx)

xlsx.info
# => Returns basic info about the spreadsheet file

Roo::Spreadsheet.openはパスとファイルインスタンスを受け取ることができます。

 

シートでの作業

ods.sheets
# => ['Info', 'Sheet 2', 'Sheet 3']   # an Array of sheet names in the workbook

ods.sheet('Info').row(1)
ods.sheet(0).row(1)

# Set the last sheet as the default sheet.
ods.default_sheet = ods.sheets.last
ods.default_sheet = ods.sheets
ods.default_sheet = 'Sheet 3'

# Iterate through each sheet
ods.each_with_pagename do |name, sheet|
  p sheet.row(1)
end

 

行と列へのアクセス

Rooは行、列、およびセルにExcelの番号付けを使用するため、1が最初のインデックスであり配列の場合の0ではありません。

sheet.row(1)
# returns the first row of the spreadsheet.

sheet.column(1)
# returns the first column of the spreadsheet.

 

大抵のメソッドにはオプションの引数sheetがあります。このパラメーターを省略すると、default_sheetが使用されます。

sheet.first_row(sheet.sheets[0])
# => 1             # the number of the first row
sheet.last_row
# => 42            # the number of the last row
sheet.first_column
# => 1             # the number of the first column
sheet.last_column
# => 10            # the number of the last column

 

セルへのアクセス

以下の方法で左上のセルにアクセスできます。

sheet.cell(1,1)
sheet.cell('A',1)
sheet.cell(1,'A')
sheet.a1

# Access the second sheet's top-left cell.
sheet.cell(1,'A',sheet.sheets)

 

スプレッドシートのクエリ

eachを使用して、各行を繰り返し処理します。

eachにいくつかの列の名前のハッシュが与えられた場合、eachが各行に提供された列のハッシュを生成します。

sheet.each(id: 'ID', name: 'FULL_NAME') do |hash|
  puts hash.inspect
  # => { id: 1, name: 'John Smith' }
end

 

sheet.parseを使用すると行の配列を返します。列名はStringまたはRegexpにすることができます。

sheet.parse(id: /UPC|SKU/, qty: /ATS*\sATP\s*QTY\z/)
# => [{:id => 727880013358, :qty => 12}, ...]

 

:headersオプションを使用すると解析コンテンツにヘッダー行を含めことができます。

sheet.parse(headers: true)

 

:header_searchオプションを使用するとヘッダー行を見つけヘッダー名を割り当てることができます。

sheet.parse(header_search: [/UPC*SKU/,/ATS*\sATP\s*QTY\z/])

 

cleanオプションを使用すると制御文字と周囲の空白を取り除くことができます。

sheet.parse(clean: true)

 

オプション

ファイルを開く際、オプションのハッシュを追加することができます。

Expand_merged_ranges

セルが結合されたドキュメントを開き、最初の行の後の行の値がnilにならないようにする場合。

xlsx = Roo::Excelx.new('./roo_error.xlsx', {:expand_merged_ranges => true})

 

スプレッドシートのエクスポート

Rooには次の形式を使用してシートをエクスポートする機能があります。 default_sheetのみをエクスポートします。

sheet.to_csv
sheet.to_matrix
sheet.to_xml
sheet.to_yaml

 

Excel(xlsxおよびxlsm)のサポート

Excelxスプレッドシートから行をストリーミングします。

xlsx = Roo::Excelx.new("./test_data/test_small.xlsx")
xlsx.each_row_streaming do |row|
  puts row.inspect # Array of Excelx::Cell objects
end

 

デフォルトでは、空白のセルは配列から除外されます。それらを保持するには、オプションpad_cells=trueを使用します。 (配列ではnilに設定されます)

xlsx.each_row_streaming(pad_cells: true) do |row|
  puts row.inspect # Array of Excelx::Cell objects
end

 

一部の行のみをストリーミングするには、max_rowsoffsetoptionsを使用できます。

xlsx.each_row_streaming(offset: 1) do |row| # Will exclude first (inevitably header) row
  puts row.inspect # Array of Excelx::Cell objects
end
xlsx.each_row_streaming(max_rows: 3) do |row| # Will yield 4 rows (it's automatically incremented by 1) after the supplied offset.
  puts row.inspect # Array of Excelx::Cell objects
end

 

各行を繰り返します

xlsx.each_row do |row|
  ...
end

 

Roo :: Excelxはこれらの便利なメソッドも提供します。

xlsx.excelx_type(3, 'C')
# => :numeric_or_formula

xlsx.cell(3, 'C')
# => 600000383.0

xlsx.excelx_value(row,col)
# => '600000383'

xlsx.formatted_value(row,col)
# => '0600000383'

 

Roo :: Excelxはセルタイプ、コメント、フォント情報、数式、ハイパーリンク、およびラベルにアクセスできます。

xlsx.comment(1,1, ods.sheets[-1])
xlsx.font(1,1).bold?
xlsx.formula('A', 2)

 

OpenOffice/LibreOfficeサポート

Roo::OpenOfficeは暗号化OpenOfficeスプレッドシートをサポートしています。

# Load an encrypted OpenOffice Spreadsheet
ods = Roo::OpenOffice.new("myspreadsheet.ods", password: "password")

 

Roo::OpenOfficeはセルタイプ/コメント/フォント/数式/ラベルにアクセスできます。

ods.celltype
# => :percentage

ods.comment(1,1, ods.sheets[-1])

ods.font(1,1).italic?
# => false

ods.formula('A', 2)

 

CSVサポート

# Load a CSV file
csv = Roo::CSV.new("mycsv.csv")

 

Rooは標準のCSVライブラリを使用するため、そのライブラリで使用可能なオプションを使用してcsvファイルを解析できます。 csv_optionsキーを使用してオプションを渡すことができます。

たとえば、タブ区切りファイル(.tsv)をロードしたり、ファイルを開くときに特定のエンコーディングを使用したりできます。

# Load a tab-delimited csv
csv = Roo::CSV.new("mytsv.tsv", csv_options: {col_sep: "\t"})

# Load a csv with an explicit encoding
csv = Roo::CSV.new("mycsv.csv", csv_options: {encoding: Encoding::ISO_8859_1})

 

Roo :: Spreadsheetクラスを介してcsvファイルを開くこともできます(たとえば、ユーザーファイルのアップロードからCSVタイプとExcelタイプの両方を受け入れる場合に便利です)。

# Load a spreadsheet from a file path
# Roo figures out the right parser based on file extension
spreadsheet = Roo::Spreadsheet.open(csv_or_xlsx_file)

# Load a csv and auto-strip the BOM (byte order mark)
# csv files saved from MS Excel typically have the BOM marker at the beginning of the file
spreadsheet = Roo::Spreadsheet.open("mycsv.csv", { csv_options: { encoding: 'bom|utf-8' } })

Roo1.13.xからのアップグレード

.xlsまたはGoogleスプレッドシートを使用している場合、その機能を引き続き使用するにはroo-xlsまたはroo-googleをインストールする必要があります。

Rooのパブリックメソッドは1.13.xと2.0.0の間で比較的一貫性が保たれていますが、1.13.x以降に行われた変更をよりよく理解するには、変更ログを確認してください。

参考

roo README

 

今回はExcelデータを読み込むことができるgem「roo」のREADMEを読んでみたので、翻訳しつつその内容を備忘録としてまとめてみました。Excelデータだけでなく、GoogleスプレッドシートやCSVファイルも読み込むことができるのは強いですね。