write_xlsx 0.90.0 → 0.97.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Changes +37 -0
- data/README.md +1 -1
- data/examples/a_simple.rb +1 -6
- data/examples/conditional_format.rb +73 -46
- data/examples/demo.rb +1 -7
- data/examples/hyperlink1.rb +4 -11
- data/lib/write_xlsx/chart.rb +81 -205
- data/lib/write_xlsx/chart/axis.rb +2 -2
- data/lib/write_xlsx/chart/caption.rb +3 -1
- data/lib/write_xlsx/chart/pie.rb +2 -0
- data/lib/write_xlsx/chart/series.rb +11 -7
- data/lib/write_xlsx/format.rb +15 -11
- data/lib/write_xlsx/package/conditional_format.rb +351 -38
- data/lib/write_xlsx/package/content_types.rb +10 -0
- data/lib/write_xlsx/package/custom.rb +125 -0
- data/lib/write_xlsx/package/packager.rb +26 -0
- data/lib/write_xlsx/package/styles.rb +53 -21
- data/lib/write_xlsx/package/table.rb +11 -4
- data/lib/write_xlsx/utility.rb +234 -34
- data/lib/write_xlsx/version.rb +1 -1
- data/lib/write_xlsx/workbook.rb +88 -1
- data/lib/write_xlsx/worksheet.rb +247 -23
- data/test/helper.rb +6 -1
- data/test/regression/_test_hyperlink31.rb +26 -0
- data/test/regression/images/zero_dpi.jpg +0 -0
- data/test/regression/test_chart_bar08.rb +3 -0
- data/test/regression/test_chart_bar11.rb +3 -0
- data/test/regression/test_chart_bar14.rb +3 -0
- data/test/regression/test_chart_chartarea05.rb +16 -17
- data/test/regression/test_chart_chartarea06.rb +49 -0
- data/test/regression/test_chart_data_labels25.rb +61 -0
- data/test/regression/test_chart_format26.rb +48 -0
- data/test/regression/test_chart_format27.rb +58 -0
- data/test/regression/test_chart_format28.rb +52 -0
- data/test/regression/test_chart_format29.rb +59 -0
- data/test/regression/test_chart_format30.rb +53 -0
- data/test/regression/test_chart_format31.rb +60 -0
- data/test/regression/test_chart_table03.rb +56 -0
- data/test/regression/test_cond_format14.rb +42 -0
- data/test/regression/test_cond_format15.rb +53 -0
- data/test/regression/test_cond_format16.rb +53 -0
- data/test/regression/test_cond_format17.rb +37 -0
- data/test/regression/test_cond_format18.rb +136 -0
- data/test/regression/test_date_1904_01.rb +1 -1
- data/test/regression/test_escapes04.rb +3 -0
- data/test/regression/test_escapes05.rb +3 -0
- data/test/regression/test_escapes07.rb +3 -0
- data/test/regression/test_escapes08.rb +3 -0
- data/test/regression/test_hyperlink01.rb +3 -0
- data/test/regression/test_hyperlink02.rb +3 -0
- data/test/regression/test_hyperlink03.rb +4 -0
- data/test/regression/test_hyperlink04.rb +3 -0
- data/test/regression/test_hyperlink05.rb +3 -0
- data/test/regression/test_hyperlink06.rb +3 -0
- data/test/regression/test_hyperlink07.rb +3 -0
- data/test/regression/test_hyperlink08.rb +3 -0
- data/test/regression/test_hyperlink09.rb +3 -0
- data/test/regression/test_hyperlink10.rb +3 -0
- data/test/regression/test_hyperlink11.rb +3 -0
- data/test/regression/test_hyperlink12.rb +3 -0
- data/test/regression/test_hyperlink13.rb +3 -0
- data/test/regression/test_hyperlink14.rb +3 -0
- data/test/regression/test_hyperlink15.rb +3 -0
- data/test/regression/test_hyperlink16.rb +3 -0
- data/test/regression/test_hyperlink17.rb +3 -0
- data/test/regression/test_hyperlink18.rb +3 -0
- data/test/regression/test_hyperlink20.rb +3 -0
- data/test/regression/test_hyperlink21.rb +3 -0
- data/test/regression/test_hyperlink22.rb +3 -0
- data/test/regression/test_hyperlink23.rb +3 -0
- data/test/regression/test_hyperlink24.rb +3 -0
- data/test/regression/test_hyperlink25.rb +3 -0
- data/test/regression/test_hyperlink26.rb +3 -0
- data/test/regression/test_hyperlink27.rb +3 -0
- data/test/regression/test_hyperlink28.rb +50 -0
- data/test/regression/test_hyperlink29.rb +27 -0
- data/test/regression/test_hyperlink30.rb +36 -0
- data/test/regression/test_image35.rb +26 -0
- data/test/regression/test_properties01.rb +1 -4
- data/test/regression/test_properties02.rb +1 -4
- data/test/regression/test_properties03.rb +26 -0
- data/test/regression/test_properties04.rb +61 -0
- data/test/regression/test_properties05.rb +30 -0
- data/test/regression/test_table03.rb +3 -0
- data/test/regression/test_table04.rb +3 -0
- data/test/regression/test_table05.rb +3 -0
- data/test/regression/test_table06.rb +3 -0
- data/test/regression/test_table20.rb +34 -0
- data/test/regression/test_table21.rb +36 -0
- data/test/regression/test_table22.rb +32 -0
- data/test/regression/xlsx_files/chart_chartarea05.xlsx +0 -0
- data/test/regression/xlsx_files/chart_chartarea06.xlsx +0 -0
- data/test/regression/xlsx_files/chart_data_labels25.xlsx +0 -0
- data/test/regression/xlsx_files/chart_format26.xlsx +0 -0
- data/test/regression/xlsx_files/chart_format27.xlsx +0 -0
- data/test/regression/xlsx_files/chart_format28.xlsx +0 -0
- data/test/regression/xlsx_files/chart_format29.xlsx +0 -0
- data/test/regression/xlsx_files/chart_format30.xlsx +0 -0
- data/test/regression/xlsx_files/chart_format31.xlsx +0 -0
- data/test/regression/xlsx_files/chart_table03.xlsx +0 -0
- data/test/regression/xlsx_files/cond_format14.xlsx +0 -0
- data/test/regression/xlsx_files/cond_format15.xlsx +0 -0
- data/test/regression/xlsx_files/cond_format16.xlsx +0 -0
- data/test/regression/xlsx_files/cond_format17.xlsx +0 -0
- data/test/regression/xlsx_files/cond_format18.xlsx +0 -0
- data/test/regression/xlsx_files/date_1904_01.xlsx +0 -0
- data/test/regression/xlsx_files/hyperlink28.xlsx +0 -0
- data/test/regression/xlsx_files/hyperlink29.xlsx +0 -0
- data/test/regression/xlsx_files/hyperlink30.xlsx +0 -0
- data/test/regression/xlsx_files/hyperlink31.xlsx +0 -0
- data/test/regression/xlsx_files/image35.xlsx +0 -0
- data/test/regression/xlsx_files/properties03.xlsx +0 -0
- data/test/regression/xlsx_files/properties04.xlsx +0 -0
- data/test/regression/xlsx_files/properties05.xlsx +0 -0
- data/test/regression/xlsx_files/table21.xlsx +0 -0
- data/test/regression/xlsx_files/table22.xlsx +0 -0
- data/test/workbook/test_write_workbook_view.rb +81 -0
- data/test/worksheet/test_cond_format_22.rb +266 -0
- data/test/worksheet/test_cond_format_23.rb +242 -0
- data/test/worksheet/test_cond_format_24.rb +303 -0
- data/test/worksheet/test_data_bar_01.rb +53 -0
- data/test/worksheet/test_data_bar_02.rb +79 -0
- data/test/worksheet/test_data_bar_03.rb +147 -0
- data/test/worksheet/test_data_bar_04.rb +145 -0
- data/test/worksheet/test_data_bar_05.rb +147 -0
- data/test/worksheet/test_data_bar_06.rb +145 -0
- data/test/worksheet/test_data_bar_07.rb +146 -0
- data/test/worksheet/test_data_bar_08.rb +54 -0
- data/test/worksheet/test_data_bar_09.rb +80 -0
- data/test/worksheet/test_data_bar_10.rb +165 -0
- data/test/worksheet/test_data_bar_11.rb +167 -0
- data/test/worksheet/test_data_bar_12.rb +104 -0
- data/test/worksheet/test_write_data_validation_02.rb +27 -0
- metadata +135 -2
@@ -184,8 +184,8 @@ def set_position_axis
|
|
184
184
|
end
|
185
185
|
|
186
186
|
def set_font_properties(args)
|
187
|
-
@num_font =
|
188
|
-
@name_font =
|
187
|
+
@num_font = convert_font_args(args[:num_font])
|
188
|
+
@name_font = convert_font_args(args[:name_font])
|
189
189
|
end
|
190
190
|
|
191
191
|
def set_axis_name_layout(args)
|
@@ -3,6 +3,8 @@
|
|
3
3
|
module Writexlsx
|
4
4
|
class Chart
|
5
5
|
class Caption
|
6
|
+
include Writexlsx::Utility
|
7
|
+
|
6
8
|
attr_accessor :name, :formula, :data_id, :name_font
|
7
9
|
attr_reader :layout, :overlay, :none
|
8
10
|
|
@@ -13,7 +15,7 @@ def initialize(chart)
|
|
13
15
|
def merge_with_hash(params) # :nodoc:
|
14
16
|
@name, @formula = @chart.process_names(params[:name], params[:name_formula])
|
15
17
|
@data_id = @chart.data_id(@formula, params[:data])
|
16
|
-
@name_font =
|
18
|
+
@name_font = convert_font_args(params[:name_font])
|
17
19
|
@layout = @chart.layout_properties(params[:layout], 1)
|
18
20
|
|
19
21
|
# Set the title overlay option.
|
data/lib/write_xlsx/chart/pie.rb
CHANGED
@@ -57,16 +57,20 @@ def initialize(params)
|
|
57
57
|
|
58
58
|
class Trendline < Chartline
|
59
59
|
attr_reader :name, :forward, :backward, :order, :period
|
60
|
+
attr_reader :intercept, :display_equation, :display_r_squared
|
60
61
|
|
61
62
|
def initialize(params)
|
62
63
|
super(params)
|
63
64
|
|
64
|
-
@name
|
65
|
-
@forward
|
66
|
-
@backward
|
67
|
-
@order
|
68
|
-
@period
|
69
|
-
@
|
65
|
+
@name = params[:name]
|
66
|
+
@forward = params[:forward]
|
67
|
+
@backward = params[:backward]
|
68
|
+
@order = params[:order]
|
69
|
+
@period = params[:period]
|
70
|
+
@intercept = params[:intercept]
|
71
|
+
@display_equation = params[:display_equation]
|
72
|
+
@display_r_squared = params[:display_r_squared]
|
73
|
+
@type = value_or_raise(types, params[:type], 'trendline type')
|
70
74
|
end
|
71
75
|
|
72
76
|
private
|
@@ -293,7 +297,7 @@ def labels_properties(labels) # :nodoc:
|
|
293
297
|
end
|
294
298
|
|
295
299
|
if labels[:font]
|
296
|
-
labels[:font] =
|
300
|
+
labels[:font] = convert_font_args(labels[:font])
|
297
301
|
end
|
298
302
|
|
299
303
|
labels
|
data/lib/write_xlsx/format.rb
CHANGED
@@ -163,7 +163,7 @@ class Format
|
|
163
163
|
include Writexlsx::Utility
|
164
164
|
|
165
165
|
attr_reader :xf_index, :dxf_index, :num_format # :nodoc:
|
166
|
-
attr_reader :underline, :font_script, :size, :theme, :font, :font_family, :hyperlink # :nodoc:
|
166
|
+
attr_reader :underline, :font_script, :size, :theme, :font, :font_family, :hyperlink, :xf_id # :nodoc:
|
167
167
|
attr_reader :diag_type, :diag_color, :font_only, :color, :color_indexed # :nodoc:
|
168
168
|
attr_reader :left, :left_color, :right, :right_color, :top, :top_color, :bottom, :bottom_color # :nodoc:
|
169
169
|
attr_reader :font_scheme # :nodoc:
|
@@ -200,6 +200,7 @@ def initialize(formats, params = {}) # :nodoc:
|
|
200
200
|
@font_extend = 0
|
201
201
|
@theme = 0
|
202
202
|
@hyperlink = 0
|
203
|
+
@xf_id = 0
|
203
204
|
|
204
205
|
@hidden = 0
|
205
206
|
@locked = 1
|
@@ -396,7 +397,8 @@ def get_font_key
|
|
396
397
|
@font,
|
397
398
|
@italic,
|
398
399
|
@size,
|
399
|
-
@underline
|
400
|
+
@underline,
|
401
|
+
@theme
|
400
402
|
].join(':')
|
401
403
|
end
|
402
404
|
|
@@ -593,15 +595,15 @@ def set_rotation(rotation)
|
|
593
595
|
end
|
594
596
|
|
595
597
|
#
|
596
|
-
# Set the properties for the hyperlink style.
|
597
|
-
#
|
598
|
+
# Set the properties for the hyperlink style. This isn't a public method. To
|
599
|
+
# be fixed when styles are supported.
|
598
600
|
#
|
599
|
-
def set_hyperlink
|
600
|
-
@
|
601
|
+
def set_hyperlink(hyperlink)
|
602
|
+
@xf_id = 1
|
601
603
|
|
602
604
|
set_underline(1)
|
603
605
|
set_theme(10)
|
604
|
-
|
606
|
+
@hyperlink = hyperlink
|
605
607
|
end
|
606
608
|
|
607
609
|
def set_font_info(fonts)
|
@@ -804,11 +806,11 @@ def xf_attributes
|
|
804
806
|
['fontId' , font_index],
|
805
807
|
['fillId' , fill_index],
|
806
808
|
['borderId', border_index],
|
807
|
-
['xfId' ,
|
809
|
+
['xfId' , xf_id]
|
808
810
|
]
|
809
811
|
attributes << ['applyNumberFormat', 1] if num_format_index > 0
|
810
812
|
# Add applyFont attribute if XF format uses a font element.
|
811
|
-
attributes << ['applyFont', 1] if font_index > 0
|
813
|
+
attributes << ['applyFont', 1] if font_index > 0 && !ptrue?(@hyperlink)
|
812
814
|
# Add applyFill attribute if XF format uses a fill element.
|
813
815
|
attributes << ['applyFill', 1] if fill_index > 0
|
814
816
|
# Add applyBorder attribute if XF format uses a border element.
|
@@ -817,8 +819,10 @@ def xf_attributes
|
|
817
819
|
# Check if XF format has alignment properties set.
|
818
820
|
apply_align, align = get_align_properties
|
819
821
|
# We can also have applyAlignment without a sub-element.
|
820
|
-
attributes << ['applyAlignment', 1] if apply_align
|
821
|
-
|
822
|
+
attributes << ['applyAlignment', 1] if apply_align || ptrue?(@hyperlink)
|
823
|
+
if get_protection_properties || ptrue?(hyperlink)
|
824
|
+
attributes << ['applyProtection', 1]
|
825
|
+
end
|
822
826
|
|
823
827
|
attributes
|
824
828
|
end
|
@@ -7,8 +7,8 @@ class ConditionalFormat
|
|
7
7
|
|
8
8
|
def self.factory(worksheet, *args)
|
9
9
|
range, param =
|
10
|
-
|
11
|
-
|
10
|
+
Package::ConditionalFormat.new(worksheet, nil, nil).
|
11
|
+
range_param_for_conditional_formatting(*args)
|
12
12
|
|
13
13
|
case param[:type]
|
14
14
|
when 'cellIs'
|
@@ -29,6 +29,8 @@ def self.factory(worksheet, *args)
|
|
29
29
|
DataBarFormat.new(worksheet, range, param)
|
30
30
|
when 'expression'
|
31
31
|
ExpressionFormat.new(worksheet, range, param)
|
32
|
+
when 'iconSet'
|
33
|
+
IconSetFormat.new(worksheet, range, param)
|
32
34
|
else # when 'duplicateValues', 'uniqueValues'
|
33
35
|
ConditionalFormat.new(worksheet, range, param)
|
34
36
|
end
|
@@ -59,11 +61,13 @@ def write_formula_tag(data) #:nodoc:
|
|
59
61
|
#
|
60
62
|
# Write the <cfvo> element.
|
61
63
|
#
|
62
|
-
def write_cfvo(type,
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
64
|
+
def write_cfvo(type, value, criteria = nil)
|
65
|
+
attributes = [ ['type', type] ]
|
66
|
+
attributes << [ 'val', value] if value
|
67
|
+
|
68
|
+
attributes << ['gte', 0] if ptrue?(criteria)
|
69
|
+
|
70
|
+
@writer.empty_tag('cfvo', attributes)
|
67
71
|
end
|
68
72
|
|
69
73
|
def attributes
|
@@ -154,6 +158,54 @@ def bar_color
|
|
154
158
|
@param[:bar_color]
|
155
159
|
end
|
156
160
|
|
161
|
+
def bar_border_color
|
162
|
+
@param[:bar_border_color]
|
163
|
+
end
|
164
|
+
|
165
|
+
def bar_negative_color
|
166
|
+
@param[:bar_negative_color]
|
167
|
+
end
|
168
|
+
|
169
|
+
def bar_negative_color_same
|
170
|
+
@param[:bar_negative_color_same]
|
171
|
+
end
|
172
|
+
|
173
|
+
def bar_no_border
|
174
|
+
@param[:bar_no_border]
|
175
|
+
end
|
176
|
+
|
177
|
+
def bar_axis_position
|
178
|
+
@param[:bar_axis_position]
|
179
|
+
end
|
180
|
+
|
181
|
+
def bar_axis_color
|
182
|
+
@param[:bar_axis_color]
|
183
|
+
end
|
184
|
+
|
185
|
+
def icon_style
|
186
|
+
@param[:icon_style]
|
187
|
+
end
|
188
|
+
|
189
|
+
def total_icons
|
190
|
+
@param[:total_icons]
|
191
|
+
end
|
192
|
+
|
193
|
+
def icons
|
194
|
+
@param[:icons]
|
195
|
+
end
|
196
|
+
|
197
|
+
def icons_only
|
198
|
+
@param[:icons_only]
|
199
|
+
end
|
200
|
+
|
201
|
+
def reverse_icons
|
202
|
+
@param[:reverse_icons]
|
203
|
+
end
|
204
|
+
|
205
|
+
def bar_only
|
206
|
+
@param[:bar_only]
|
207
|
+
end
|
208
|
+
|
157
209
|
def range_param_for_conditional_formatting(*args) # :nodoc:
|
158
210
|
range_start_cell_for_conditional_formatting(*args)
|
159
211
|
param_for_conditional_formatting(*args)
|
@@ -274,17 +326,68 @@ def handling_of_blanks_error_types
|
|
274
326
|
@param[:mid_color] = palette_color(@param[:mid_color])
|
275
327
|
@param[:min_color] = palette_color(@param[:min_color])
|
276
328
|
when 'dataBar'
|
277
|
-
#
|
329
|
+
# Excel 2007 data bars don't use any additional formatting.
|
278
330
|
@param[:format] = nil
|
279
331
|
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
332
|
+
if !@param[:min_type]
|
333
|
+
@param[:min_type] = 'min'
|
334
|
+
@param[:x14_min_type] = 'autoMin'
|
335
|
+
else
|
336
|
+
@param[:x14_min_type] = @param[:min_type]
|
337
|
+
end
|
338
|
+
if !@param[:max_type]
|
339
|
+
@param[:max_type] = 'max'
|
340
|
+
@param[:x14_max_type] = 'autoMax'
|
341
|
+
else
|
342
|
+
@param[:x14_max_type] = @param[:max_type]
|
343
|
+
end
|
344
|
+
|
345
|
+
@param[:min_value] ||= 0
|
346
|
+
@param[:max_value] ||= 0
|
347
|
+
@param[:bar_color] ||= '#638EC6'
|
348
|
+
@param[:bar_border_color] ||= @param[:bar_color]
|
349
|
+
@param[:bar_only] ||= 0
|
350
|
+
@param[:bar_no_border] ||= 0
|
351
|
+
@param[:bar_solid] ||= 0
|
352
|
+
@param[:bar_direction] ||= ''
|
353
|
+
@param[:bar_negative_color] ||= '#FF0000'
|
354
|
+
@param[:bar_negative_border_color] ||= '#FF0000'
|
355
|
+
@param[:bar_negative_color_same] ||= 0
|
356
|
+
@param[:bar_negative_border_color_same] ||= 0
|
357
|
+
@param[:bar_axis_position] ||= ''
|
358
|
+
@param[:bar_axis_color] ||= '#000000'
|
359
|
+
|
360
|
+
@param[:bar_color] =
|
361
|
+
palette_color(@param[:bar_color])
|
362
|
+
@param[:bar_border_color] =
|
363
|
+
palette_color(@param[:bar_border_color])
|
364
|
+
@param[:bar_negative_color] =
|
365
|
+
palette_color(@param[:bar_negative_color])
|
366
|
+
@param[:bar_negative_border_color] =
|
367
|
+
palette_color(@param[:bar_negative_border_color])
|
368
|
+
@param[:bar_axis_color] =
|
369
|
+
palette_color(@param[:bar_axis_color])
|
370
|
+
end
|
371
|
+
|
372
|
+
# Adjust for 2010 style data_bar parameters.
|
373
|
+
if ptrue?(@param[:is_data_bar_2010])
|
374
|
+
@worksheet.excel_version = 2010
|
285
375
|
|
286
|
-
@param[:
|
376
|
+
if @param[:min_type] == 'min' && @param[:min_value] == 0
|
377
|
+
@param[:min_value] = nil
|
378
|
+
end
|
379
|
+
if @param[:max_type] == 'max' && @param[:max_value] == 0
|
380
|
+
@param[:max_value] = nil
|
381
|
+
end
|
382
|
+
|
383
|
+
# Store range for Excel 2010 data bars.
|
384
|
+
@param[:range] = range
|
287
385
|
end
|
386
|
+
|
387
|
+
# Strip the leading = from formulas.
|
388
|
+
@param[:min_value] = @param[:min_value].to_s.sub(/^=/, '') if @param[:min_value]
|
389
|
+
@param[:mid_value] = @param[:mid_value].to_s.sub(/^=/, '') if @param[:mid_value]
|
390
|
+
@param[:max_value] = @param[:max_value].to_s.sub(/^=/, '') if @param[:max_value]
|
288
391
|
end
|
289
392
|
|
290
393
|
def palette_color(index)
|
@@ -293,7 +396,7 @@ def palette_color(index)
|
|
293
396
|
|
294
397
|
def range_start_cell_for_conditional_formatting(*args) # :nodoc:
|
295
398
|
row1, row2, col1, col2, user_range, param =
|
296
|
-
|
399
|
+
row_col_param_for_conditional_formatting(*args)
|
297
400
|
# If the first and last cell are the same write a single cell.
|
298
401
|
if row1 == row2 && col1 == col2
|
299
402
|
range = xl_rowcol_to_cell(row1, col1)
|
@@ -336,19 +439,32 @@ def row_col_param_for_conditional_formatting(*args)
|
|
336
439
|
|
337
440
|
def param_for_conditional_formatting(*args) # :nodoc:
|
338
441
|
dummy, dummy, dummy, dummy, dummy, @param =
|
339
|
-
|
442
|
+
row_col_param_for_conditional_formatting(*args)
|
340
443
|
check_conditional_formatting_parameters(@param)
|
341
444
|
|
342
445
|
@param[:format] = @param[:format].get_dxf_index if @param[:format]
|
343
446
|
@param[:priority] = @worksheet.dxf_priority
|
447
|
+
|
448
|
+
# Check for 2010 style data_bar parameters.
|
449
|
+
%i(data_bar_2010 bar_solid bar_border_color bar_negative_color
|
450
|
+
bar_negative_color_same bar_negative_border_color
|
451
|
+
bar_negative_border_color_same bar_no_border
|
452
|
+
bar_axis_position bar_axis_color bar_direction
|
453
|
+
).each do |key|
|
454
|
+
if @param[key]
|
455
|
+
@param[:is_data_bar_2010] = 1
|
456
|
+
break
|
457
|
+
end
|
458
|
+
end
|
459
|
+
|
344
460
|
@worksheet.dxf_priority += 1
|
345
461
|
end
|
346
462
|
|
347
463
|
def check_conditional_formatting_parameters(param) # :nodoc:
|
348
464
|
# Check for valid input parameters.
|
349
|
-
|
350
|
-
|
351
|
-
|
465
|
+
if !(param.keys.uniq - valid_parameter_for_conditional_formatting).empty? ||
|
466
|
+
!param.has_key?(:type) ||
|
467
|
+
!valid_type_for_conditional_formatting.has_key?(param[:type].downcase)
|
352
468
|
raise WriteXLSXOptionParameterError, "Invalid type : #{param[:type]}"
|
353
469
|
end
|
354
470
|
|
@@ -369,6 +485,32 @@ def check_conditional_formatting_parameters(param) # :nodoc:
|
|
369
485
|
param[:maximum] = convert_date_time_if_required(param[:maximum])
|
370
486
|
end
|
371
487
|
|
488
|
+
# Set properties for icon sets.
|
489
|
+
if param[:type] == 'iconSet'
|
490
|
+
if !param[:icon_style]
|
491
|
+
raise "The 'icon_style' parameter must be specified when " +
|
492
|
+
"'type' == 'icon_set' in conditional_formatting()"
|
493
|
+
end
|
494
|
+
|
495
|
+
# Check for valid icon styles.
|
496
|
+
if !icon_set_styles[param[:icon_style]]
|
497
|
+
raise "Unknown icon style '$param->{icon_style}' for parameter " +
|
498
|
+
"'icon_style' in conditional_formatting()"
|
499
|
+
else
|
500
|
+
param[:icon_style] = icon_set_styles[param[:icon_style]]
|
501
|
+
end
|
502
|
+
|
503
|
+
# Set the number of icons for the icon style.
|
504
|
+
param[:total_icons] = 3
|
505
|
+
if param[:icon_style] =~ /^4/
|
506
|
+
param[:total_icons] = 4
|
507
|
+
elsif param[:icon_style] =~ /^5/
|
508
|
+
param[:total_icons] = 5
|
509
|
+
end
|
510
|
+
|
511
|
+
param[:icons] = set_icon_properties(param[:total_icons], param[:icons])
|
512
|
+
end
|
513
|
+
|
372
514
|
# 'Between' and 'Not between' criteria require 2 values.
|
373
515
|
if param[:criteria] == 'between' || param[:criteria] == 'notBetween'
|
374
516
|
unless param.has_key?(:minimum) || param.has_key?(:maximum)
|
@@ -400,23 +542,39 @@ def convert_date_time_if_required(val)
|
|
400
542
|
# List of valid input parameters for conditional_formatting.
|
401
543
|
def valid_parameter_for_conditional_formatting
|
402
544
|
[
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
545
|
+
:type,
|
546
|
+
:format,
|
547
|
+
:criteria,
|
548
|
+
:value,
|
549
|
+
:minimum,
|
550
|
+
:maximum,
|
551
|
+
:stop_if_true,
|
552
|
+
:min_type,
|
553
|
+
:mid_type,
|
554
|
+
:max_type,
|
555
|
+
:min_value,
|
556
|
+
:mid_value,
|
557
|
+
:max_value,
|
558
|
+
:min_color,
|
559
|
+
:mid_color,
|
560
|
+
:max_color,
|
561
|
+
:bar_color,
|
562
|
+
:bar_negative_color,
|
563
|
+
:bar_negative_color_same,
|
564
|
+
:bar_solid,
|
565
|
+
:bar_border_color,
|
566
|
+
:bar_negative_border_color,
|
567
|
+
:bar_negative_border_color_same,
|
568
|
+
:bar_no_border,
|
569
|
+
:bar_direction,
|
570
|
+
:bar_axis_position,
|
571
|
+
:bar_axis_color,
|
572
|
+
:bar_only,
|
573
|
+
:icon_style,
|
574
|
+
:reverse_icons,
|
575
|
+
:icons_only,
|
576
|
+
:icons,
|
577
|
+
:data_bar_2010
|
420
578
|
]
|
421
579
|
end
|
422
580
|
|
@@ -440,7 +598,8 @@ def valid_type_for_conditional_formatting
|
|
440
598
|
'2_color_scale' => '2_color_scale',
|
441
599
|
'3_color_scale' => '3_color_scale',
|
442
600
|
'data_bar' => 'dataBar',
|
443
|
-
'formula' => 'expression'
|
601
|
+
'formula' => 'expression',
|
602
|
+
'icon_set' => 'iconSet'
|
444
603
|
}
|
445
604
|
end
|
446
605
|
|
@@ -479,6 +638,100 @@ def valid_criteria_type_for_conditional_formatting
|
|
479
638
|
}
|
480
639
|
end
|
481
640
|
|
641
|
+
# List of valid icon styles.
|
642
|
+
def icon_set_styles
|
643
|
+
{
|
644
|
+
"3_arrows" => "3Arrows", # 1
|
645
|
+
"3_flags" => "3Flags", # 2
|
646
|
+
"3_traffic_lights_rimmed" => "3TrafficLights2", # 3
|
647
|
+
"3_symbols_circled" => "3Symbols", # 4
|
648
|
+
"4_arrows" => "4Arrows", # 5
|
649
|
+
"4_red_to_black" => "4RedToBlack", # 6
|
650
|
+
"4_traffic_lights" => "4TrafficLights", # 7
|
651
|
+
"5_arrows_gray" => "5ArrowsGray", # 8
|
652
|
+
"5_quarters" => "5Quarters", # 9
|
653
|
+
"3_arrows_gray" => "3ArrowsGray", # 10
|
654
|
+
"3_traffic_lights" => "3TrafficLights", # 11
|
655
|
+
"3_signs" => "3Signs", # 12
|
656
|
+
"3_symbols" => "3Symbols2", # 13
|
657
|
+
"4_arrows_gray" => "4ArrowsGray", # 14
|
658
|
+
"4_ratings" => "4Rating", # 15
|
659
|
+
"5_arrows" => "5Arrows", # 16
|
660
|
+
"5_ratings" => "5Rating", # 17
|
661
|
+
}
|
662
|
+
end
|
663
|
+
|
664
|
+
#
|
665
|
+
# Set the sub-properites for icons.
|
666
|
+
#
|
667
|
+
def set_icon_properties(total_icons, user_props)
|
668
|
+
props = []
|
669
|
+
|
670
|
+
# Set the default icon properties.
|
671
|
+
total_icons.times do
|
672
|
+
props << {
|
673
|
+
:criteria => 0,
|
674
|
+
:value => 0,
|
675
|
+
:type => 'percent'
|
676
|
+
}
|
677
|
+
end
|
678
|
+
|
679
|
+
# Set the default icon values based on the number of icons.
|
680
|
+
if total_icons == 3
|
681
|
+
props[0][:value] = 67
|
682
|
+
props[1][:value] = 33
|
683
|
+
elsif total_icons == 4
|
684
|
+
props[0][:value] = 75
|
685
|
+
props[1][:value] = 50
|
686
|
+
props[2][:value] = 25
|
687
|
+
elsif total_icons == 5
|
688
|
+
props[0][:value] = 80
|
689
|
+
props[1][:value] = 60
|
690
|
+
props[2][:value] = 40
|
691
|
+
props[3][:value] = 20
|
692
|
+
end
|
693
|
+
|
694
|
+
# Overwrite default properties with user defined properties.
|
695
|
+
if user_props
|
696
|
+
|
697
|
+
# Ensure we don't set user properties for lowest icon.
|
698
|
+
max_data = user_props.size
|
699
|
+
max_data = total_icons -1 if max_data >= total_icons
|
700
|
+
|
701
|
+
(0..max_data - 1).each do |i|
|
702
|
+
# Set the user defined 'value' property.
|
703
|
+
if user_props[i][:value]
|
704
|
+
props[i][:value] = user_props[i][:value].to_s.sub(/^=/, '')
|
705
|
+
end
|
706
|
+
|
707
|
+
# Set the user defined 'type' property.
|
708
|
+
if user_props[i][:type]
|
709
|
+
|
710
|
+
type = user_props[i][:type]
|
711
|
+
|
712
|
+
if type != 'percent' && type != 'percentile' &&
|
713
|
+
type != 'number' && type != 'formula'
|
714
|
+
raise "Unknown icon property type '$props->{type}' for sub-" +
|
715
|
+
"property 'type' in conditional_formatting()"
|
716
|
+
else
|
717
|
+
props[i][:type] = type
|
718
|
+
|
719
|
+
if props[i][:type] == 'number'
|
720
|
+
props[i][:type] = 'num'
|
721
|
+
end
|
722
|
+
end
|
723
|
+
end
|
724
|
+
|
725
|
+
# Set the user defined 'criteria' property.
|
726
|
+
if user_props[i][:criteria] && user_props[i][:criteria] == '>'
|
727
|
+
props[i][:criteria] = 1
|
728
|
+
end
|
729
|
+
|
730
|
+
end
|
731
|
+
end
|
732
|
+
props
|
733
|
+
end
|
734
|
+
|
482
735
|
def date_1904?
|
483
736
|
@worksheet.date_1904?
|
484
737
|
end
|
@@ -578,6 +831,9 @@ class DataBarFormat < ConditionalFormat
|
|
578
831
|
def write_cf_rule
|
579
832
|
@writer.tag_elements('cfRule', attributes) do
|
580
833
|
write_data_bar
|
834
|
+
if ptrue?(@param[:is_data_bar_2010])
|
835
|
+
write_data_bar_ext(@param)
|
836
|
+
end
|
581
837
|
end
|
582
838
|
end
|
583
839
|
|
@@ -585,13 +841,42 @@ def write_cf_rule
|
|
585
841
|
# Write the <dataBar> element.
|
586
842
|
#
|
587
843
|
def write_data_bar
|
588
|
-
|
844
|
+
attributes = []
|
845
|
+
|
846
|
+
if ptrue?(bar_only)
|
847
|
+
attributes << ['showValue', 0]
|
848
|
+
end
|
849
|
+
@writer.tag_elements('dataBar',attributes) do
|
589
850
|
write_cfvo(min_type, min_value)
|
590
851
|
write_cfvo(max_type, max_value)
|
591
852
|
|
592
853
|
write_color(@writer, 'rgb', bar_color)
|
593
854
|
end
|
594
855
|
end
|
856
|
+
|
857
|
+
#
|
858
|
+
# Write the <extLst> dataBar extension element.
|
859
|
+
#
|
860
|
+
def write_data_bar_ext(param)
|
861
|
+
# Create a pseudo GUID for each unique Excel 2010 data bar.
|
862
|
+
worksheet_count = @worksheet.index + 1
|
863
|
+
data_bar_count = @worksheet.data_bars_2010.size + 1
|
864
|
+
|
865
|
+
guid = sprintf(
|
866
|
+
"{DA7ABA51-AAAA-BBBB-%04X-%012X}",
|
867
|
+
worksheet_count, data_bar_count
|
868
|
+
)
|
869
|
+
|
870
|
+
# Store the 2010 data bar parameters to write the extLst elements.
|
871
|
+
param[:guid] = guid
|
872
|
+
@worksheet.data_bars_2010 << param
|
873
|
+
|
874
|
+
@writer.tag_elements('extLst') do
|
875
|
+
@worksheet.write_ext('{B025F937-C7B1-47D3-B67F-A62EFF666E3E}') do
|
876
|
+
@writer.data_element('x14:id', guid)
|
877
|
+
end
|
878
|
+
end
|
879
|
+
end
|
595
880
|
end
|
596
881
|
|
597
882
|
class ExpressionFormat < ConditionalFormat
|
@@ -599,5 +884,33 @@ def write_cf_rule
|
|
599
884
|
write_cf_rule_formula_tag(criteria)
|
600
885
|
end
|
601
886
|
end
|
887
|
+
|
888
|
+
class IconSetFormat < ConditionalFormat
|
889
|
+
def write_cf_rule
|
890
|
+
@writer.tag_elements('cfRule', attributes) do
|
891
|
+
write_icon_set
|
892
|
+
end
|
893
|
+
end
|
894
|
+
|
895
|
+
#
|
896
|
+
# Write the <iconSet> element.
|
897
|
+
#
|
898
|
+
def write_icon_set
|
899
|
+
attributes = []
|
900
|
+
# Don't set attribute for default style.
|
901
|
+
attributes = [ ['iconSet', icon_style] ] if icon_style != '3TrafficLights'
|
902
|
+
attributes << ['showValue', 0] if icons_only
|
903
|
+
attributes << ['reverse', 1] if reverse_icons
|
904
|
+
|
905
|
+
@writer.tag_elements('iconSet', attributes) do
|
906
|
+
# Write the properties for different icon styles.
|
907
|
+
if icons
|
908
|
+
icons.reverse.each do |icon|
|
909
|
+
write_cfvo(icon[:type], icon[:value], icon[:criteria])
|
910
|
+
end
|
911
|
+
end
|
912
|
+
end
|
913
|
+
end
|
914
|
+
end
|
602
915
|
end
|
603
916
|
end
|