在没有数据库的情况下上传,处理和导出CSV

时间:2018-10-25 05:46:36

标签: ruby-on-rails ruby csv upload export-to-csv

我正在构建一个非常简单的Web工具,用户可以在其中上传CSV文件,然后对该文件进行处理,然后可以立即下载结果CSV。

上传表单:

<%= form_tag '/upload', multipart: true do %>
  <%= file_field_tag :csv %>
  <%= submit_tag 'Import CSV' %>
<% end %>

上传和下载操作:

def upload
  original_csv = params[:csv]
  p original_csv.path # /var/folders/71/chp2vrc92_19b3jt2fcwhvp80000gn/T/RackMultipart20181025-11469-25guh5.csv
  redirect_to result_path(file_path: original_csv.path)
end

def result
  p params[:file_path] # /var/folders/71/chp2vrc92_19b3jt2fcwhvp80000gn/T/RackMultipart20181025-11469-25guh5.csv
  output_csv = CSV.generate do |csv|
    CSV.foreach(params[:file_path], headers: true) do |row|
      #############################################
      # "No such file or directory @ rb_sysopen"  #
      # exception is thrown                       #
      #############################################

      # each row data is being processed here
      csv << row
    end
  end

  # Download the file into user's computer
  send_data output_csv
end

从注释中可以看到,此方法不起作用,因为临时文件路径在result操作中不再存在。我该怎么办却根本不接触数据库。

2 个答案:

答案 0 :(得分:1)

上载的文件由应用程序存储为临时文件。这意味着一旦请求结束,临时文件将被自动删除。因此,当请求下一页时,它不再存在。

一个选择是将文件自己复制到另一个位置,并使它成为文件系统中的“真实”文件,该文件不再自动删除。但这也有缺点:现在您也有责任自己管理和删除这些文件。这意味着您需要生成唯一的文件名并将它们传递给下一个请求,并且需要确保在下载文件后删除该文件,否则这些文件将慢慢占用服务器磁盘上的所有空间。此外,它不能扩展到多台服务器,仅适用于在一台服务器上运行的小型应用程序。

更好的选择可能是仅在一个请求中执行上载,处理和下载,而无需任何重定向。只要可以在合理的时间和内存中完成处理,这可能是避免复杂性的好选择。

Stream

答案 1 :(得分:0)

尝试一下:

def upload
  result(params[:csv])
end

def result(fpath=params[:file_path])
  output_csv = CSV.generate do |csv|
    CSV.foreach(fpath, headers: true) do |row|
      csv << row
    end
  end

  # Download the file into user's computer
  send_data output_csv
end