我正在尝试上传 csv 文件,解析它,然后为 S3 生成一个文件,或者只是传递给查看。我使用 file_field_tag 上传 csv。我认为 file_field_tag 传递的对象是 IO 的子类,并且具有所有 ruby IO 方法,例如“each_line”。我可以在对象上调用“read”(IO 类的方法),但不能调用“each_line”...那么如何迭代 file_field_tag 上传的每一行?
我的 Controller 的创建方法为:
@csv_file = params[:csv_file]
我的显示 View 抛出无“each_line”方法错误:
<% @csv_file.each_line do |line| %>
<%= line %>
<% end %>
但是我可以使用
<%= @csv_file.read(100) %>
我真的很困惑 file_field_tag upload params[] 有什么方法...each_line, gets 不起作用...我似乎找不到我可以使用的列表。
编辑 我通过这样做解决了这个问题:
@csv_file = params[:csv_file].read.to_s
然后迭代:
<% @sp_file.each_line do |line| %>
<%= line %>
<% end %>
编辑2 正在上传的文件在不包含逗号的行之后重复了标题(不要问)...所以我找到不包含逗号的行并调用 .gets (在我的 rb 脚本中独立于 Rails)。不幸的是,我收到一个关于 gets 是我无法调用的私有(private)方法的错误。这又回到了我最初的问题。文件不是具有像 read_lines 和 gets 这样的 IO 方法的 IO 子类吗?
@file_out = []
@file_in.each_line do |line|
case line
when /^[^,]+$/
@comp = line.to_s.strip
comp_header = @file_in.gets.strip.split('')
@file_out.push(@comp)
end
end
最佳答案
当您发布 'file_field' 时,返回到 Controller 的参数具有一些特殊的魔力。
即在你的情况下你可以这样
<%= "The following file was uploaded #{params[:csv_file].original_filename}" %>
<%= "It's content type was #{params[:csv_file].content_type}" %>
<%= "The content of the file is as follows: #{params[:csv_file].read}" %>
因此,这些是您可以在 params[:csv_file] 上调用的三种特殊方法,或者在 View 中作为成功的“file_field_tag”或“f.file_field”结果发布的任何参数
请记住,这些是您可以对作为 file_field 发布的参数进行的三个额外特殊操作:
原始文件名
内容类型
阅读
您已经清楚地知道如何进行读取,original_filename 和 content_type 可能会在将来帮助您。
编辑
好的,所以你所拥有的就是 read 方法,它将读取上传的文件的内容。
contents = params[:csv_file].read
现在,contents 是一个包含文件内容的字符串,但除了它是一个 csv 文件之外,对该文件一无所知。我们知道 csv 是用 '\r' 分隔的(我想,我已经做了很多解析 csv 的工作,但我懒得去检查)
所以你可以这样做:
contents = params[:csv_file].read
contents.split("\r").each do |csvline|
???
end
编辑2
这是这篇文章的要点
当您将 file_field 发布到 Controller 时,对上传文件的内容最常见的操作是将其“读取”到 ruby 字符串中。对上传内容的任何额外处理都必须在“read”返回的 ruby 字符串上完成。
在这种特殊情况下,如果上传的文件始终是 CSV,您可以假设 CSV 并开始相应地解析它。如果您期望多种上传格式,则必须处理该问题,例如:
contents = params[:csv_file].read
case params[:csv_file].content_type
when 'txt/csv'
contents.split("\r").each do |csvline|
???
end
when 'application/pdf'
???
end
关于ruby-on-rails - 有没有一个rails方法可以循环遍历上传文件的每一行? "each_line"是一个IO方法,但它不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14178396/