#Ruby on Rails で Excelファイル操作
業務で必要だったのでメモ書き。
excel操作には「spreadsheet」を使用。
excelを取り込むときは、「form_tag」で「:multipart=>true」を設定しておかないとparamsで受け取った時、「ファイル」として受け取れず、文字列で受け取るので注意
以下source
_form.html.erb
<%= form_tag(User_path, :method=>"get", :multipart=>true) do %>
<%= file_field_tag :upload_file %>
<%= submit_tag "取込" %>
<%= submit_tag "出力" %>
<% end %>
User.controller.rb
def index
if params[:commit] == "出力"
output_user_list()
elsif params[:commit] == "取込"
import_user_list(params[:upload_file])
end
end
#出力処理
def output_user_list(params)
#出力対象のリストを取得
users = User.new(params)
@output_user_list = user.search()
filename = "user_lists_#{Time.now.strftime('%y%m%d%H%M%S')}.xls"
tempfilename = "temp_user_lists_#{Time.now.strftime('%y%m%d%H%M%S')}.xls"
# IE対応:ファイル名のエンコード
filename = filenameEncode(filename)
Spreadsheet.client_encoding = 'UTF-8'
book = Spreadsheet.open("public/user_lists.xls")
sheet1 = book.worksheet(0) #レイアウトを指定
#カウンター
row_count = 0
col_count = 0
begin
#セルに値をセット
@output_user_list .each do |user|
sheet1[row_idx + row_count, col_count] = user.name
col_count += 1
sheet1[row_idx + row_count, col_count] = user.age
col_count += 1
#########################
# 出力処理 省略
#########################
# 一列処理終了
col_count = 0
row_count += 1
end
rescue => e
#エラー処理
#エラーの内容と行数をwibrickに出力
logger.debug "書き込み時エラー:#{e}"
err = Array.new
e.backtrace.each do |e|
err << e.to_s if e.include?("#{railsのプロジェクト名}")
end
logger.debug "バックトレース:#{err.inspect}"
@notice = "出力に失敗しました"
return false
else
# ファイルを生成、ダウンロード
# ------------------------------------------------
# TempFileの作成
# ------------------------------------------------
tempfile = Tempfile.new(tempfilename,"#{Rails.root}/public/")
book.write(tempfile)
# ------------------------------------------------
# ファイルの転送
# ------------------------------------------------
tempfile.open
tempfile.binmode
send_data(
tempfile.read,
:disposition => 'attachment',
:type => 'application/octet-stream',
:filename => filename
)
tempfile.close(true)
end
end
#取込処理
def import_user_list(import_excel)
#渡されたファイルの情報は以下の要素で取得可能
#一時的にtmpファイルに保存される
excel_original_filename = import_excel.original_filename
excel_content_type = import_excel.content_type
excel_headers = import_excel.headers
excel_tempfile = import_excel.tempfile
begin
spreadsheet = Spreadsheet.open(excel_tempfile)
sheet = spreadsheet.worksheet(0) #出力レイアウトを指定
sheet.each_with_index do |row, idx|
#A列に値がなければスキップ
if row[0].to_s != ""
logger.debug "#{idx}行目: #{row[0]} #{row[1]} #{row[2]}"
end
end
#sheet.count で総行数取れるので、forでもeachでも。
logger.debug "sheet : " + sheet.count.to_s
rescue => e
logger.debug "読み込み時エラー:#{e}"
#エラーの内容と行数をwibrickに出力
logger.debug "書き込み時エラー:#{e}"
err = Array.new
e.backtrace.each do |e|
err << e.to_s if e.include?("#{railsのプロジェクト名}")
end
logger.debug "バックトレース:#{err.inspect}"
@notice = "出力に失敗しました"
return false
else
return true
end
end
ruby 1.9.2
rails 3.0.5
spreadsheet
バージョン古すぎぃ!
もうちょい新しいバージョンを使うときは再確認すること
多分使えるんじゃないかな