axlsx 1.1.1 → 1.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +18 -7
- data/examples/conditional_formatting/example_conditional_formatting.rb +72 -0
- data/examples/conditional_formatting/getting_barred.rb +37 -0
- data/examples/conditional_formatting/hitting_the_high_notes.rb +37 -0
- data/examples/conditional_formatting/scaled_colors.rb +39 -0
- data/examples/conditional_formatting/stop_and_go.rb +37 -0
- data/examples/example.rb +6 -2
- data/examples/{real_example.rb → skydrive/real_example.rb} +0 -0
- data/lib/axlsx.rb +1 -1
- data/lib/axlsx/drawing/axis.rb +16 -0
- data/lib/axlsx/stylesheet/dxf.rb +79 -0
- data/lib/axlsx/stylesheet/font.rb +2 -1
- data/lib/axlsx/stylesheet/styles.rb +141 -50
- data/lib/axlsx/stylesheet/xf.rb +2 -0
- data/lib/axlsx/util/constants.rb +8 -0
- data/lib/axlsx/util/validators.rb +44 -0
- data/lib/axlsx/version.rb +1 -1
- data/lib/axlsx/workbook/workbook.rb +6 -0
- data/lib/axlsx/workbook/worksheet/cfvo.rb +62 -0
- data/lib/axlsx/workbook/worksheet/cfvo.rb~ +0 -0
- data/lib/axlsx/workbook/worksheet/color_scale.rb +76 -0
- data/lib/axlsx/workbook/worksheet/color_scale.rb~ +46 -0
- data/lib/axlsx/workbook/worksheet/conditional_formatting.rb +82 -0
- data/lib/axlsx/workbook/worksheet/conditional_formatting_rule.rb +216 -0
- data/lib/axlsx/workbook/worksheet/data_bar.rb +97 -0
- data/lib/axlsx/workbook/worksheet/data_bar.rb~ +0 -0
- data/lib/axlsx/workbook/worksheet/icon_set.rb +83 -0
- data/lib/axlsx/workbook/worksheet/icon_set.rb~ +95 -0
- data/lib/axlsx/workbook/worksheet/row.rb +2 -0
- data/lib/axlsx/workbook/worksheet/worksheet.rb +25 -3
- data/test/drawing/tc_axis.rb +8 -0
- data/test/stylesheet/tc_dxf.rb +81 -0
- data/test/stylesheet/tc_styles.rb +148 -2
- data/test/workbook/worksheet/tc_cfvo.rb +31 -0
- data/test/workbook/worksheet/tc_cfvo.rb~ +20 -0
- data/test/workbook/worksheet/tc_color_scale.rb +29 -0
- data/test/workbook/worksheet/tc_color_scale.rb~ +0 -0
- data/test/workbook/worksheet/tc_conditional_formatting.rb +173 -0
- data/test/workbook/worksheet/tc_data_bar.rb +39 -0
- data/test/workbook/worksheet/tc_data_bar.rb~ +0 -0
- data/test/workbook/worksheet/tc_icon_set.rb +45 -0
- data/test/workbook/worksheet/tc_icon_set.rb~ +0 -0
- data/test/workbook/worksheet/tc_row.rb +9 -2
- metadata +45 -27
- data/examples/axlsx.xlsx +0 -0
- data/examples/example.xlsx +0 -0
- data/examples/example_streamed.xlsx +0 -0
- data/examples/no-use_autowidth.xlsx +0 -0
- data/examples/shared_strings_example.xlsx +0 -0
- data/lib/axlsx/util/doc/_index.html +0 -84
- data/lib/axlsx/util/doc/class_list.html +0 -47
- data/lib/axlsx/util/doc/css/common.css +0 -1
- data/lib/axlsx/util/doc/css/full_list.css +0 -55
- data/lib/axlsx/util/doc/css/style.css +0 -322
- data/lib/axlsx/util/doc/file_list.html +0 -46
- data/lib/axlsx/util/doc/frames.html +0 -13
- data/lib/axlsx/util/doc/index.html +0 -84
- data/lib/axlsx/util/doc/js/app.js +0 -205
- data/lib/axlsx/util/doc/js/full_list.js +0 -173
- data/lib/axlsx/util/doc/js/jquery.js +0 -16
- data/lib/axlsx/util/doc/method_list.html +0 -46
- data/lib/axlsx/util/doc/top-level-namespace.html +0 -95
@@ -103,7 +103,8 @@ module Axlsx
|
|
103
103
|
# @option options [Integer] sz
|
104
104
|
def initialize(options={})
|
105
105
|
options.each do |o|
|
106
|
-
|
106
|
+
next if o[1].nil?
|
107
|
+
self.send("#{o[0]}=", o[1]) if self.respond_to? "#{o[0]}="
|
107
108
|
end
|
108
109
|
end
|
109
110
|
# @see name
|
@@ -14,6 +14,7 @@ module Axlsx
|
|
14
14
|
require 'axlsx/stylesheet/table_style.rb'
|
15
15
|
require 'axlsx/stylesheet/table_styles.rb'
|
16
16
|
require 'axlsx/stylesheet/table_style_element.rb'
|
17
|
+
require 'axlsx/stylesheet/dxf.rb'
|
17
18
|
require 'axlsx/stylesheet/xf.rb'
|
18
19
|
require 'axlsx/stylesheet/cell_protection.rb'
|
19
20
|
|
@@ -137,6 +138,7 @@ module Axlsx
|
|
137
138
|
# @option options [String] bg_color The background color to apply to the cell
|
138
139
|
# @option options [Boolean] hidden Indicates if the cell should be hidden
|
139
140
|
# @option options [Boolean] locked Indicates if the cell should be locked
|
141
|
+
# @option options [Symbol] type What type of style is this. Options are [:dxf, :xf]. :xf is default
|
140
142
|
# @option options [Hash] alignment A hash defining any of the attributes used in CellAlignment
|
141
143
|
# @see CellAlignment
|
142
144
|
#
|
@@ -189,67 +191,156 @@ module Axlsx
|
|
189
191
|
# ws.add_row :values => ["Q4", 2000, 20], :style=>[title, currency, percent]
|
190
192
|
# f = File.open('example_you_got_style.xlsx', 'w')
|
191
193
|
# p.serialize(f)
|
194
|
+
#
|
195
|
+
# @example Differential styling
|
196
|
+
# # Differential styles apply on top of cell styles. Used in Conditional Formatting. Must specify :type => :dxf, and you can't use :num_fmt.
|
197
|
+
# require "rubygems" # if that is your preferred way to manage gems!
|
198
|
+
# require "axlsx"
|
199
|
+
#
|
200
|
+
# p = Axlsx::Package.new
|
201
|
+
# wb = p.workbook
|
202
|
+
# ws = wb.add_worksheet
|
203
|
+
#
|
204
|
+
# # define your styles
|
205
|
+
# profitable = wb.styles.add_style(:bg_color => "FFFF0000",
|
206
|
+
# :fg_color=>"#FF000000",
|
207
|
+
# :type => :dxf)
|
208
|
+
#
|
209
|
+
# ws.add_row :values => ["Genreated At:", Time.now], :styles=>[nil, date_time]
|
210
|
+
# ws.add_row :values => ["Previous Year Quarterly Profits (JPY)"], :style=>title
|
211
|
+
# ws.add_row :values => ["Quarter", "Profit", "% of Total"], :style=>title
|
212
|
+
# ws.add_row :values => ["Q1", 4000, 40], :style=>[title, currency, percent]
|
213
|
+
# ws.add_row :values => ["Q2", 3000, 30], :style=>[title, currency, percent]
|
214
|
+
# ws.add_row :values => ["Q3", 1000, 10], :style=>[title, currency, percent]
|
215
|
+
# ws.add_row :values => ["Q4", 2000, 20], :style=>[title, currency, percent]
|
216
|
+
#
|
217
|
+
# ws.add_conditional_formatting("A1:A7", { :type => :cellIs, :operator => :greaterThan, :formula => "2000", :dxfId => profitable, :priority => 1 })
|
218
|
+
# f = File.open('example_differential_styling', 'w')
|
219
|
+
# p.serialize(f)
|
220
|
+
#
|
192
221
|
def add_style(options={})
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
edges = borderId[:edges] || [:left, :right, :top, :bottom]
|
210
|
-
|
211
|
-
border = Border.new
|
212
|
-
edges.each {|pr| border.prs << BorderPr.new(:name => pr, :style=>s, :color => Color.new(:rgb => c))}
|
213
|
-
borderId = self.borders << border
|
222
|
+
# Default to :xf
|
223
|
+
options[:type] ||= :xf
|
224
|
+
raise ArgumentError, "Type must be one of [:xf, :dxf]" unless [:xf, :dxf].include?(options[:type] )
|
225
|
+
|
226
|
+
fill = parse_fill_options options
|
227
|
+
font = parse_font_options options
|
228
|
+
numFmt = parse_num_fmt_options options
|
229
|
+
border = parse_border_options options
|
230
|
+
alignment = parse_alignment_options options
|
231
|
+
protection = parse_protection_options options
|
232
|
+
|
233
|
+
case options[:type]
|
234
|
+
when :dxf
|
235
|
+
style = Dxf.new :fill => fill, :font => font, :numFmt => numFmt, :border => border, :alignment => alignment, :protection => protection
|
236
|
+
else
|
237
|
+
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?
|
214
238
|
end
|
215
239
|
|
216
|
-
|
240
|
+
options[:type] == :xf ? cellXfs << style : dxfs << style
|
241
|
+
end
|
217
242
|
|
218
|
-
|
219
|
-
|
220
|
-
pattern = PatternFill.new(:patternType =>:solid, :fgColor=>color)
|
221
|
-
fills << Fill.new(pattern)
|
222
|
-
else
|
223
|
-
0
|
224
|
-
end
|
243
|
+
# parses add_style options for protection styles
|
244
|
+
# noop if options hash does not include :hide or :locked key
|
225
245
|
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
0
|
234
|
-
end
|
246
|
+
# @option options [Boolean] hide boolean value defining cell protection attribute for hiding.
|
247
|
+
# @option options [Boolean] locked boolean value defining cell protection attribute for locking.
|
248
|
+
# @return [CellProtection]
|
249
|
+
def parse_protection_options(options={})
|
250
|
+
return if (options.keys & [:hidden, :locked]).empty?
|
251
|
+
CellProtection.new(options)
|
252
|
+
end
|
235
253
|
|
236
|
-
|
254
|
+
# parses add_style options for alignment
|
255
|
+
# noop if options hash does not include :alignment key
|
256
|
+
# @option options [Hash] alignment A hash of options to prive the CellAlignment intializer
|
257
|
+
# @return [CellAlignment]
|
258
|
+
# @see CellAlignment
|
259
|
+
def parse_alignment_options(options={})
|
260
|
+
return unless options[:alignment]
|
261
|
+
CellAlignment.new options[:alignment]
|
262
|
+
end
|
237
263
|
|
238
|
-
|
264
|
+
# parses add_style options for fonts. If the options hash contains :type => :dxf we return a new Font object.
|
265
|
+
# if not, we return the index of the newly created font object in the styles.fonts collection.
|
266
|
+
# @note noop if none of the options described here are set on the options parameter.
|
267
|
+
# @option options [Symbol] type The type of style object we are working with (dxf or xf)
|
268
|
+
# @option options [String] fg_color The text color
|
269
|
+
# @option options [Integer] sz The text size
|
270
|
+
# @option options [Boolean] b Indicates if the text should be bold
|
271
|
+
# @option options [Boolean] i Indicates if the text should be italicised
|
272
|
+
# @option options [Boolean] u Indicates if the text should be underlined
|
273
|
+
# @option options [Boolean] strike Indicates if the text should be rendered with a strikethrough
|
274
|
+
# @option options [Boolean] outline Indicates if the text should be rendered with a shadow
|
275
|
+
# @option options [Integer] charset The character set to use.
|
276
|
+
# @option options [Integer] family The font family to use.
|
277
|
+
# @option options [String] font_name The name of the font to use
|
278
|
+
# @return [Font|Integer]
|
279
|
+
def parse_font_options(options={})
|
280
|
+
return if (options.keys & [:fg_color, :sz, :b, :i, :u, :strike, :outline, :shadow, :charset, :family, :font_name]).empty?
|
281
|
+
font = Font.new(options)
|
282
|
+
font.color = Color.new(:rgb => options[:fg_color]) if options[:fg_color]
|
283
|
+
font.name = options[:font_name] if options[:font_name]
|
284
|
+
options[:type] == :dxf ? font : fonts << font
|
285
|
+
end
|
239
286
|
|
240
|
-
|
241
|
-
|
287
|
+
# 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.
|
288
|
+
# @note noop if :bg_color is not specified in options
|
289
|
+
# @option options [String] bg_color The rgb color to apply to the fill
|
290
|
+
# @return [Fill|Integer]
|
291
|
+
def parse_fill_options(options={})
|
292
|
+
return unless options[:bg_color]
|
293
|
+
color = Color.new(:rgb=>options[:bg_color])
|
294
|
+
pattern = PatternFill.new(:patternType =>:solid, :fgColor=>color)
|
295
|
+
fill = Fill.new(pattern)
|
296
|
+
options[:type] == :dxf ? fill : fills << fill
|
297
|
+
end
|
242
298
|
|
243
|
-
|
244
|
-
|
245
|
-
|
299
|
+
# parses Style#add_style options for borders.
|
300
|
+
# @note noop if :border is not specified in options
|
301
|
+
# @option options [Hash|Integer] A border style definition hash or the index of an existing border. 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 or any other valid Border initializer options. If the :edges entity is not provided the style is applied to all edges of cells that reference this style.
|
302
|
+
# @example
|
303
|
+
# #apply a thick red border to the top and bottom
|
304
|
+
# { :border => { :style => :thick, :color => "FFFF0000", :edges => [:top, :bottom] }
|
305
|
+
# @return [Border|Integer]
|
306
|
+
def parse_border_options(options={})
|
307
|
+
return unless options[:border]
|
308
|
+
b_opts = options[:border]
|
309
|
+
if b_opts.is_a?(Hash)
|
310
|
+
raise ArgumentError, (ERR_INVALID_BORDER_OPTIONS % b_opts) unless b_opts.values_at(:style, :color).size == 2
|
311
|
+
border = Border.new b_opts
|
312
|
+
(b_opts[:edges] || [:left, :right, :top, :bottom]).each do |edge|
|
313
|
+
b_options = { :name => edge, :style => b_opts[:style], :color => Color.new(:rgb => b_opts[:color]) }
|
314
|
+
border.prs << BorderPr.new(b_options)
|
315
|
+
end
|
316
|
+
options[:type] == :dxf ? border : borders << border
|
317
|
+
elsif b_opts.is_a? Integer
|
318
|
+
raise ArgumentError, (ERR_INVALID_BORDER_ID % b_opts) unless b_opts < borders.size
|
319
|
+
if options[:type] == :dxf
|
320
|
+
borders[b_opts].clone
|
321
|
+
else
|
322
|
+
border = b_opts
|
323
|
+
end
|
246
324
|
end
|
325
|
+
end
|
247
326
|
|
248
|
-
|
249
|
-
|
327
|
+
# Parses Style#add_style options for number formatting.
|
328
|
+
# noop if neither :format_code or :num_format options are set.
|
329
|
+
# @option options [Hash] A hash describing the :format_code and/or :num_fmt integer for the style.
|
330
|
+
# @return [NumFmt|Integer]
|
331
|
+
def parse_num_fmt_options(options={})
|
332
|
+
return if (options.keys & [:format_code, :num_fmt]).empty?
|
333
|
+
|
334
|
+
#When the user provides format_code - we always need to create a new numFmt object
|
335
|
+
#When the type is :dxf we always need to create a new numFmt object
|
336
|
+
if options[:format_code] || options[:type] == :dxf
|
337
|
+
#If this is a standard xf we pull from numFmts the highest current and increment for num_fmt
|
338
|
+
options[:num_fmt] ||= (@numFmts.map{ |num_fmt| num_fmt.numFmtId }.max + 1) if options[:type] != :dxf
|
339
|
+
numFmt = NumFmt.new(:numFmtId => options[:num_fmt] || 0, :formatCode=> options[:format_code].to_s)
|
340
|
+
options[:type] == :dxf ? numFmt : (numFmts << numFmt; numFmt.numFmtId)
|
341
|
+
else
|
342
|
+
options[:num_fmt]
|
250
343
|
end
|
251
|
-
|
252
|
-
cellXfs << xf
|
253
344
|
end
|
254
345
|
|
255
346
|
# Serializes the object
|
@@ -306,7 +397,7 @@ module Axlsx
|
|
306
397
|
@cellXfs << Xf.new(:borderId=>0, :xfId=>0, :numFmtId=>14, :fontId=>0, :fillId=>0, :applyNumberFormat=>1)
|
307
398
|
@cellXfs.lock
|
308
399
|
|
309
|
-
@dxfs = SimpleTypedList.new(
|
400
|
+
@dxfs = SimpleTypedList.new(Dxf, "dxfs"); @dxfs.lock
|
310
401
|
@tableStyles = TableStyles.new(:defaultTableStyle => "TableStyleMedium9", :defaultPivotStyle => "PivotStyleLight16"); @tableStyles.lock
|
311
402
|
end
|
312
403
|
end
|
data/lib/axlsx/stylesheet/xf.rb
CHANGED
@@ -85,6 +85,7 @@ module Axlsx
|
|
85
85
|
# @option options [CellProtection] protection
|
86
86
|
def initialize(options={})
|
87
87
|
options.each do |o|
|
88
|
+
next if o[1].nil?
|
88
89
|
self.send("#{o[0]}=", o[1]) if self.respond_to? "#{o[0]}="
|
89
90
|
end
|
90
91
|
end
|
@@ -139,5 +140,6 @@ module Axlsx
|
|
139
140
|
str << '</xf>'
|
140
141
|
end
|
141
142
|
|
143
|
+
|
142
144
|
end
|
143
145
|
end
|
data/lib/axlsx/util/constants.rb
CHANGED
@@ -232,4 +232,12 @@ module Axlsx
|
|
232
232
|
# error message for duplicate sheet names
|
233
233
|
ERR_DUPLICATE_SHEET_NAME = "There is already a worksheet in this workbook named '%s'. Please use a unique name"
|
234
234
|
|
235
|
+
# error message when user does not provide color and or style options for border in Style#add_sytle
|
236
|
+
ERR_INVALID_BORDER_OPTIONS = "border hash must include both style and color. e.g. :border => { :color => 'FF000000', :style => :thin }. You provided: %s"
|
237
|
+
|
238
|
+
# error message for invalid border id reference
|
239
|
+
ERR_INVALID_BORDER_ID = "The border id you specified (%s) does not exist. Please add a border with Style#add_style before referencing its index."
|
240
|
+
|
241
|
+
# error message for invalid angles
|
242
|
+
ERR_ANGLE = "Angles must be a value between -90 and 90. You provided: %s"
|
235
243
|
end
|
@@ -45,6 +45,9 @@ module Axlsx
|
|
45
45
|
true
|
46
46
|
end
|
47
47
|
|
48
|
+
def self.validate_angle(v)
|
49
|
+
raise ArgumentError, (ERR_ANGLE % v.inspect) unless (v >= -5400000 && v <= 5400000)
|
50
|
+
end
|
48
51
|
# Requires that the value is a Fixnum or Integer and is greater or equal to 0
|
49
52
|
# @param [Any] v The value validated
|
50
53
|
# @raise [ArgumentError] raised if the value is not a Fixnum or Integer value greater or equal to 0
|
@@ -96,6 +99,47 @@ module Axlsx
|
|
96
99
|
:darkTrellis, :lightHorizontal, :lightVertical, :lightDown, :lightUp, :lightGrid, :lightTrellis, :gray125, :gray0625], v
|
97
100
|
end
|
98
101
|
|
102
|
+
# Requires that the value is one of the ST_TimePeriod types
|
103
|
+
# valid time period types are today, yesterday, tomorrow, last7Days,
|
104
|
+
# thisMonth, lastMonth, nextMonth, thisWeek, lastWeek, nextWeek
|
105
|
+
def self.validate_time_period_type(v)
|
106
|
+
RestrictionValidator.validate :time_period_type, [:today, :yesterday, :tomorrow, :last7Days, :thisMonth, :lastMonth, :nextMonth, :thisWeek, :lastWeek, :nextWeek], v
|
107
|
+
|
108
|
+
|
109
|
+
end
|
110
|
+
|
111
|
+
# Requires that the value is one of the valid ST_IconSet types
|
112
|
+
# Allowed values are: 3Arrows, 3ArrowsGray, 3Flags, 3TrafficLights1, 3TrafficLights2, 3Signs, 3Symbols, 3Symbols2, 4Arrows, 4ArrowsGray, 4RedToBlack, 4Rating, 4TrafficLights, 5Arrows, 5ArrowsGray, 5Rating, 5Quarters
|
113
|
+
def self.validate_icon_set(v)
|
114
|
+
RestrictionValidator.validate :iconSet, ["3Arrows", "3ArrowsGray", "3Flags", "3TrafficLights1", "3TrafficLights2", "3Signs", "3Symbols", "3Symbols2", "4Arrows", "4ArrowsGray", "4RedToBlack", "4Rating", "4TrafficLights", "5Arrows", "5ArrowsGray", "5Rating", "5Quarters"], v
|
115
|
+
end
|
116
|
+
|
117
|
+
# Requires that the value is valid conditional formatting type.
|
118
|
+
# valid types must be one of expression, cellIs, colorScale,
|
119
|
+
# dataBar, iconSet, top10, uniqueValues, duplicateValues,
|
120
|
+
# containsText, notContainsText, beginsWith, endsWith,
|
121
|
+
# containsBlanks, notContainsBlanks, containsErrors,
|
122
|
+
# notContainsErrors, timePeriod, aboveAverage
|
123
|
+
# @param [Any] v The value validated
|
124
|
+
def self.validate_conditional_formatting_type(v)
|
125
|
+
RestrictionValidator.validate :conditional_formatting_type, [:expression, :cellIs, :colorScale, :dataBar, :iconSet, :top10, :uniqueValues, :duplicateValues, :containsText, :notContainsText, :beginsWith, :endsWith, :containsBlanks, :notContainsBlanks, :containsErrors, :notContainsErrors, :timePeriod, :aboveAverage], v
|
126
|
+
end
|
127
|
+
|
128
|
+
# Requires thatt he value is a valid conditional formatting value object type.
|
129
|
+
# valid types must be one of num, percent, max, min, formula and percentile
|
130
|
+
def self.validate_conditional_formatting_value_object_type(v)
|
131
|
+
RestrictionValidator.validate :conditional_formatting_value_object_type, [:num, :percent, :max, :min, :formula, :percentile], v
|
132
|
+
end
|
133
|
+
|
134
|
+
# Requires that the value is valid conditional formatting operator.
|
135
|
+
# valid operators must be one of lessThan, lessThanOrEqual, equal,
|
136
|
+
# notEqual, greaterThanOrEqual, greaterThan, between, notBetween,
|
137
|
+
# containsText, notContains, beginsWith, endsWith
|
138
|
+
# @param [Any] v The value validated
|
139
|
+
def self.validate_conditional_formatting_operator(v)
|
140
|
+
RestrictionValidator.validate :conditional_formatting_type, [:lessThan, :lessThanOrEqual, :equal, :notEqual, :greaterThanOrEqual, :greaterThan, :between, :notBetween, :containsText, :notContains, :beginsWith, :endsWith], v
|
141
|
+
end
|
142
|
+
|
99
143
|
# Requires that the value is a gradient_type.
|
100
144
|
# valid types are :linear and :path
|
101
145
|
# @param [Any] v The value validated
|
data/lib/axlsx/version.rb
CHANGED
@@ -5,6 +5,6 @@ module Axlsx
|
|
5
5
|
# When using bunle exec rake and referencing the gem on github or locally
|
6
6
|
# it will use the gemspec, which preloads this constant for the gem's version.
|
7
7
|
# We check to make sure that it has not already been loaded
|
8
|
-
VERSION="1.1.
|
8
|
+
VERSION="1.1.2" unless defined? Axlsx::VERSION
|
9
9
|
|
10
10
|
end
|
@@ -4,6 +4,12 @@ module Axlsx
|
|
4
4
|
require 'axlsx/workbook/worksheet/date_time_converter.rb'
|
5
5
|
require 'axlsx/workbook/worksheet/cell.rb'
|
6
6
|
require 'axlsx/workbook/worksheet/page_margins.rb'
|
7
|
+
require 'axlsx/workbook/worksheet/cfvo.rb'
|
8
|
+
require 'axlsx/workbook/worksheet/color_scale.rb'
|
9
|
+
require 'axlsx/workbook/worksheet/data_bar.rb'
|
10
|
+
require 'axlsx/workbook/worksheet/icon_set.rb'
|
11
|
+
require 'axlsx/workbook/worksheet/conditional_formatting.rb'
|
12
|
+
require 'axlsx/workbook/worksheet/conditional_formatting_rule.rb'
|
7
13
|
require 'axlsx/workbook/worksheet/row.rb'
|
8
14
|
require 'axlsx/workbook/worksheet/col.rb'
|
9
15
|
require 'axlsx/workbook/worksheet/worksheet.rb'
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module Axlsx
|
2
|
+
# Conditional Format Value Object
|
3
|
+
# Describes the values of the interpolation points in a gradient scale. This object is used by ColorScale, DataBar and IconSet classes
|
4
|
+
#
|
5
|
+
# @note The recommended way to manage these rules is via Worksheet#add_conditional_formatting
|
6
|
+
# @see Worksheet#add_conditional_formatting
|
7
|
+
# @see ConditionalFormattingRule#initialize
|
8
|
+
#
|
9
|
+
class Cfvo
|
10
|
+
|
11
|
+
# Type (ST_CfvoType)
|
12
|
+
# The type of this conditional formatting value object. options are num, percent, max, min, formula and percentile
|
13
|
+
# @return [Symbol]
|
14
|
+
attr_reader :type
|
15
|
+
|
16
|
+
|
17
|
+
# Type (xsd:boolean)
|
18
|
+
# For icon sets, determines whether this threshold value uses the greater than or equal to operator. 0 indicates 'greater than' is used instead of 'greater than or equal to'.
|
19
|
+
# The default value is true
|
20
|
+
# @return [Boolean]
|
21
|
+
attr_reader :gte
|
22
|
+
|
23
|
+
|
24
|
+
# Type (ST_Xstring)
|
25
|
+
# The value of the conditional formatting object
|
26
|
+
# This library will accept any value so long as it supports to_s
|
27
|
+
attr_reader :val
|
28
|
+
|
29
|
+
# Creates a new Cfvo object
|
30
|
+
# @option options [Symbol] type The type of conditional formatting value object
|
31
|
+
# @option options [Boolean] gte threshold value usage indicator
|
32
|
+
# @option options [String] val The value of the conditional formatting object
|
33
|
+
def initialize(options={})
|
34
|
+
@gte = true
|
35
|
+
options.each do |o|
|
36
|
+
self.send("#{o[0]}=", o[1]) if self.respond_to? "#{o[0]}="
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# @see type
|
41
|
+
def type=(v); Axlsx::validate_conditional_formatting_value_object_type(v); @type = v end
|
42
|
+
|
43
|
+
# @see gte
|
44
|
+
def gte=(v); Axlsx::validate_boolean(v); @gte = v end
|
45
|
+
|
46
|
+
# @see val
|
47
|
+
def val=(v)
|
48
|
+
raise ArgumentError, "#{v.inspect} must respond to to_s" unless v.respond_to?(:to_s)
|
49
|
+
@val = v.to_s
|
50
|
+
end
|
51
|
+
|
52
|
+
# serialize the Csvo object
|
53
|
+
# @param [String] str
|
54
|
+
# @return [String]
|
55
|
+
def to_xml_string(str = '')
|
56
|
+
str << '<cfvo '
|
57
|
+
str << instance_values.map { |key, value| '' << key << '="' << value.to_s << '"' }.join(' ')
|
58
|
+
str << ' />'
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
end
|
File without changes
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module Axlsx
|
2
|
+
# Conditional Format Rule color scale object
|
3
|
+
# Describes a gradated color scale in this conditional formatting rule.
|
4
|
+
|
5
|
+
# @note The recommended way to manage these rules is via Worksheet#add_conditional_formatting
|
6
|
+
# @see Worksheet#add_conditional_formatting
|
7
|
+
# @see ConditionalFormattingRule#initialize
|
8
|
+
class ColorScale
|
9
|
+
|
10
|
+
# A simple typed list of cfvos
|
11
|
+
# @return [SimpleTypedList]
|
12
|
+
# @see Cfvo
|
13
|
+
attr_reader :value_objects
|
14
|
+
|
15
|
+
# A simple types list of colors
|
16
|
+
# @return [SimpleTypedList]
|
17
|
+
# @see Color
|
18
|
+
attr_reader :colors
|
19
|
+
|
20
|
+
# creates a new ColorScale object.
|
21
|
+
# This method will yield it self so you can alter the properites of the defauls conditional formating value object (cfvo and colors
|
22
|
+
# Two value objects and two colors are created on initialization and cannot be deleted.
|
23
|
+
# @see Cfvo
|
24
|
+
# @see Color
|
25
|
+
def initialize
|
26
|
+
initialize_value_objects
|
27
|
+
initialize_colors
|
28
|
+
yield self if block_given?
|
29
|
+
end
|
30
|
+
|
31
|
+
# adds a new cfvo / color pair to the color scale and returns a hash containing
|
32
|
+
# a reference to the newly created cfvo and color objects so you can alter the default properties.
|
33
|
+
# @return [Hash] a hash with :cfvo and :color keys referencing the newly added objects.
|
34
|
+
def add(options={})
|
35
|
+
@value_objects << Cfvo.new(:type => options[:type] || :min, :val => options[:val] || 0)
|
36
|
+
@colors << Color.new(:rgb => options[:color] || "FF000000")
|
37
|
+
{:cfvo => @value_objects.last, :color => @colors.last}
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
# removes the cfvo and color pair at the index specified.
|
42
|
+
# @param [Integer] index The index of the cfvo and color object to delete
|
43
|
+
# @note you cannot remove the first two cfvo and color pairs
|
44
|
+
def delete_at(index=2)
|
45
|
+
@value_objects.delete_at index
|
46
|
+
@colors.delete_at index
|
47
|
+
end
|
48
|
+
|
49
|
+
# Serialize this color_scale object data to an xml string
|
50
|
+
# @param [String] str
|
51
|
+
# @return [String]
|
52
|
+
def to_xml_string(str = '')
|
53
|
+
str << '<colorScale>'
|
54
|
+
@value_objects.each { |cfvo| cfvo.to_xml_string(str) }
|
55
|
+
@colors.each { |color| color.to_xml_string(str) }
|
56
|
+
str << '</colorScale>'
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
# creates the initial cfvo objects
|
62
|
+
def initialize_value_objects
|
63
|
+
@value_objects = SimpleTypedList.new Cfvo
|
64
|
+
@value_objects.concat [Cfvo.new(:type => :min, :val => 0), Cfvo.new(:type => :max, :val => 0)]
|
65
|
+
@value_objects.lock
|
66
|
+
end
|
67
|
+
|
68
|
+
# creates the initial color objects
|
69
|
+
def initialize_colors
|
70
|
+
@colors = SimpleTypedList.new Color
|
71
|
+
@colors.concat [Color.new(:rgb => "FFFF0000"), Color.new(:rgb => "FF0000FF")]
|
72
|
+
@colors.lock
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
end
|