Class: Axlsx::Styles

Inherits:
Object
  • Object
show all
Defined in:
lib/axlsx/stylesheet/styles.rb

Overview

Note:

The recommended way to manage styles is with add_style

The Styles class manages worksheet styles In addition to creating the require style objects for a valid xlsx package, this class provides the key mechanism for adding styles to your workbook, and safely applying them to the cells of your worksheet. All portions of the stylesheet are implemented here exception colors, which specify legacy and modified pallete colors, and exLst, whic is used as a future feature data storage area.

See Also:

  • Open XML Part 1 18.8.11 for gory details on how this stuff gets put together
  • #add_style

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeStyles

Creates a new Styles object and prepopulates it with the requires objects to generate a valid package style part.



119
120
121
# File 'lib/axlsx/stylesheet/styles.rb', line 119

def initialize()
  load_default_styles
end

Instance Attribute Details

#bordersSimpleTypedList (readonly)

Note:

The recommended way to manage styles is with add_style

The collection of borders used in this workbook Axlsx predefines THIN_BORDER which can be used to put a border around all of your cells.

Returns:

  • (SimpleTypedList)

See Also:



86
87
88
# File 'lib/axlsx/stylesheet/styles.rb', line 86

def borders
  @borders
end

#cellStylesSimpleTypedList (readonly)

Note:

The recommended way to manage styles is with add_style

The collection of named styles, referencing cellStyleXfs items in the workbook.

Returns:

  • (SimpleTypedList)

See Also:



98
99
100
# File 'lib/axlsx/stylesheet/styles.rb', line 98

def cellStyles
  @cellStyles
end

#cellStyleXfsSimpleTypedList (readonly)

Note:

The recommended way to manage styles is with add_style

The collection of master formatting records for named cell styles, which means records defined in cellStyles, in the workbook

Returns:

  • (SimpleTypedList)

See Also:



92
93
94
# File 'lib/axlsx/stylesheet/styles.rb', line 92

def cellStyleXfs
  @cellStyleXfs
end

#cellXfsSimpleTypedList (readonly)

Note:

The recommended way to manage styles is with add_style

The collection of master formatting records. This is the list that you will actually use in styling a workbook.

Returns:

  • (SimpleTypedList)

See Also:



104
105
106
# File 'lib/axlsx/stylesheet/styles.rb', line 104

def cellXfs
  @cellXfs
end

#dxfsSimpleTypedList (readonly)

Note:

The recommended way to manage styles is with add_style

The collection of non-cell formatting records used in the worksheet.

Returns:

  • (SimpleTypedList)

See Also:



110
111
112
# File 'lib/axlsx/stylesheet/styles.rb', line 110

def dxfs
  @dxfs
end

#fillsSimpleTypedList (readonly)

Note:

The recommended way to manage styles is with add_style

The collection of fills used in this workbook

Returns:

  • (SimpleTypedList)

See Also:



79
80
81
# File 'lib/axlsx/stylesheet/styles.rb', line 79

def fills
  @fills
end

#fontsSimpleTypedList (readonly)

Note:

The recommended way to manage styles is with add_style

The collection of fonts used in this workbook

Returns:

  • (SimpleTypedList)

See Also:



73
74
75
# File 'lib/axlsx/stylesheet/styles.rb', line 73

def fonts
  @fonts
end

#numFmtsSimpleTypedList (readonly)

Note:

The recommended way to manage styles is with add_style

numFmts for your styles. The default styles, which change based on the system local, are as follows. id formatCode 0 General 1 0 2 0.00 3 #,##0 4 #,##0.00 9 0% 10 0.00% 11 0.00E+00 12 # ?/? 13 # ??/?? 14 mm-dd-yy 15 d-mmm-yy 16 d-mmm 17 mmm-yy 18 h:mm AM/PM 19 h:mm:ss AM/PM 20 h:mm 21 h:mm:ss 22 m/d/yy h:mm 37 #,##0 ;(#,##0) 38 #,##0 ;Red 39 #,##0.00;(#,##0.00) 40 #,##0.00;Red 45 mm:ss 46 [h]:mm:ss 47 mmss.0 48 ##0.0E+0 49 @ Axlsx also defines the following constants which you can use in add_style. NUM_FMT_PERCENT formats to "0%" NUM_FMT_YYYYMMDD formats to "yyyy/mm/dd" NUM_FMT_YYYYMMDDHHMMSS formats to "yyyy/mm/dd hh:mm:ss"

Returns:

  • (SimpleTypedList)

See Also:

  • Open XML Part 1 - 18.8.31 for more information on creating number formats
  • #add_style


67
68
69
# File 'lib/axlsx/stylesheet/styles.rb', line 67

def numFmts
  @numFmts
end

#tableStylesSimpleTypedList (readonly)

Note:

The recommended way to manage styles is with add_style

The collection of table styles that will be available to the user in the excel UI

Returns:

  • (SimpleTypedList)

See Also:



116
117
118
# File 'lib/axlsx/stylesheet/styles.rb', line 116

def tableStyles
  @tableStyles
end

Instance Method Details

#add_style(options = {}) ⇒ Integer

Drastically simplifies style creation and management.

Examples:

You Got Style

require "rubygems" # if that is your preferred way to manage gems!
require "axlsx"

p = Axlsx::Package.new
ws = p.workbook.add_worksheet

# black text on a white background at 14pt with thin borders!
title = ws.style.add_style(:bg_color => "FFFF0000", :fg_color=>"#FF000000", :sz=>14,  :border=> {:style => :thin, :color => "FFFF0000"}

ws.add_row ["Least Popular Pets"]
ws.add_row ["", "Dry Skinned Reptiles", "Bald Cats", "Violent Parrots"], :style=>title
ws.add_row ["Votes", 6, 4, 1], :style=>Axlsx::STYLE_THIN_BORDER
f = File.open('example_you_got_style.xlsx', 'w')
p.serialize(f)

Styling specifically

# an example of applying specific styles to specific cells
require "rubygems" # if that is your preferred way to manage gems!
require "axlsx"

p = Axlsx::Package.new
ws = p.workbook.add_worksheet

# define your styles
title = ws.style.add_style(:bg_color => "FFFF0000",
                           :fg_color=>"#FF000000",
                           :border=>Axlsx::STYLE_THIN_BORDER,
                           :alignment=>{:horizontal => :center})

date_time = ws.style.add_style(:num_fmt => Axlsx::NUM_FMT_YYYYMMDDHHMMSS,
                               :border=>Axlsx::STYLE_THIN_BORDER)

percent = ws.style.add_style(:num_fmt => Axlsx::NUM_FMT_PERCENT,
                             :border=>Axlsx::STYLE_THIN_BORDER)

currency = ws.style.add_style(:format_code=>"¥#,##0;[Red]¥-#,##0",
                              :border=>Axlsx::STYLE_THIN_BORDER)

# build your rows
ws.add_row ["Generated At:", Time.now], :styles=>[nil, date_time]
ws.add_row ["Previous Year Quarterly Profits (JPY)"], :style=>title
ws.add_row ["Quarter", "Profit", "% of Total"], :style=>title
ws.add_row ["Q1", 4000, 40], :style=>[title, currency, percent]
ws.add_row ["Q2", 3000, 30], :style=>[title, currency, percent]
ws.add_row ["Q3", 1000, 10], :style=>[title, currency, percent]
ws.add_row ["Q4", 2000, 20], :style=>[title, currency, percent]
f = File.open('example_you_got_style.xlsx', 'w')
p.serialize(f)

Differential styling

# Differential styles apply on top of cell styles. Used in Conditional Formatting. Must specify :type => :dxf, and you can't use :num_fmt.
require "rubygems" # if that is your preferred way to manage gems!
require "axlsx"

p = Axlsx::Package.new
wb = p.workbook
ws = wb.add_worksheet

# define your styles
profitable = wb.styles.add_style(:bg_color => "FFFF0000",
                           :fg_color=>"#FF000000",
                           :type => :dxf)

ws.add_row ["Genreated At:", Time.now], :styles=>[nil, date_time]
ws.add_row ["Previous Year Quarterly Profits (JPY)"], :style=>title
ws.add_row ["Quarter", "Profit", "% of Total"], :style=>title
ws.add_row ["Q1", 4000, 40], :style=>[title, currency, percent]
ws.add_row ["Q2", 3000, 30], :style=>[title, currency, percent]
ws.add_row ["Q3", 1000, 10], :style=>[title, currency, percent]
ws.add_row ["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)

Parameters:

  • options (Hash) (defaults to: {})

    a customizable set of options

Options Hash (options):

  • fg_color (String)

    The text color

  • sz (Integer)

    The text size

  • b (Boolean)

    Indicates if the text should be bold

  • i (Boolean)

    Indicates if the text should be italicised

  • u (Boolean)

    Indicates if the text should be underlined

  • strike (Boolean)

    Indicates if the text should be rendered with a strikethrough

  • strike (Boolean)

    Indicates if the text should be rendered with a shadow

  • charset (Integer)

    The character set to use.

  • family (Integer)

    The font family to use.

  • font_name (String)

    The name of the font to use

  • num_fmt (Integer)

    The number format to apply

  • format_code (String)

    The formatting to apply.

  • border (Integer|Hash)

    The border style to use. borders support style, color and edges options @see parse_border_options

  • bg_color (String)

    The background color to apply to the cell

  • hidden (Boolean)

    Indicates if the cell should be hidden

  • locked (Boolean)

    Indicates if the cell should be locked

  • type (Symbol)

    What type of style is this. Options are [:dxf, :xf]. :xf is default

  • alignment (Hash)

    A hash defining any of the attributes used in CellAlignment

Returns:

  • (Integer)

Raises:

  • (ArgumentError)

See Also:



222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
# File 'lib/axlsx/stylesheet/styles.rb', line 222

def add_style(options={})
  # Default to :xf
  options[:type] ||= :xf
  raise ArgumentError, "Type must be one of [:xf, :dxf]" unless [:xf, :dxf].include?(options[:type] )

  fill = parse_fill_options options
  font = parse_font_options options
  numFmt = parse_num_fmt_options options
  border = parse_border_options options
  alignment = parse_alignment_options options
  protection = parse_protection_options options

  case options[:type]
  when :dxf
    style = Dxf.new :fill => fill, :font => font, :numFmt => numFmt, :border => border, :alignment => alignment, :protection => protection
  else
    style = Xf.new :fillId=>fill || 0, :fontId=>font || 0, :numFmtId=>numFmt || 0, :borderId=>border || 0, :alignment => alignment, :protection => protection, :applyFill=>!fill.nil?, :applyFont=>!font.nil?, :applyNumberFormat =>!numFmt.nil?, :applyBorder=>!border.nil?, :applyAlignment => !alignment.nil?, :applyProtection => !protection.nil?
  end

  options[:type] == :xf ? cellXfs << style : dxfs << style
end

#parse_alignment_options(options = {}) ⇒ CellAlignment

parses add_style options for alignment noop if options hash does not include :alignment key

Parameters:

  • options (Hash) (defaults to: {})

    a customizable set of options

Options Hash (options):

  • alignment (Hash)

    A hash of options to prive the CellAlignment intializer

Returns:

See Also:



260
261
262
263
# File 'lib/axlsx/stylesheet/styles.rb', line 260

def parse_alignment_options(options={})
  return unless options[:alignment]
  CellAlignment.new options[:alignment]
end

#parse_border_options(options = {}) ⇒ Border|Integer

Examples:

#apply a thick red border to the top and bottom
{ :border => { :style => :thick, :color => "FFFF0000", :edges => [:top, :bottom] }

Returns:



319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
# File 'lib/axlsx/stylesheet/styles.rb', line 319

def parse_border_options(options={})
  return unless options[:border]
  b_opts = options[:border]
  if b_opts.is_a?(Hash)
    raise ArgumentError, (ERR_INVALID_BORDER_OPTIONS % b_opts) unless b_opts.keys.include?(:style) && b_opts.keys.include?(:color)
    border = Border.new b_opts
    (b_opts[:edges] || [:left, :right, :top, :bottom]).each do |edge|
      edge_options = options["border_#{edge}".to_sym] || {}
      border_edge = b_opts.merge(edge_options)
      b_options = { :name => edge, :style => border_edge[:style], :color => Color.new(:rgb => border_edge[:color]) }
      border.prs << BorderPr.new(b_options)
    end
    options[:type] == :dxf ? border : borders << 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

#parse_fill_options(options = {}) ⇒ Fill|Integer

Note:

noop if :bg_color is not specified in options

parses add_style options for fills. If the options hash contains :type => :dxf we return a Fill object. If not, we return the index of the fill after being added to the fills collection.

Parameters:

  • options (Hash) (defaults to: {})

    a customizable set of options

Options Hash (options):

  • bg_color (String)

    The rgb color to apply to the fill

Returns:



296
297
298
299
300
301
302
303
304
# File 'lib/axlsx/stylesheet/styles.rb', line 296

def parse_fill_options(options={})
  return unless options[:bg_color]
  color = Color.new(:rgb=>options[:bg_color])
  dxf = options[:type] == :dxf
  color_key = dxf ? :bgColor : :fgColor
  pattern = PatternFill.new(:patternType =>:solid, color_key=>color)
  fill = Fill.new(pattern)
  dxf ? fill : fills << fill
end

#parse_font_options(options = {}) ⇒ Font|Integer

Note:

noop if none of the options described here are set on the options parameter.

parses add_style options for fonts. If the options hash contains :type => :dxf we return a new Font object. if not, we return the index of the newly created font object in the styles.fonts collection.

Parameters:

  • options (Hash) (defaults to: {})

    a customizable set of options

Options Hash (options):

  • type (Symbol)

    The type of style object we are working with (dxf or xf)

  • fg_color (String)

    The text color

  • sz (Integer)

    The text size

  • b (Boolean)

    Indicates if the text should be bold

  • i (Boolean)

    Indicates if the text should be italicised

  • u (Boolean)

    Indicates if the text should be underlined

  • strike (Boolean)

    Indicates if the text should be rendered with a strikethrough

  • outline (Boolean)

    Indicates if the text should be rendered with a shadow

  • charset (Integer)

    The character set to use.

  • family (Integer)

    The font family to use.

  • font_name (String)

    The name of the font to use

Returns:



280
281
282
283
284
285
286
287
288
289
290
# File 'lib/axlsx/stylesheet/styles.rb', line 280

def parse_font_options(options={})
  return if (options.keys & [:fg_color, :sz, :b, :i, :u, :strike, :outline, :shadow, :charset, :family, :font_name]).empty?
  fonts.first.instance_values.each do |key, value|
    # Thanks for that 1.8.7 - cant do a simple merge...
    options[key.to_sym] = value unless options.keys.include?(key.to_sym)
  end
  font = Font.new(options)
  font.color = Color.new(:rgb => options[:fg_color]) if options[:fg_color]
  font.name = options[:font_name] if options[:font_name]
  options[:type] == :dxf ? font : fonts << font
end

#parse_num_fmt_options(options = {}) ⇒ NumFmt|Integer

Parses Style#add_style options for number formatting. noop if neither :format_code or :num_format options are set.

Parameters:

  • options (Hash) (defaults to: {})

    a customizable set of options

Options Hash (options):

  • A (Hash)

    hash describing the :format_code and/or :num_fmt integer for the style.

Returns:



346
347
348
349
350
351
352
353
354
355
356
357
358
359
# File 'lib/axlsx/stylesheet/styles.rb', line 346

def parse_num_fmt_options(options={})
  return if (options.keys & [:format_code, :num_fmt]).empty?

  #When the user provides format_code - we always need to create a new numFmt object
  #When the type is :dxf we always need to create a new numFmt object
  if options[:format_code] || options[:type] == :dxf
    #If this is a standard xf we pull from numFmts the highest current and increment for num_fmt
    options[:num_fmt] ||= (@numFmts.map{ |num_fmt| num_fmt.numFmtId }.max + 1) if options[:type] != :dxf
    numFmt = NumFmt.new(:numFmtId => options[:num_fmt] || 0, :formatCode=> options[:format_code].to_s)
    options[:type] == :dxf ? numFmt : (numFmts << numFmt; numFmt.numFmtId)
  else
    options[:num_fmt]
  end
end

#parse_protection_options(options = {}) ⇒ CellProtection

Parameters:

  • options (Hash) (defaults to: {})

    a customizable set of options

Options Hash (options):

  • hide (Boolean)

    boolean value defining cell protection attribute for hiding.

  • locked (Boolean)

    boolean value defining cell protection attribute for locking.

Returns:



250
251
252
253
# File 'lib/axlsx/stylesheet/styles.rb', line 250

def parse_protection_options(options={})
  return if (options.keys & [:hidden, :locked]).empty?
  CellProtection.new(options)
end

#to_xml_string(str = '') ⇒ String

Serializes the object

Parameters:

  • str (String) (defaults to: '')

Returns:

  • (String)


364
365
366
367
368
369
370
# File 'lib/axlsx/stylesheet/styles.rb', line 364

def to_xml_string(str = '')
  str << '<styleSheet xmlns="' << XML_NS << '">'
  [:numFmts, :fonts, :fills, :borders, :cellStyleXfs, :cellXfs, :cellStyles, :dxfs, :tableStyles].each do |key|
    self.instance_values[key.to_s].to_xml_string(str) unless self.instance_values[key.to_s].nil?
  end
  str << '</styleSheet>'
end