从Ruby中的哈希数组生成HTML表

什么是从散列数组生成HTML表格的最佳方法(理想情况下是gem,但必要时还有代码片段)?

例如,这个哈希数组:

[{"col1"=>"v1", "col2"=>"v2"}, {"col1"=>"v3", "col2"=>"v4"}] 

应该生成这个表:

 
col1col2
v1v2
v3v4

使用XMLBuilder:

 data = [{"col1"=>"v1", "col2"=>"v2"}, {"col1"=>"v3", "col2"=>"v4"}] xm = Builder::XmlMarkup.new(:indent => 2) xm.table { xm.tr { data[0].keys.each { |key| xm.th(key)}} data.each { |row| xm.tr { row.values.each { |value| xm.td(value)}}} } puts "#{xm}" 

产量

 
col1 col2
v1 v2
v3 v4
 # modified from Harish's answer, to take care of sparse hashes: require 'builder' def hasharray_to_html( hashArray ) # collect all hash keys, even if they don't appear in each hash: headers = hashArray.inject([]){|a,x| a |= x.keys ; a} # use array union to find all unique headers/keys html = Builder::XmlMarkup.new(:indent => 2) html.table { html.tr { headers.each{|h| html.th(h)} } hashArray.each do |row| html.tr { row.values.each { |value| html.td(value) }} end } return html end 

这似乎并不特别难以手工完成。 根据你将要使用它的位置,这可能应该在某个地方使用自己的方法,但这里是我刚写的小脚本:

table.rb

 class Array def to_cells(tag) self.map { |c| "<#{tag}>#{c}" }.join end end rows = [{"col1"=>"v1", "col2"=>"v2"}, {"col1"=>"v3", "col2"=>"v4"}] headers = "#{rows[0].keys.to_cells('th')}" cells = rows.map do |row| "#{row.values.to_cells('td')}" end.join("\n ") table = " #{headers} #{cells} 
" puts table

输出:

 
col1col2
v1v2
v3v4

显然,存在一些问题 – 例如,它假设第一行的标题与所有其他标题相同。 但是,您可以非常轻松地预处理和解决此问题,方法是在所有行中填入nils,以便未正确分配所有标题。

没有gem的原因是生成表并不是一项巨大的工作。 当你扣下来并自己编写代码时,你可以做的事情真是太棒了:)

您可以使用builder

 require 'builder' a = [{"col1"=>"v1", "col2"=>"v2"}, {"col1"=>"v3", "col2"=>"v4"}] builder = Builder::XmlMarkup.new columns = a.first.keys builder.table do |t| t.tr do |tr| columns.each do |col| tr.th(col) end end a.each do |row| t.tr do |tr| columns.each do |col| tr.td(row[col]) end end end end p builder.target #=> "
col1col2
v1v2
v3v4
"

Matchu的答案给了我很多启发,我将其修改为自定义方法,而不是更改内置类(除非你有一个非常好的理由,否则不要这样做)。

此外,在生成表格时,Array的结构可能更方便,更直观地访问元素。

比方说,让整个表存储在二维数组中

 @table_array = [ ["Name","Gender","Age"], ["Andy","M","20"], ["Mary","F","19"], ["Tony","M","18"] ] 

其中每个第一个元素用作表头,其余元素是表内容。 现在我们可以使用格式良好的table_array和一个表类属性来生成表格html代码:

 def ToCell (tag,value) value.map{ |c| "<#{tag}>#{c}" }.join end def ToTable (table_array, table_class) headers = "" + ToCell('th',table_array[0]) + "" cells = table_array[1..table_array.count].map{ |each_row| "#{ToCell('td',each_row)}" }.join table = "#{headers}#{cells}
" end

并将其嵌入.erb文件中

 <%= ToTable(@table_array,"table").html_safe %> 

如果从浏览器中看到,输出将是这样的

 
NameGenderAge
AndyM20
MaryF19
TonyM18

我开发的dom gem具有你想要做的function。 您可以在Ruby代码中轻松创建这样的表:

 require "dom" [%w[aaa bbb], %w[ccc ddd]].dom(:td, :tr, :table) # => "
aaabbb
cccddd
"