【问题标题】:Upload, process and export CSV without Database上传、处理和导出没有数据库的 CSV
【发布时间】:2019-03-29 15:27:41
【问题描述】:

我正在构建一个非常简单的网络工具,用户可以在其中上传 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

从 cmets 中可以看出,此方法不起作用,因为 result 操作中不再存在临时文件路径。我怎么能在不接触 db 的情况下解决这个问题。

【问题讨论】:

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


    【解决方案1】:

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

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

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

    def upload
      original_csv = params[:csv]
    
      output_csv = CSV.generate do |csv|
        CSV.foreach(original_csv.path, headers: true) do |row|
          # process data
          csv << row
        end
      end
    
      send_data output_csv
    end
    

    【讨论】:

      【解决方案2】:

      试试这个:

      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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-08-01
        • 1970-01-01
        • 2022-06-12
        • 1970-01-01
        相关资源
        最近更新 更多