Permalink
Browse files

'init'

  • Loading branch information...
0 parents commit 75a1d34e252f10f2ddd0511ee5659ecc4d6b58f4 @stevo committed Oct 11, 2009
Showing with 173 additions and 0 deletions.
  1. +2 −0 .gitignore
  2. 0 README
  3. +1 −0 init.rb
  4. +1 −0 install.rb
  5. +7 −0 lib/excellent.rb
  6. +10 −0 lib/excellent/base_overrides.rb
  7. +1 −0 lib/excellent/template_handler.rb
  8. +24 −0 lib/excellent/xerb.rb
  9. +127 −0 lib/excellent/xhtml2xls.rb
2 .gitignore
@@ -0,0 +1,2 @@
+.idea
+.idea/**/*
0 README
No changes.
1 init.rb
@@ -0,0 +1 @@
+require 'excellent'
1 install.rb
@@ -0,0 +1 @@
+# Install hook code here
7 lib/excellent.rb
@@ -0,0 +1,7 @@
+require 'excellent/base_overrides'
+require 'excellent/template_handler'
+
+Mime::Type.register "application/vnd.ms-excel", :xls
+
+ActionView::Template.register_template_handler :xerb, ActionView::TemplateHandlers::XERB
+
10 lib/excellent/base_overrides.rb
@@ -0,0 +1,10 @@
+#Changes keys of hash accordig to given map
+# >> {:a => 10, :c => 20}.map_keys({:a => :b})
+# => {:c=>20, :b=>10}
+class Hash
+ def map_keys(hsh)
+ returning Hash.new do |r|
+ each{|k,v| r[hsh[k] || k] = v}
+ end
+ end
+end
1 lib/excellent/template_handler.rb
@@ -0,0 +1 @@
+require 'excellent/xerb'
24 lib/excellent/xerb.rb
@@ -0,0 +1,24 @@
+#require 'erb'
+require 'excellent/xhtml2xls'
+
+module ActionView
+ module TemplateHandlers
+ class XERB < ERB
+ include Compilable
+
+ cattr_accessor :erb_trim_mode
+ self.erb_trim_mode = '-'
+
+ def compile(template)
+ src = %{
+ ts = %{#{template.source}}
+ xhtml = self.render(:inline => ts, :type => :erb )
+ h2x = Hsh2Xls.new(xhtml)
+ h2x.output
+ }
+
+ RUBY_VERSION >= '1.9' ? src.sub(/\A#coding:.*\n/, '') : src
+ end
+ end
+ end
+end
127 lib/excellent/xhtml2xls.rb
@@ -0,0 +1,127 @@
+
+
+class XlsCellStyle
+ attr_reader :raw_style, :style
+
+ ATTRIBUTES_MAP = {
+ "font-weight" => :weight,
+ "color" => :color,
+ "font-size" => :size
+ }
+
+ def initialize(style)
+ return nil unless style
+ @raw_style = style.gsub(' ','')
+ @style = Spreadsheet::Format.new(style2hsh)
+ end
+
+ def style2hsh
+ attrs = @raw_style.split(';')
+ attrs.inject({}){|acc, attr| acc.merge(encode_attribute(attr))}
+ end
+
+ def encode_attribute(attribute)
+ attr,value = attribute.split(':')
+
+ value = case attr
+ when "color" then value.to_sym
+ when "font-size" then value.to_i
+ when "font-weight" then value.to_sym
+ end
+
+ return Hash[attr,value].map_keys(ATTRIBUTES_MAP)
+ end
+
+end
+
+class XlsCell
+
+ attr_reader :data
+
+ def initialize(cell,kind='normal')
+ if cell.is_a? Hash
+ cell.symbolize_keys!
+ @data = cell[:content] || ''
+ @style = XlsCellStyle.new(cell[:style])
+ else
+ @data = cell || ''
+ @style = nil
+ end
+ end
+
+ def style
+ @style ? @style.style : nil
+ end
+
+end
+
+class XlsRow
+ attr_reader :cells
+
+ def initialize(row)
+ kind = row.keys.include?(:th) ? 'header' : 'normal'
+ @cells = row.values.sum.map{|c| XlsCell.new(c,kind)}
+ end
+
+end
+
+class XlsTable
+ attr_reader :rows
+
+ def initialize(hsh)
+ @rows = hsh[:tr].map{|tr| XlsRow.new(tr)}
+ end
+
+end
+
+class Hsh2Xls
+ require 'spreadsheet'
+ require 'xmlsimple'
+
+ attr_reader :xhtml
+
+ REQUIRED_FIRST_LEVEL_KEYS = [:name, :tr]
+
+ def initialize(xhtml)
+ @xhtml = xhtml
+ @hsh = XmlSimple.xml_in(@xhtml, {'ForceArray' => true}).symbolize_keys
+ validate_hash
+ end
+
+ private
+
+ def validate_hash
+ #TODO To rewrite
+ raise "Table has to have 'name' attribute and a set of rows" if !(REQUIRED_FIRST_LEVEL_KEYS-@hsh.keys ).empty?
+ raise "tr is to be array" unless @hsh[:tr].kind_of?(Array)
+ end
+
+ def render_xls
+ xls = Spreadsheet::Workbook.new
+ @sheet = xls.create_worksheet :name => @hsh[:name]
+
+ xls_table = XlsTable.new(@hsh)
+
+ xls_table.rows.each_with_index do |row, row_idx|
+ row.cells.each_with_index do |cell, cell_idx|
+ render_cell(row_idx, cell_idx, cell)
+ end
+ end
+
+ xls_output = StringIO.new
+ xls.write xls_output
+ return xls_output.string
+ end
+
+ def render_cell(row_idx, cell_idx, cell)
+ @sheet.row(row_idx).set_format(cell_idx, cell.style) if cell.style
+ @sheet[row_idx, cell_idx] = cell.data
+ end
+
+ public
+
+ def output
+ render_xls
+ end
+
+end

0 comments on commit 75a1d34

Please sign in to comment.