Skip to content
Browse files

Use axlsx add_style for formatting

Simplified DSL context handling
Version bump to 1.0.1
  • Loading branch information...
1 parent 81e04d7 commit b6c0f02873e9cbe7616cf1f9c65adf3bbc19dddd @glebm committed Dec 4, 2012
View
1 Gemfile
@@ -10,4 +10,5 @@ group :test, :development do
gem 'haml'
gem 'RedCloth'
gem 'debugger', platform: :ruby
+ gem 'ruby-debug', platform: :jruby
end
View
6 lib/to_spreadsheet.rb
@@ -1,9 +1,7 @@
-require 'nokogiri'
-require 'to_spreadsheet/action_pack_renderers'
-require 'to_spreadsheet/mime_types'
require 'to_spreadsheet/version'
-require 'to_spreadsheet/helpers'
require 'to_spreadsheet/context'
+require 'to_spreadsheet/renderer'
+require 'to_spreadsheet/railtie' if defined?(Rails)
module ToSpreadsheet
class << self
View
20 lib/to_spreadsheet/context.rb
@@ -17,10 +17,26 @@ class << self
def global
@global ||= new
end
+
+ def current
+ Thread.current[:_to_spreadsheet_ctx]
+ end
+
+ def current=(ctx)
+ Thread.current[:_to_spreadsheet_ctx] = ctx
+ end
+
+ def with_context(ctx, &block)
+ old = current
+ self.current = ctx
+ r = block.call(ctx)
+ self.current = old
+ r
+ end
end
def initialize(wb_options = nil)
- @rules = []
+ @rules = []
workbook wb_options if wb_options
end
@@ -83,7 +99,7 @@ def add_rule(rule_type, selector_type, selector_value, options = {})
# A new context
def merge(other_context)
- ctx = Context.new()
+ ctx = Context.new()
ctx.rules = rules + other_context.rules
ctx
end
View
19 lib/to_spreadsheet/helpers.rb
@@ -1,19 +0,0 @@
-module ToSpreadsheet
- module Helpers
- def format_xls(selector = nil, &block)
- context.format_xls selector, &block
- end
-
- def context
- @context || ToSpreadsheet::Context.global
- end
-
- def with_context(context, &block)
- context_was = self.context
- @context = context
- result = block.call
- @context = context_was
- result
- end
- end
-end
View
56 lib/to_spreadsheet/action_pack_renderers.rb → ...preadsheet/rails/action_pack_renderers.rb
@@ -1,32 +1,24 @@
-require 'active_support'
-require 'action_controller/metal/renderers'
-require 'action_controller/metal/responder'
-
-require 'to_spreadsheet/renderer'
-
-# This will let us do thing like `render :xlsx => 'index'`
-# This is similar to how Rails internally implements its :json and :xml renderers
-ActionController::Renderers.add :xlsx do |template, options|
- filename = options[:filename] || options[:template] || 'data'
-
- html = with_context ToSpreadsheet::Context.global.merge(ToSpreadsheet::Context.new) do
- # local context
- @local_formats.each do |selector, &block|
- context.process_dsl selector, &block
- end if @local_formats
- render_to_string(options[:template], options)
- end
-
- data = ToSpreadsheet::Axlsx::Renderer.to_data(html)
- send_data data, type: :xlsx, disposition: %(attachment; filename="#{filename}.xlsx")
-end
-
-class ActionController::Responder
- # This sets up a default render call for when you do
- # respond_to do |format|
- # format.xlsx
- # end
- def to_xlsx
- controller.render xlsx: controller.action_name
- end
-end
+require 'active_support'
+require 'action_controller/metal/renderers'
+require 'action_controller/metal/responder'
+
+# This will let us do thing like `render :xlsx => 'index'`
+# This is similar to how Rails internally implements its :json and :xml renderers
+ActionController::Renderers.add :xlsx do |template, options|
+ filename = options[:filename] || options[:template] || 'data'
+ data = ToSpreadsheet::Context.with_context ToSpreadsheet::Context.global.merge(ToSpreadsheet::Context.new) do |context|
+ html = render_to_string(template, options.merge(template: template, formats: ['html']))
+ ToSpreadsheet::Renderer.to_data(html, context)
+ end
+ send_data data, type: :xlsx, disposition: %(attachment; filename="#{filename}.xlsx")
+end
+
+class ActionController::Responder
+ # This sets up a default render call for when you do
+ # respond_to do |format|
+ # format.xlsx
+ # end
+ def to_xlsx
+ controller.render xlsx: controller.action_name
+ end
+end
View
4 lib/to_spreadsheet/mime_types.rb → lib/to_spreadsheet/rails/mime_types.rb
@@ -1,2 +1,2 @@
-require 'action_dispatch/http/mime_type'
-Mime::Type.register "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", :xlsx unless Mime::Type.lookup_by_extension(:xlsx)
+require 'action_dispatch/http/mime_type'
+Mime::Type.register "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", :xlsx unless Mime::Type.lookup_by_extension(:xlsx)
View
11 lib/to_spreadsheet/rails/view_helpers.rb
@@ -0,0 +1,11 @@
+module ToSpreadsheet
+ module Rails
+ module ViewHelpers
+ def format_xls(selector = nil, &block)
+ ctx = ToSpreadsheet::Context.current
+ return unless ctx
+ ctx.format_xls selector, &block
+ end
+ end
+ end
+end
View
11 lib/to_spreadsheet/railtie.rb
@@ -0,0 +1,11 @@
+require 'rails/railtie'
+require 'to_spreadsheet/rails/mime_types'
+require 'to_spreadsheet/rails/action_pack_renderers'
+require 'to_spreadsheet/rails/view_helpers'
+module ToSpreadsheet
+ class Railtie < ::Rails::Railtie
+ initializer "to_spreadsheet.view_helpers" do
+ ActionView::Base.send :include, ToSpreadsheet::Rails::ViewHelpers
+ end
+ end
+end
View
30 lib/to_spreadsheet/renderer.rb
@@ -1,34 +1,30 @@
require 'axlsx'
+require 'nokogiri'
+
module ToSpreadsheet
module Renderer
extend self
- def to_stream(html, local_context = nil)
- to_package(html, local_context).to_stream
+ def to_stream(html, context = nil)
+ to_package(html, context).to_stream
end
- def to_data(html, local_context = nil)
- to_package(html, local_context).to_stream.read
+ def to_data(html, context = nil)
+ to_package(html, context).to_stream.read
end
- def to_package(html, local_context = nil)
- with_context init_context(local_context) do
- package = build_package(html, context)
- context.rules.each do |rule|
- puts "Applying #{rule}"
- rule.apply(context, package)
- end
- package
+ def to_package(html, context = nil)
+ context ||= ToSpreadsheet::Context.global.merge(Context.new)
+ package = build_package(html, context)
+ context.rules.each do |rule|
+ #Rails.logger.debug "Applying #{rule}"
+ rule.apply(context, package)
end
+ package
end
private
- def init_context(local_context)
- local_context ||= ToSpreadsheet::Context.new
- ToSpreadsheet::Context.global.merge local_context
- end
-
def build_package(html, context)
package = ::Axlsx::Package.new
spreadsheet = package.workbook
View
21 lib/to_spreadsheet/rule/format.rb
@@ -5,10 +5,11 @@ module Rule
class Format < Base
include ::ToSpreadsheet::TypeFromValue
def apply(context, sheet)
+ wb = sheet.workbook
case selector_type
when :css
css_match selector_query, context.to_xml_node(sheet) do |xml_node|
- apply_inline_styles context, context.to_xls_entity(xml_node)
+ add_and_apply_style wb, context, context.to_xls_entity(xml_node)
end
when :row
sheet.row_style selector_query, options if options.present?
@@ -17,7 +18,7 @@ def apply(context, sheet)
sheet.col_style selector_query, inline_styles if inline_styles.present?
apply_col_info sheet.column_info[selector_query]
when :range
- apply_inline_styles range_match(selector_type, sheet), context
+ add_and_apply_style wb, range_match(selector_type, sheet), context
end
end
@@ -32,7 +33,7 @@ def apply_col_info(col_info)
end
end
- def apply_inline_styles(context, xls_ent)
+ def add_and_apply_style(wb, context, xls_ent)
# Custom format rule
# format 'td.sel', lambda { |node| ...}
if self.options.is_a?(Proc)
@@ -47,17 +48,9 @@ def apply_inline_styles(context, xls_ent)
options[k] = context.instance_exec(xls_ent, &v) if v.is_a?(Proc)
end
- # Apply inline styles
- options.each do |k, v|
- next if v.nil?
- setter = :"#{k}="
- xls_ent.send setter, v if xls_ent.respond_to?(setter)
- if xls_ent.respond_to?(:cells)
- xls_ent.cells.each do |cell|
- cell.send setter, v if cell.respond_to?(setter)
- end
- end
- end
+ style = wb.styles.add_style options
+ cells = xls_ent.respond_to?(:cells) ? xls_ent.cells : [xls_ent]
+ cells.each { |cell| cell.style = style }
end
end
end
View
6 lib/to_spreadsheet/version.rb
@@ -1,3 +1,3 @@
-module ToSpreadsheet
- VERSION = '1.0.0'
-end
+module ToSpreadsheet
+ VERSION = '1.0.1'
+end
View
7 spec/format_spec.rb
@@ -6,7 +6,7 @@
:ruby
format_xls do
format column: 0, width: 25
- format 'tr', color: lambda { |row| 'cccccc' if row.index.odd? }
+ format 'tr', fg_color: lambda { |row| 'cccccc' if row.index.odd? }
end
%table
%tr
@@ -23,7 +23,10 @@
sheet.column_info[0].width.should == 25
end
it 'runs lambdas' do
- sheet.rows[1].cells[0].color.rgb.should == Axlsx::Color.new(rgb: 'cccccc').rgb
+ cell = sheet.rows[1].cells[0]
+ styles = sheet.workbook.styles
+ font_id = styles.cellXfs[cell.style].fontId
+ styles.fonts[font_id].color.rgb.should == Axlsx::Color.new(rgb: 'cccccc').rgb
end
end
end
View
27 spec/spec_helper.rb
@@ -4,15 +4,24 @@
require 'to_spreadsheet'
require 'haml'
-RSpec.configure do |config|
- include ToSpreadsheet::Helpers
+
+module TestRendering
+ def build_spreadsheet(src = {})
+ haml = if src[:haml]
+ src[:haml]
+ elsif src[:file]
+ File.read(File.expand_path "support/#{src[:file]}", File.dirname(__FILE__))
+ end
+ ToSpreadsheet::Context.with_context ToSpreadsheet::Context.global.merge(ToSpreadsheet::Context.new) do |context|
+ html = Haml::Engine.new(haml).render(self)
+ ToSpreadsheet::Renderer.to_package(html, context)
+ end
+ end
end
-def build_spreadsheet(src = {})
- haml = if src[:haml]
- src[:haml]
- elsif src[:file]
- File.read(File.expand_path "support/#{src[:file]}", File.dirname(__FILE__))
- end
- ToSpreadsheet::Renderer.to_package(Haml::Engine.new(haml).render)
+
+require 'to_spreadsheet/rails/view_helpers'
+RSpec.configure do |config|
+ include TestRendering
+ include ::ToSpreadsheet::Rails::ViewHelpers
end

0 comments on commit b6c0f02

Please sign in to comment.
Something went wrong with that request. Please try again.