第7回 CSV形式経由でExcelデータを読み込む
2008/02/23
今回は、カンマ区切り(CSV)形式のデータを Ruby on Rails で利用する方法について説明します。
まず、右図のような Excel ファイル table2.xls
を用意してください。
Excel の [ファイル名を付けて保存] メニューで、[ファイルの種類] として「CSV(カンマ区切り)」を選び、RAILS_ROOT/data/table2.csv
として保存します。もし RAILS_ROOT/data
ディレクトリが存在しなければ、作成してください。
このデータを使ってテーブルを表示する TablesController
は、次のようになります。
require 'csv' class TablesController < ActionController def show id = params[:id] @records = [] reader = CSV.open(RAILS_ROOT + "/data/table#{id}.csv", 'r') reader.shift reader.each {|row| @records << row } end end
前回の記事で作成した TablesController
との違いに注意してください。
ポイントは次の通りです:
CSV
モジュールを読み込むため、冒頭にrequire 'csv'
と書かれている。CSV.open
の第二引数には、読み込みモードを示す文字列'r'
を指定する。- CSV データのヘッダ行を読み飛ばすには、
shift
メソッドを使う。 @records &;&; row
という書き方で、@records
の末尾にrow
を要素として加える。
テンプレート show.rhtml
も前回のそれとは少し違います。
<table border="1" cellpadding="4"> <tr> <th>名前</th> <th>メールアドレス</th> <th>年齢</th> </tr> <% @records.each do |record| -%> <tr> <td><%= record[0] %></td> <td><%= record[1] %></td> <td><%= record[2] %></td> </tr> <% end -%> </table>
前回は、変数 record
がハッシュでしたが、今回は配列です。record['email']
のようには書けません。
ブラウザで http://localhost:3000/tables/show/2
にアクセスし、次のように表示されることを確認してください。
名前 | メールアドレス | 年齢 |
---|---|---|
taro | taro@sample.com | 39 |
jiro | jiro@sample.com | 35 |
saburo | saburo@sample.com | 31 |
さて、読者の中には文字コードの処理は大丈夫なのだろうか、と心配になった方もいらっしゃることでしょう。
RAILS_ROOT/data/table2.csv
を Excel で開いて、「taro」を「太郎」に変えてみましょう。ブラウザをリロードすると…、あ。ダメです。文字化けしてしまいます。
Excel が作る CSV ファイルの文字コードは Shift JIS で、Rails の文字コードは UTF-8 なので変換が必要です。
require 'csv' class TablesController < ActionController def show id = params[:id] @records = [] reader = CSV.open(RAILS_ROOT + "/data/table#{id}.csv", 'r') reader.shift reader.each do |row| row = row.collect {|value| NKF.nkf('-Sw', value) } @records << row end end end
NKF
モジュールの nkf
メソッドは、日本語文字列の文字コードを変換します。第1引数 '-Sw'
は、入力が Shift JIS で、出力が UTF-8 であることを示しています。配列 row
の collect
メソッドは、配列要素を一つずつ変数 value
に格納して、ブロック(中括弧で囲まれたコード)を実行し、その結果から新たな配列を作ります。
ブラウザをリロードすると…、今度は大丈夫です。
名前 | メールアドレス | 年齢 |
---|---|---|
太郎 | taro@sample.com | 39 |
jiro | jiro@sample.com | 35 |
saburo | saburo@sample.com | 31 |