Class: Xlsxrb::StyleBuilder

Inherits:
Object
  • Object
show all
Defined in:
lib/xlsxrb/style_builder.rb,
sig/generated/xlsxrb/style_builder.rbs

Overview

Helper class for building cell styles with a fluent DSL. Encapsulates font, fill, border, alignment, and number format properties.

Constant Summary collapse

COLORS =

Returns:

  • (Object)
{
  black: "FF000000",
  white: "FFFFFFFF",
  red: "FFFF0000",
  green: "FF00FF00",
  blue: "FF0000FF",
  yellow: "FFFFFF00",
  cyan: "FF00FFFF",
  magenta: "FFFF00FF",
  gray: "FF808080",
  grey: "FF808080"
}.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name = nil) ⇒ StyleBuilder

: (?String? name) -> void

Parameters:

  • name (Object) (defaults to: nil)


33
34
35
36
37
38
39
40
# File 'lib/xlsxrb/style_builder.rb', line 33

def initialize(name = nil)
  @name = name
  @font_props = {}
  @fill_props = {}
  @border_props = {}
  @num_fmt_id = nil
  @alignment = {}
end

Instance Attribute Details

#alignmentObject (readonly)

Returns the value of attribute alignment.

Returns:

  • (Object)


42
43
44
# File 'lib/xlsxrb/style_builder.rb', line 42

def alignment
  @alignment
end

#border_propsObject (readonly)

Returns the value of attribute border_props.

Returns:

  • (Object)


42
43
44
# File 'lib/xlsxrb/style_builder.rb', line 42

def border_props
  @border_props
end

#fill_propsObject (readonly)

Returns the value of attribute fill_props.

Returns:

  • (Object)


42
43
44
# File 'lib/xlsxrb/style_builder.rb', line 42

def fill_props
  @fill_props
end

#font_propsObject (readonly)

Returns the value of attribute font_props.

Returns:

  • (Object)


42
43
44
# File 'lib/xlsxrb/style_builder.rb', line 42

def font_props
  @font_props
end

#nameObject (readonly)

Returns the value of attribute name.

Returns:

  • (Object)


42
43
44
# File 'lib/xlsxrb/style_builder.rb', line 42

def name
  @name
end

#num_fmt_idObject (readonly)

Returns the value of attribute num_fmt_id.

Returns:

  • (Object)


42
43
44
# File 'lib/xlsxrb/style_builder.rb', line 42

def num_fmt_id
  @num_fmt_id
end

Instance Method Details

#align_horizontal(value) ⇒ Object

: (String | Symbol value) -> self

Parameters:

  • value (Object)

Returns:

  • (Object)


286
287
288
289
# File 'lib/xlsxrb/style_builder.rb', line 286

def align_horizontal(value)
  @alignment[:horizontal] = value
  self
end

#align_vertical(value) ⇒ Object

: (String | Symbol value) -> self

Parameters:

  • value (Object)

Returns:

  • (Object)


292
293
294
295
# File 'lib/xlsxrb/style_builder.rb', line 292

def align_vertical(value)
  @alignment[:vertical] = value
  self
end

#apply_options!(**opts) ⇒ Object

Applies option-style definitions so callers can use add_style(name, **opts) as an alternative to block-based fluent chaining.

Parameters:

  • opts (Object)

Returns:

  • (Object)


47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/xlsxrb/style_builder.rb', line 47

def apply_options!(**opts)
  if opts.key?(:font)
    font_opts = opts[:font] || {}
    bold(font_opts[:bold]) if font_opts.key?(:bold)
    italic(font_opts[:italic]) if font_opts.key?(:italic)
    size(font_opts[:size]) if font_opts.key?(:size)
    font_name(font_opts[:name]) if font_opts.key?(:name)
    font_color(font_opts[:color]) if font_opts.key?(:color)
    underline(font_opts[:underline]) if font_opts.key?(:underline)
    strike(font_opts[:strike]) if font_opts.key?(:strike)
    vert_align(font_opts[:vert_align]) if font_opts.key?(:vert_align)
  else
    bold(opts[:bold]) if opts.key?(:bold)
    italic(opts[:italic]) if opts.key?(:italic)
    size(opts[:size]) if opts.key?(:size)
    font_name(opts[:font_name]) if opts.key?(:font_name)
    font_color(opts[:font_color]) if opts.key?(:font_color)
    underline(opts[:underline]) if opts.key?(:underline)
    strike(opts[:strike]) if opts.key?(:strike)
    vert_align(opts[:vert_align]) if opts.key?(:vert_align)
  end

  if opts.key?(:fill)
    fill_opts = opts[:fill] || {}
    if fill_opts.key?(:color)
      fill_color(fill_opts[:color])
    else
      fill_pattern(
        fill_opts[:pattern] || "solid",
        fg_color: fill_opts[:fg_color],
        bg_color: fill_opts[:bg_color]
      )
    end
  else
    fill_color(opts[:fill_color]) if opts.key?(:fill_color)
    if opts.key?(:fill_pattern)
      pattern = opts[:fill_pattern] || {}
      fill_pattern(
        pattern[:pattern] || "solid",
        fg_color: pattern[:fg_color],
        bg_color: pattern[:bg_color]
      )
    end
  end
  fill_gradient(**opts[:fill_gradient]) if opts.key?(:fill_gradient) && opts[:fill_gradient]

  if opts.key?(:border)
    border_opts = opts[:border] || {}
    border_all(**border_opts[:all]) if border_opts.key?(:all) && border_opts[:all]
    border_left(**border_opts[:left]) if border_opts.key?(:left) && border_opts[:left]
    border_right(**border_opts[:right]) if border_opts.key?(:right) && border_opts[:right]
    border_top(**border_opts[:top]) if border_opts.key?(:top) && border_opts[:top]
    border_bottom(**border_opts[:bottom]) if border_opts.key?(:bottom) && border_opts[:bottom]
  else
    border_all(**opts[:border_all]) if opts.key?(:border_all) && opts[:border_all]
    border_left(**opts[:border_left]) if opts.key?(:border_left) && opts[:border_left]
    border_right(**opts[:border_right]) if opts.key?(:border_right) && opts[:border_right]
    border_top(**opts[:border_top]) if opts.key?(:border_top) && opts[:border_top]
    border_bottom(**opts[:border_bottom]) if opts.key?(:border_bottom) && opts[:border_bottom]
  end

  number_format(opts[:number_format]) if opts.key?(:number_format)

  if opts.key?(:alignment)
    align_opts = opts[:alignment] || {}
    align_horizontal(align_opts[:horizontal]) if align_opts.key?(:horizontal)
    align_vertical(align_opts[:vertical]) if align_opts.key?(:vertical)
    wrap_text(align_opts[:wrap_text]) if align_opts.key?(:wrap_text)
    text_rotation(align_opts[:text_rotation]) if align_opts.key?(:text_rotation)
    indent(align_opts[:indent]) if align_opts.key?(:indent)
    shrink_to_fit(align_opts[:shrink_to_fit]) if align_opts.key?(:shrink_to_fit)
  else
    align_horizontal(opts[:align_horizontal]) if opts.key?(:align_horizontal)
    align_vertical(opts[:align_vertical]) if opts.key?(:align_vertical)
    wrap_text(opts[:wrap_text]) if opts.key?(:wrap_text)
    text_rotation(opts[:text_rotation]) if opts.key?(:text_rotation)
    indent(opts[:indent]) if opts.key?(:indent)
    shrink_to_fit(opts[:shrink_to_fit]) if opts.key?(:shrink_to_fit)
  end

  self
end

#bold(value = true) ⇒ Object

rubocop:disable Style/OptionalBooleanParameter

Parameters:

  • value (Object) (defaults to: true)

Returns:

  • (Object)


147
148
149
150
# File 'lib/xlsxrb/style_builder.rb', line 147

def bold(value = true)
  @font_props[:bold] = value
  self
end

#border(**opts) ⇒ Object

: (**untyped opts) -> self



230
231
232
233
234
235
236
237
# File 'lib/xlsxrb/style_builder.rb', line 230

def border(**opts)
  border_all(**opts[:all]) if opts.key?(:all) && opts[:all]
  border_left(**opts[:left]) if opts.key?(:left) && opts[:left]
  border_right(**opts[:right]) if opts.key?(:right) && opts[:right]
  border_top(**opts[:top]) if opts.key?(:top) && opts[:top]
  border_bottom(**opts[:bottom]) if opts.key?(:bottom) && opts[:bottom]
  self
end

#border_all(style: "thin", color: nil) ⇒ Object

: (?style: String | Symbol, ?color: String | Symbol | nil) -> self

Parameters:

  • style: (Object) (defaults to: "thin")
  • color: (Object) (defaults to: nil)

Returns:

  • (Object)


240
241
242
243
244
245
246
247
# File 'lib/xlsxrb/style_builder.rb', line 240

def border_all(style: "thin", color: nil)
  color_opt = color ? { color: resolve_color(color) } : {}
  @border_props[:left] = { style: style, **color_opt }
  @border_props[:right] = { style: style, **color_opt }
  @border_props[:top] = { style: style, **color_opt }
  @border_props[:bottom] = { style: style, **color_opt }
  self
end

#border_bottom(style: "thin", color: nil) ⇒ Object

: (?style: String | Symbol, ?color: String | Symbol | nil) -> self

Parameters:

  • style: (Object) (defaults to: "thin")
  • color: (Object) (defaults to: nil)

Returns:

  • (Object)


268
269
270
271
# File 'lib/xlsxrb/style_builder.rb', line 268

def border_bottom(style: "thin", color: nil)
  @border_props[:bottom] = { style: style, color: resolve_color(color) }.compact
  self
end

#border_diagonal(style: "thin", color: nil, up: false, down: false) ⇒ Object

rubocop:disable Naming/MethodParameterName

Parameters:

  • style: (Object) (defaults to: "thin")
  • color: (Object) (defaults to: nil)
  • up: (Object) (defaults to: false)
  • down: (Object) (defaults to: false)

Returns:

  • (Object)


275
276
277
278
279
280
# File 'lib/xlsxrb/style_builder.rb', line 275

def border_diagonal(style: "thin", color: nil, up: false, down: false)
  @border_props[:diagonal] = { style: style, color: resolve_color(color) }.compact
  @border_props[:diagonal_up] = true if up
  @border_props[:diagonal_down] = true if down
  self
end

#border_left(style: "thin", color: nil) ⇒ Object

: (?style: String | Symbol, ?color: String | Symbol | nil) -> self

Parameters:

  • style: (Object) (defaults to: "thin")
  • color: (Object) (defaults to: nil)

Returns:

  • (Object)


250
251
252
253
# File 'lib/xlsxrb/style_builder.rb', line 250

def border_left(style: "thin", color: nil)
  @border_props[:left] = { style: style, color: resolve_color(color) }.compact
  self
end

#border_right(style: "thin", color: nil) ⇒ Object

: (?style: String | Symbol, ?color: String | Symbol | nil) -> self

Parameters:

  • style: (Object) (defaults to: "thin")
  • color: (Object) (defaults to: nil)

Returns:

  • (Object)


256
257
258
259
# File 'lib/xlsxrb/style_builder.rb', line 256

def border_right(style: "thin", color: nil)
  @border_props[:right] = { style: style, color: resolve_color(color) }.compact
  self
end

#border_top(style: "thin", color: nil) ⇒ Object

: (?style: String | Symbol, ?color: String | Symbol | nil) -> self

Parameters:

  • style: (Object) (defaults to: "thin")
  • color: (Object) (defaults to: nil)

Returns:

  • (Object)


262
263
264
265
# File 'lib/xlsxrb/style_builder.rb', line 262

def border_top(style: "thin", color: nil)
  @border_props[:top] = { style: style, color: resolve_color(color) }.compact
  self
end

#fill(pattern: "solid", fg_color: nil, bg_color: nil) ⇒ Object

: (?pattern: String | Symbol, ?fg_color: String | Symbol | nil, ?bg_color: String | Symbol | nil) -> self

Parameters:

  • pattern: (Object) (defaults to: "solid")
  • fg_color: (Object) (defaults to: nil)
  • bg_color: (Object) (defaults to: nil)

Returns:

  • (Object)


213
214
215
# File 'lib/xlsxrb/style_builder.rb', line 213

def fill(pattern: "solid", fg_color: nil, bg_color: nil)
  fill_pattern(pattern, fg_color: resolve_color(fg_color), bg_color: resolve_color(bg_color))
end

#fill_color(color) ⇒ Object

: (String | Symbol color) -> self

Parameters:

  • color (Object)

Returns:

  • (Object)


206
207
208
209
210
# File 'lib/xlsxrb/style_builder.rb', line 206

def fill_color(color)
  @fill_props[:pattern] = "solid"
  @fill_props[:fg_color] = resolve_color(color)
  self
end

#fill_gradient(type:, degree: nil, stops: []) ⇒ Object

: (type: String, ?degree: Numeric | nil, ?stops: Array) -> self

Parameters:

  • type: (Object)
  • degree: (Object) (defaults to: nil)
  • stops: (Object) (defaults to: [])

Returns:

  • (Object)


218
219
220
221
222
223
224
225
# File 'lib/xlsxrb/style_builder.rb', line 218

def fill_gradient(type:, degree: nil, stops: [])
  @fill_props[:gradient] = {
    type: type,
    degree: degree,
    stops: stops
  }.compact
  self
end

#fill_pattern(pattern, fg_color: nil, bg_color: nil) ⇒ Object

: (String | Symbol pattern, ?fg_color: String | Symbol | nil, ?bg_color: String | Symbol | nil) -> self

Parameters:

  • pattern (Object)
  • fg_color: (Object) (defaults to: nil)
  • bg_color: (Object) (defaults to: nil)

Returns:

  • (Object)


198
199
200
201
202
203
# File 'lib/xlsxrb/style_builder.rb', line 198

def fill_pattern(pattern, fg_color: nil, bg_color: nil)
  @fill_props[:pattern] = pattern
  @fill_props[:fg_color] = fg_color if fg_color
  @fill_props[:bg_color] = bg_color if bg_color
  self
end

#font(**opts) ⇒ Object

: (**untyped opts) -> self



133
134
135
136
137
138
139
140
141
142
143
# File 'lib/xlsxrb/style_builder.rb', line 133

def font(**opts)
  bold(opts[:bold]) if opts.key?(:bold)
  italic(opts[:italic]) if opts.key?(:italic)
  size(opts[:size]) if opts.key?(:size)
  font_name(opts[:name]) if opts.key?(:name)
  font_color(opts[:color]) if opts.key?(:color)
  underline(opts[:underline]) if opts.key?(:underline)
  strike(opts[:strike]) if opts.key?(:strike)
  vert_align(opts[:vert_align]) if opts.key?(:vert_align)
  self
end

#font_color(color) ⇒ Object

: (String | Symbol color) -> self

Parameters:

  • color (Object)

Returns:

  • (Object)


171
172
173
174
# File 'lib/xlsxrb/style_builder.rb', line 171

def font_color(color)
  @font_props[:color] = resolve_color(color)
  self
end

#font_name(name) ⇒ Object

: (String name) -> self

Parameters:

  • name (Object)

Returns:

  • (Object)


165
166
167
168
# File 'lib/xlsxrb/style_builder.rb', line 165

def font_name(name)
  @font_props[:name] = name
  self
end

#indent(value) ⇒ Object

: (Numeric value) -> self

Parameters:

  • value (Object)

Returns:

  • (Object)


318
319
320
321
# File 'lib/xlsxrb/style_builder.rb', line 318

def indent(value)
  @alignment[:indent] = value.to_i
  self
end

#italic(value = true) ⇒ Object

: (?bool value) -> self

Parameters:

  • value (Object) (defaults to: true)

Returns:

  • (Object)


153
154
155
156
# File 'lib/xlsxrb/style_builder.rb', line 153

def italic(value = true)
  @font_props[:italic] = value
  self
end

#number_format(num_fmt_id) ⇒ Object Also known as: num_fmt

: (String | Integer num_fmt_id) -> self

Parameters:

  • num_fmt_id (Object)

Returns:

  • (Object)


326
327
328
329
# File 'lib/xlsxrb/style_builder.rb', line 326

def number_format(num_fmt_id)
  @num_fmt_id = num_fmt_id
  self
end

#register_with(writer) ⇒ Object

Register this style with the given Writer, returning the style_id.

writer

Xlsxrb::Ooxml::Writer instance

Parameters:

  • writer (Object)

Returns:

  • (Object)


335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
# File 'lib/xlsxrb/style_builder.rb', line 335

def register_with(writer)
  font_id = 0
  fill_id = 0
  border_id = 0

  font_id = writer.add_font(**@font_props) if @font_props.any?
  fill_id = writer.add_fill(**@fill_props) if @fill_props.any?
  border_id = writer.add_border(**@border_props) if @border_props.any?

  resolved_num_fmt_id = if @num_fmt_id.is_a?(String)
                          writer.add_number_format(@num_fmt_id)
                        else
                          @num_fmt_id
                        end

  cell_style_opts = {
    num_fmt_id: resolved_num_fmt_id,
    font_id: font_id,
    fill_id: fill_id,
    border_id: border_id
  }
  cell_style_opts[:alignment] = @alignment if @alignment.any?

  writer.add_cell_style(**cell_style_opts)
end

#resolve_color(color) ⇒ Object

Parameters:

  • color (Object)

Returns:

  • (Object)


22
23
24
25
26
27
28
29
30
# File 'lib/xlsxrb/style_builder.rb', line 22

def resolve_color(color)
  return nil unless color

  if color.is_a?(Symbol) || (color.is_a?(String) && color.start_with?(":") && color.length > 1)
    key = color.to_s.sub(/^:/, "").to_sym
    return COLORS[key] || color.to_s
  end
  color.to_s
end

#shrink_to_fit(value = true) ⇒ Object

: (?bool value) -> self

Parameters:

  • value (Object) (defaults to: true)

Returns:

  • (Object)


305
306
307
308
# File 'lib/xlsxrb/style_builder.rb', line 305

def shrink_to_fit(value = true)
  @alignment[:shrink_to_fit] = value
  self
end

#size(size_value) ⇒ Object

: (Numeric size_value) -> self

Parameters:

  • size_value (Object)

Returns:

  • (Object)


159
160
161
162
# File 'lib/xlsxrb/style_builder.rb', line 159

def size(size_value)
  @font_props[:sz] = size_value.to_i
  self
end

#strike(value = true) ⇒ Object

: (?bool value) -> self

Parameters:

  • value (Object) (defaults to: true)

Returns:

  • (Object)


183
184
185
186
# File 'lib/xlsxrb/style_builder.rb', line 183

def strike(value = true)
  @font_props[:strike] = value
  self
end

#text_rotation(value) ⇒ Object

: (Numeric value) -> self

Parameters:

  • value (Object)

Returns:

  • (Object)


312
313
314
315
# File 'lib/xlsxrb/style_builder.rb', line 312

def text_rotation(value)
  @alignment[:text_rotation] = value
  self
end

#underline(val = "single") ⇒ Object

: (?String val) -> self

Parameters:

  • val (Object) (defaults to: "single")

Returns:

  • (Object)


177
178
179
180
# File 'lib/xlsxrb/style_builder.rb', line 177

def underline(val = "single")
  @font_props[:underline] = val
  self
end

#vert_align(value) ⇒ Object

: (String value) -> self

Parameters:

  • value (Object)

Returns:

  • (Object)


189
190
191
192
# File 'lib/xlsxrb/style_builder.rb', line 189

def vert_align(value)
  @font_props[:vert_align] = value
  self
end

#wrap_text(value = true) ⇒ Object

rubocop:disable Style/OptionalBooleanParameter

Parameters:

  • value (Object) (defaults to: true)

Returns:

  • (Object)


299
300
301
302
# File 'lib/xlsxrb/style_builder.rb', line 299

def wrap_text(value = true)
  @alignment[:wrap_text] = value
  self
end