LoginSignup
1
2

More than 3 years have passed since last update.

開発メモ rails excel操作

Posted at

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

バージョン古すぎぃ!
もうちょい新しいバージョンを使うときは再確認すること
多分使えるんじゃないかな

参考
https://qiita.com/Kta-M/items/02a2c41c5624f75498aa

1
2
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
1
2