diff options
| author | Randy Morgan <[email protected]> | 2012-04-23 09:38:49 +0900 |
|---|---|---|
| committer | Randy Morgan <[email protected]> | 2012-04-23 09:38:49 +0900 |
| commit | 372fb7b2fe3408e8aab9b1b4ae5285aa98a8a945 (patch) | |
| tree | 1a67fcc7cd7135fb6da182ddee06e094f2ff6540 /lib/axlsx/stylesheet/styles.rb | |
| parent | 050f4cfac1b3a52da16b98f3a494083f0de5348f (diff) | |
| download | caxlsx-372fb7b2fe3408e8aab9b1b4ae5285aa98a8a945.tar.gz caxlsx-372fb7b2fe3408e8aab9b1b4ae5285aa98a8a945.zip | |
first stage refactoring for Style#add_style [inprogress]
Diffstat (limited to 'lib/axlsx/stylesheet/styles.rb')
| -rw-r--r-- | lib/axlsx/stylesheet/styles.rb | 158 |
1 files changed, 94 insertions, 64 deletions
diff --git a/lib/axlsx/stylesheet/styles.rb b/lib/axlsx/stylesheet/styles.rb index 499657ca..f988df95 100644 --- a/lib/axlsx/stylesheet/styles.rb +++ b/lib/axlsx/stylesheet/styles.rb @@ -14,7 +14,7 @@ module Axlsx require 'axlsx/stylesheet/table_style.rb' require 'axlsx/stylesheet/table_styles.rb' require 'axlsx/stylesheet/table_style_element.rb' - require 'axlsx/stylesheet/dxf.rb' + require 'axlsx/stylesheet/dxf.rb' require 'axlsx/stylesheet/xf.rb' require 'axlsx/stylesheet/cell_protection.rb' @@ -205,7 +205,7 @@ module Axlsx # profitable = wb.styles.add_style(:bg_color => "FFFF0000", # :fg_color=>"#FF000000", # :type => :dxf) - # + # # ws.add_row :values => ["Genreated At:", Time.now], :styles=>[nil, date_time] # ws.add_row :values => ["Previous Year Quarterly Profits (JPY)"], :style=>title # ws.add_row :values => ["Quarter", "Profit", "% of Total"], :style=>title @@ -213,7 +213,7 @@ module Axlsx # ws.add_row :values => ["Q2", 3000, 30], :style=>[title, currency, percent] # ws.add_row :values => ["Q3", 1000, 10], :style=>[title, currency, percent] # ws.add_row :values => ["Q4", 2000, 20], :style=>[title, currency, percent] - # + # # ws.add_conditional_formatting("A1:A7", { :type => :cellIs, :operator => :greaterThan, :formula => "2000", :dxfId => profitable, :priority => 1 }) # f = File.open('example_differential_styling', 'w') # p.serialize(f) @@ -222,74 +222,26 @@ module Axlsx # Default to :xf options[:type] ||= :xf raise ArgumentError, "Type must be one of [:xf, :dxf]" unless [:xf, :dxf].include?(options[:type] ) - - numFmt = if options[:format_code] - n = @numFmts.map{ |f| f.numFmtId }.max + 1 - NumFmt.new(:numFmtId => n, :formatCode=> options[:format_code]) - elsif options[:type] == :xf - options[:num_fmt] || 0 - elsif options[:type] == :dxf and options[:num_fmt] - raise ArgumentError, "Can't use :num_fmt with :dxf" - end - - border = options[:border] - - if border.is_a?(Hash) - raise ArgumentError, "border hash definitions must include both style and color" unless border.keys.include?(:style) && border.keys.include?(:color) - - s = border[:style] - c = border[:color] - edges = border[:edges] || [:left, :right, :top, :bottom] - - border = Border.new - edges.each {|pr| border.prs << BorderPr.new(:name => pr, :style=>s, :color => Color.new(:rgb => c))} - elsif border.is_a? Integer - raise ArgumentError, "Must pass border options directly if specifying dxf" if options[:type] == :dxf - raise ArgumentError, "Invalid borderId" unless border < borders.size - end - - fill = if options[:bg_color] - color = Color.new(:rgb=>options[:bg_color]) - pattern = PatternFill.new(:patternType =>:solid, :fgColor=>color) - Fill.new(pattern) - end - - font = if (options.values_at(:fg_color, :sz, :b, :i, :u, :strike, :outline, :shadow, :charset, :family, :font_name).length) - font = Font.new() - [:b, :i, :u, :strike, :outline, :shadow, :charset, :family, :sz].each { |k| font.send("#{k}=", options[k]) unless options[k].nil? } - font.color = Color.new(:rgb => options[:fg_color]) unless options[:fg_color].nil? - font.name = options[:font_name] unless options[:font_name].nil? - font - end + numFmt = parse_num_fmt_options options applyProtection = (options[:hidden] || options[:locked]) ? 1 : 0 + border = parse_border_options options + fill = parse_fill_options options + font = parse_font_options options + alignment = parse_alignment_options options + protection = parse_protection_options options if options[:type] == :dxf - style = Dxf.new - style.fill = fill if fill - style.font = font if font - style.numFmt = numFmt if numFmt - style.border = border if border + style = Dxf.new :fill => fill, :font => font, :numFmt => numFmt, :border => border, :alignment => alignment, :protection => protection else # Only add styles if we're adding to Xf. They're embedded inside the Dxf pieces directly - fontId = font ? fonts << font : 0 - fillId = fill ? fills << fill : 0 # Default to borderId = 0 rather than no border - border ||= 0 - borderId = border.is_a?(Border) ? borders << border : border - numFmtId = numFmt.is_a?(NumFmt) ? numFmts << numFmt : numFmt - style = Xf.new(:fillId=>fillId, :fontId=>fontId, :applyFill=>1, :applyFont=>1, :numFmtId=>numFmtId, :borderId=>borderId, :applyProtection=>applyProtection) - style.applyNumberFormat = true if style.numFmtId > 0 - style.applyBorder = true if borderId > 0 - end - - if options[:alignment] - style.alignment = CellAlignment.new(options[:alignment]) - style.applyAlignment = true if style.is_a? Xf - end - - if applyProtection - style.protection = CellProtection.new(options) + borderId = border.is_a?(Border) ? borders << border : border || 0 + numFmtId = numFmt.is_a?(NumFmt) ? numFmt.numFmtId : options[:num_fmt] || 0 + numFmts << numFmt if numFmt.is_a?(NumFmt) + style = Xf.new(:fillId=>fill || 0, :fontId=>font || 0, :applyNumberFormat => 1, :applyFill=>1, :applyFont=>1, :numFmtId=>numFmtId, :borderId=>borderId, :applyProtection=>applyProtection, :applyBorder=>1, :alignment => alignment, :protection => protection) + style.applyAlignment = 1 if style.alignment + style.applyProtection = 1 if style.protection end if style.is_a? Dxf @@ -299,6 +251,84 @@ module Axlsx end end + def parse_protection_options(options={}) + CellProtection.new(options) if options[:hide] || options[:locked] + end + + def parse_alignment_options(options={}) + CellAlignment.new(options[:alignment]) if options[:alignment] + end + + def parse_font_options(options={}) + if (options.values_at(:fg_color, :sz, :b, :i, :u, :strike, :outline, :shadow, :charset, :family, :font_name).length) + # it would be better to pass a hash of what is allowed to the constructor and only set color and font name conditionally + font = Font.new() + [:b, :i, :u, :strike, :outline, :shadow, :charset, :family, :sz, :fg_color, :font_name].each do |key| + next if options[key].nil? + case key + when :fg_color + font.color = Color.new(:rgb => options[:fg_color]) + when :font_name + font.name = options[:font_name] + else + font.send("#{key}=", options[key]) + end + end + font = fonts << font if options[:type] != :dxf + end + end + + def parse_fill_options(options={}) + if options[:bg_color] + color = Color.new(:rgb=>options[:bg_color]) + pattern = PatternFill.new(:patternType =>:solid, :fgColor=>color) + fill = Fill.new(pattern) + fill = fills << fill if options[:type] != :dxf + fill + end + end + # parses Style#add_style options for borders. + # @option options [Hash|Integer] A border style definition hash. Border style definition hashes must include :style and color: key-value entries and may include an :edges entry that references an array of symbols identifying which border edges you wish to apply the style to. If the :edges entity is not provided the style is applied to all edges of cells that reference this style. + # @example + # #apply a thick red border to the top and bottom + # { :border => { :style => :thick, :color => "FFFF0000", :edges => [:top, :bottom] } + # When options is an Integer it is expected to reference a predefined border entry in styles and must be a valid index withing the Style#borders list. + # @note An error will be raised if you attempt to use an Integer border reference with a dxf style + # @return [Border|Integer|nil] + def parse_border_options(options={}) + b_opts = options[:border] + if b_opts.is_a?(Hash) + raise ArgumentError, (ERR_INVALID_BORDER_OPTIONS % b_opts) unless (b_opts.keys & [:style, :color]).size == 2 + border = Border.new + (b_opts[:edges] || [:left, :right, :top, :bottom]).each do |edge| + b_options = { :name => edge, :style => b_opts[:style], :color => Color.new(:rgb => b_opts[:color]) } + border.prs << BorderPr.new(b_options) + end + border + elsif b_opts.is_a? Integer + raise ArgumentError, (ERR_INVALID_BORDER_ID % b_opts) unless b_opts < borders.size + if options[:type] == :dxf + borders[b_opts].clone + else + border = b_opts + end + end + end + + # Parses Style#add_style options for number formatting. + # noop if neither :format_code or :num_format options are set. + # @option options [Hash] A hash describing the :format_code and/or :num_fmt integer for the style. + # @return [NumFmt|Integer] + def parse_num_fmt_options(options={}) + return unless options.values_at([:format_code,:num_fmt]).length + if options[:format_code] || (options[:type] == :dxf && options[:num_fmt]) + options[:num_fmt] ||= (@numFmts.map{ |num_fmt| num_fmt.numFmtId }.max + 1) if options[:type] != :dxf + NumFmt.new(:numFmtId => options[:num_fmt] || 0, :formatCode=> options[:format_code].to_s) + else + options[:num_fmt] + end + end + # Serializes the object # @param [String] str # @return [String] |
