write_xlsx 1.11.0 → 1.11.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.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -1
- data/Changes +12 -0
- data/examples/shape_all.rb +1 -1
- data/lib/write_xlsx/chart/area.rb +1 -0
- data/lib/write_xlsx/chart/axis.rb +1 -0
- data/lib/write_xlsx/chart/bar.rb +1 -0
- data/lib/write_xlsx/chart/caption.rb +1 -0
- data/lib/write_xlsx/chart/column.rb +1 -0
- data/lib/write_xlsx/chart/doughnut.rb +1 -0
- data/lib/write_xlsx/chart/legend.rb +1 -0
- data/lib/write_xlsx/chart/line.rb +1 -0
- data/lib/write_xlsx/chart/pie.rb +15 -2
- data/lib/write_xlsx/chart/radar.rb +1 -0
- data/lib/write_xlsx/chart/scatter.rb +1 -0
- data/lib/write_xlsx/chart/series.rb +56 -4
- data/lib/write_xlsx/chart/stock.rb +1 -0
- data/lib/write_xlsx/chart.rb +107 -23
- data/lib/write_xlsx/chartsheet.rb +10 -1
- data/lib/write_xlsx/col_name.rb +7 -3
- data/lib/write_xlsx/colors.rb +20 -19
- data/lib/write_xlsx/format.rb +10 -8
- data/lib/write_xlsx/package/app.rb +9 -5
- data/lib/write_xlsx/package/comments.rb +2 -1
- data/lib/write_xlsx/package/conditional_format.rb +6 -6
- data/lib/write_xlsx/package/packager.rb +2 -3
- data/lib/write_xlsx/package/styles.rb +11 -13
- data/lib/write_xlsx/package/table.rb +74 -20
- data/lib/write_xlsx/package/xml_writer_simple.rb +32 -44
- data/lib/write_xlsx/sheets.rb +6 -2
- data/lib/write_xlsx/sparkline.rb +2 -2
- data/lib/write_xlsx/utility.rb +14 -12
- data/lib/write_xlsx/version.rb +1 -1
- data/lib/write_xlsx/workbook.rb +2 -3
- data/lib/write_xlsx/worksheet/cell_data.rb +17 -18
- data/lib/write_xlsx/worksheet/hyperlink.rb +2 -2
- data/lib/write_xlsx/worksheet.rb +90 -39
- data/write_xlsx.gemspec +2 -0
- metadata +31 -3
@@ -411,7 +411,7 @@ module Writexlsx
|
|
411
411
|
# Check for a cell reference in A1 notation and substitute row and column
|
412
412
|
user_range = if args[0].to_s =~ (/^\D/) && (args[0] =~ /,/)
|
413
413
|
# Check for a user defined multiple range like B3:K6,B8:K11.
|
414
|
-
args[0].sub(/^=/, '').gsub(/\s*,\s*/, ' ').gsub(
|
414
|
+
args[0].sub(/^=/, '').gsub(/\s*,\s*/, ' ').gsub("$", '')
|
415
415
|
end
|
416
416
|
|
417
417
|
if (row_col_array = row_col_notation(args.first))
|
@@ -769,7 +769,7 @@ module Writexlsx
|
|
769
769
|
attr = super
|
770
770
|
attr << ['percent', 1] if criteria == '%'
|
771
771
|
attr << ['bottom', 1] if direction
|
772
|
-
attr << ['rank',
|
772
|
+
attr << ['rank', value || 10]
|
773
773
|
attr
|
774
774
|
end
|
775
775
|
end
|
@@ -818,9 +818,9 @@ module Writexlsx
|
|
818
818
|
write_cfvo(min_type, min_value)
|
819
819
|
write_cfvo(mid_type, mid_value) if mid_type
|
820
820
|
write_cfvo(max_type, max_value)
|
821
|
-
write_color(
|
822
|
-
write_color(
|
823
|
-
write_color(
|
821
|
+
write_color('rgb', min_color)
|
822
|
+
write_color('rgb', mid_color) if mid_color
|
823
|
+
write_color('rgb', max_color)
|
824
824
|
end
|
825
825
|
end
|
826
826
|
end
|
@@ -844,7 +844,7 @@ module Writexlsx
|
|
844
844
|
write_cfvo(min_type, min_value)
|
845
845
|
write_cfvo(max_type, max_value)
|
846
846
|
|
847
|
-
write_color(
|
847
|
+
write_color('rgb', bar_color)
|
848
848
|
end
|
849
849
|
end
|
850
850
|
|
@@ -142,13 +142,12 @@ module Writexlsx
|
|
142
142
|
def write_app_file
|
143
143
|
app = Package::App.new(@workbook)
|
144
144
|
|
145
|
+
# Add the Worksheet parts.
|
146
|
+
app.add_worksheet_part_names
|
145
147
|
# Add the Worksheet heading pairs.
|
146
148
|
app.add_worksheet_heading_pairs
|
147
149
|
# Add the Chartsheet heading pairs.
|
148
150
|
app.add_chartsheet_heading_pairs
|
149
|
-
|
150
|
-
# Add the Worksheet parts.
|
151
|
-
app.add_worksheet_part_names
|
152
151
|
# Add the Chartsheet parts.
|
153
152
|
app.add_chartsheet_part_names
|
154
153
|
# Add the Named Range heading pairs.
|
@@ -59,6 +59,8 @@ module Writexlsx
|
|
59
59
|
def palette_color(index)
|
60
60
|
if index.to_s =~ /^#([0-9A-F]{6})$/i
|
61
61
|
"FF#{::Regexp.last_match(1).upcase}"
|
62
|
+
elsif index == 0x40
|
63
|
+
"Automatic"
|
62
64
|
else
|
63
65
|
"FF#{super(index)}"
|
64
66
|
end
|
@@ -186,15 +188,6 @@ module Writexlsx
|
|
186
188
|
end
|
187
189
|
end
|
188
190
|
|
189
|
-
#
|
190
|
-
# Write the <color> element.
|
191
|
-
#
|
192
|
-
def write_color(name, value)
|
193
|
-
attributes = [[name, value]]
|
194
|
-
|
195
|
-
@writer.empty_tag('color', attributes)
|
196
|
-
end
|
197
|
-
|
198
191
|
#
|
199
192
|
# Write the <fills> element.
|
200
193
|
#
|
@@ -284,10 +277,14 @@ module Writexlsx
|
|
284
277
|
def write_pattern_fill(format, dxf_format)
|
285
278
|
bg_color, fg_color = bg_and_fg_color(format, dxf_format)
|
286
279
|
|
287
|
-
|
280
|
+
if fg_color && fg_color != 0 && fg_color != 0x40 # 'Automatic'
|
281
|
+
@writer.empty_tag('fgColor', [['rgb', palette_color(fg_color)]])
|
282
|
+
end
|
288
283
|
|
289
284
|
if bg_color && bg_color != 0
|
290
|
-
|
285
|
+
if bg_color != 0x40 # 'Automatic'
|
286
|
+
@writer.empty_tag('bgColor', [['rgb', palette_color(bg_color)]])
|
287
|
+
end
|
291
288
|
elsif !dxf_format && format.pattern <= 1
|
292
289
|
@writer.empty_tag('bgColor', [['indexed', 64]])
|
293
290
|
end
|
@@ -390,10 +387,11 @@ module Writexlsx
|
|
390
387
|
attributes = [[:style, BORDER_STYLES[style]]]
|
391
388
|
|
392
389
|
@writer.tag_elements(type, attributes) do
|
393
|
-
if color
|
390
|
+
if [0, 0x40].include?(color) # 'Automatic'
|
394
391
|
@writer.empty_tag('color', [['auto', 1]])
|
395
|
-
|
392
|
+
elsif color != 0 && color != 0x40 # 'Automatic'
|
396
393
|
color = palette_color(color)
|
394
|
+
|
397
395
|
@writer.empty_tag('color', [['rgb', color]])
|
398
396
|
end
|
399
397
|
end
|
@@ -12,13 +12,14 @@ module Writexlsx
|
|
12
12
|
class ColumnData
|
13
13
|
attr_reader :id
|
14
14
|
attr_accessor :name, :format, :formula, :name_format
|
15
|
-
attr_accessor :total_string, :total_function
|
15
|
+
attr_accessor :total_string, :total_function, :custom_total
|
16
16
|
|
17
17
|
def initialize(id, param = {})
|
18
18
|
@id = id
|
19
19
|
@name = "Column#{id}"
|
20
20
|
@total_string = ''
|
21
21
|
@total_function = ''
|
22
|
+
@custom_total = ''
|
22
23
|
@formula = ''
|
23
24
|
@format = nil
|
24
25
|
@name_format = nil
|
@@ -51,6 +52,7 @@ module Writexlsx
|
|
51
52
|
|
52
53
|
add_the_table_columns
|
53
54
|
write_the_cell_data_if_supplied
|
55
|
+
write_any_columns_formulas_after_the_user_supplied_table_data
|
54
56
|
store_filter_cell_positions
|
55
57
|
end
|
56
58
|
|
@@ -78,7 +80,7 @@ module Writexlsx
|
|
78
80
|
# Set up the default column data.
|
79
81
|
col_data = Package::Table::ColumnData.new(col_id + 1, @param[:columns])
|
80
82
|
|
81
|
-
|
83
|
+
overwrite_the_defaults_with_any_use_defined_values(col_id, col_data, col_num)
|
82
84
|
|
83
85
|
# Store the column data.
|
84
86
|
@columns << col_data
|
@@ -89,7 +91,7 @@ module Writexlsx
|
|
89
91
|
end # Table columns.
|
90
92
|
end
|
91
93
|
|
92
|
-
def
|
94
|
+
def overwrite_the_defaults_with_any_use_defined_values(col_id, col_data, col_num)
|
93
95
|
# Check if there are user defined values for this column.
|
94
96
|
if @param[:columns] && (user_data = @param[:columns][col_id])
|
95
97
|
# Map user defined values to internal values.
|
@@ -156,6 +158,23 @@ module Writexlsx
|
|
156
158
|
end
|
157
159
|
end
|
158
160
|
|
161
|
+
def write_any_columns_formulas_after_the_user_supplied_table_data
|
162
|
+
col_id = 0
|
163
|
+
|
164
|
+
(@col1..@col2).each do |col|
|
165
|
+
column_data = @columns[col_id]
|
166
|
+
if ptrue?(column_data) && ptrue?(column_data.formula)
|
167
|
+
formula_format = @col_formats[col_id]
|
168
|
+
formula = column_data.formula
|
169
|
+
|
170
|
+
(@first_data_row..@last_data_row).each do |row|
|
171
|
+
@worksheet.write_formula(row, col, formula, formula_format)
|
172
|
+
end
|
173
|
+
end
|
174
|
+
col_id += 1
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
159
178
|
def store_filter_cell_positions
|
160
179
|
if ptrue?(@param[:autofilter])
|
161
180
|
(@col1..@col2).each do |col|
|
@@ -234,25 +253,45 @@ module Writexlsx
|
|
234
253
|
]
|
235
254
|
end
|
236
255
|
|
237
|
-
def handle_the_column_formula(col_data,
|
256
|
+
def handle_the_column_formula(col_data, _col_num, formula, _format)
|
238
257
|
return unless formula
|
239
258
|
|
240
|
-
|
259
|
+
formula = formula.sub(/^=/, '').gsub(/@/, '[#This Row],')
|
241
260
|
|
242
|
-
|
243
|
-
|
244
|
-
|
261
|
+
# Escape any future functions.
|
262
|
+
col_data.formula = @worksheet.prepare_formula(formula, 1)
|
263
|
+
|
264
|
+
# (@first_data_row..@last_data_row).each do |row|
|
265
|
+
# @worksheet.write_formula(row, col_num, col_data.formula, format)
|
266
|
+
# end
|
245
267
|
end
|
246
268
|
|
247
269
|
def handle_the_function_for_the_table_row(row2, col_data, col_num, user_data)
|
248
|
-
|
270
|
+
formula = ''
|
271
|
+
function = user_data[:total_function]
|
272
|
+
function = 'countNums' if function == 'count_nums'
|
273
|
+
function = 'stdDev' if function == 'std_dev'
|
249
274
|
|
250
|
-
|
251
|
-
|
275
|
+
subtotals = {
|
276
|
+
average: 101,
|
277
|
+
countNums: 102,
|
278
|
+
count: 103,
|
279
|
+
max: 104,
|
280
|
+
min: 105,
|
281
|
+
stdDev: 106,
|
282
|
+
sum: 109,
|
283
|
+
var: 110
|
284
|
+
}
|
252
285
|
|
253
|
-
|
286
|
+
if subtotals[function.to_sym]
|
287
|
+
formula = table_function_to_formula(function, col_data.name)
|
288
|
+
else
|
289
|
+
formula = @worksheet.prepare_formula(function, 1)
|
290
|
+
col_data.custom_total = formula
|
291
|
+
function = 'custom'
|
292
|
+
end
|
254
293
|
|
255
|
-
|
294
|
+
col_data.total_function = function
|
256
295
|
@worksheet.write_formula(row2, col_num, formula, user_data[:format], user_data[:total_value])
|
257
296
|
end
|
258
297
|
|
@@ -260,10 +299,10 @@ module Writexlsx
|
|
260
299
|
# Convert a table total function to a worksheet formula.
|
261
300
|
#
|
262
301
|
def table_function_to_formula(function, col_name)
|
263
|
-
col_name = col_name.gsub(
|
264
|
-
.gsub(
|
265
|
-
.gsub(
|
266
|
-
.gsub(
|
302
|
+
col_name = col_name.gsub("'", "''")
|
303
|
+
.gsub("#", "'#")
|
304
|
+
.gsub("[", "'[")
|
305
|
+
.gsub("]", "']")
|
267
306
|
|
268
307
|
subtotals = {
|
269
308
|
average: 101,
|
@@ -395,10 +434,16 @@ module Writexlsx
|
|
395
434
|
|
396
435
|
attributes << [:dataDxfId, col_data.format] if col_data.format
|
397
436
|
|
398
|
-
if ptrue?(col_data.formula)
|
437
|
+
if ptrue?(col_data.formula) || ptrue?(col_data.custom_total)
|
399
438
|
@writer.tag_elements('tableColumn', attributes) do
|
400
|
-
|
401
|
-
|
439
|
+
if ptrue?(col_data.formula)
|
440
|
+
# Write the calculatedColumnFormula element.
|
441
|
+
write_calculated_column_formula(col_data.formula)
|
442
|
+
end
|
443
|
+
if ptrue?(col_data.custom_total)
|
444
|
+
# Write the totalsRowFormula element.
|
445
|
+
write_totals_row_formula(col_data.custom_total)
|
446
|
+
end
|
402
447
|
end
|
403
448
|
else
|
404
449
|
@writer.empty_tag('tableColumn', attributes)
|
@@ -425,6 +470,15 @@ module Writexlsx
|
|
425
470
|
def write_calculated_column_formula(formula)
|
426
471
|
@writer.data_element('calculatedColumnFormula', formula)
|
427
472
|
end
|
473
|
+
|
474
|
+
#
|
475
|
+
# _write_totals_row_formula()
|
476
|
+
#
|
477
|
+
# Write the <totalsRowFormula> element.
|
478
|
+
#
|
479
|
+
def write_totals_row_formula(formula)
|
480
|
+
@writer.data_element('totalsRowFormula', formula)
|
481
|
+
end
|
428
482
|
end
|
429
483
|
end
|
430
484
|
end
|
@@ -29,33 +29,28 @@ module Writexlsx
|
|
29
29
|
io_write(str)
|
30
30
|
end
|
31
31
|
|
32
|
-
def tag_elements(tag, attributes =
|
32
|
+
def tag_elements(tag, attributes = nil)
|
33
33
|
start_tag(tag, attributes)
|
34
34
|
yield
|
35
35
|
end_tag(tag)
|
36
36
|
end
|
37
37
|
|
38
|
-
def tag_elements_str(tag, attributes =
|
38
|
+
def tag_elements_str(tag, attributes = nil)
|
39
39
|
start_tag_str(tag, attributes) +
|
40
40
|
yield +
|
41
41
|
end_tag_str(tag)
|
42
42
|
end
|
43
43
|
|
44
|
-
def start_tag(tag, attr =
|
44
|
+
def start_tag(tag, attr = nil)
|
45
45
|
io_write(start_tag_str(tag, attr))
|
46
46
|
end
|
47
47
|
|
48
|
-
def start_tag_str(tag, attr =
|
49
|
-
if attr.empty?
|
50
|
-
|
51
|
-
unless result
|
52
|
-
result = "<#{tag}>"
|
53
|
-
@tag_start_cache[tag] = result
|
54
|
-
end
|
48
|
+
def start_tag_str(tag, attr = nil)
|
49
|
+
if attr.nil? || attr.empty?
|
50
|
+
@tag_start_cache[tag] ||= "<#{tag}>"
|
55
51
|
else
|
56
|
-
|
52
|
+
"<#{tag}#{key_vals(attr)}>"
|
57
53
|
end
|
58
|
-
result
|
59
54
|
end
|
60
55
|
|
61
56
|
def end_tag(tag)
|
@@ -63,28 +58,15 @@ module Writexlsx
|
|
63
58
|
end
|
64
59
|
|
65
60
|
def end_tag_str(tag)
|
66
|
-
|
67
|
-
unless result
|
68
|
-
result = "</#{tag}>"
|
69
|
-
@tag_end_cache[tag] = result
|
70
|
-
end
|
71
|
-
result
|
61
|
+
@tag_end_cache[tag] ||= "</#{tag}>"
|
72
62
|
end
|
73
63
|
|
74
|
-
def empty_tag(tag, attr =
|
64
|
+
def empty_tag(tag, attr = nil)
|
75
65
|
str = "<#{tag}#{key_vals(attr)}/>"
|
76
66
|
io_write(str)
|
77
67
|
end
|
78
68
|
|
79
|
-
def
|
80
|
-
io_write(empty_tag_encoded_str(tag, attr))
|
81
|
-
end
|
82
|
-
|
83
|
-
def empty_tag_encoded_str(tag, attr = [])
|
84
|
-
"<#{tag}#{key_vals(attr)}/>"
|
85
|
-
end
|
86
|
-
|
87
|
-
def data_element(tag, data, attr = [])
|
69
|
+
def data_element(tag, data, attr = nil)
|
88
70
|
tag_elements(tag, attr) { io_write(escape_data(data)) }
|
89
71
|
end
|
90
72
|
|
@@ -126,31 +108,37 @@ module Writexlsx
|
|
126
108
|
|
127
109
|
private
|
128
110
|
|
129
|
-
def key_val(key, val)
|
130
|
-
%( #{key}="#{val}")
|
131
|
-
end
|
132
|
-
|
133
111
|
def key_vals(attribute)
|
134
|
-
attribute
|
135
|
-
|
112
|
+
if attribute
|
113
|
+
result = "".dup
|
114
|
+
attribute.each do |attr|
|
115
|
+
# Generate and concat %( #{key}="#{val}") values for attribute pair
|
116
|
+
result << " "
|
117
|
+
result << attr.first.to_s
|
118
|
+
result << '="'
|
119
|
+
result << escape_attributes(attr.last).to_s
|
120
|
+
result << '"'
|
121
|
+
end
|
122
|
+
result
|
123
|
+
end
|
136
124
|
end
|
137
125
|
|
138
126
|
def escape_attributes(str = '')
|
139
|
-
return str unless str.
|
127
|
+
return str unless str.respond_to?(:match) && str =~ /["&<>\n]/
|
140
128
|
|
141
129
|
str
|
142
|
-
.gsub(
|
143
|
-
.gsub(
|
144
|
-
.gsub(
|
145
|
-
.gsub(
|
146
|
-
.gsub(
|
130
|
+
.gsub("&", "&")
|
131
|
+
.gsub('"', """)
|
132
|
+
.gsub("<", "<")
|
133
|
+
.gsub(">", ">")
|
134
|
+
.gsub("\n", "
")
|
147
135
|
end
|
148
136
|
|
149
137
|
def escape_data(str = '')
|
150
|
-
if str.
|
151
|
-
str.gsub(
|
152
|
-
.gsub(
|
153
|
-
.gsub(
|
138
|
+
if str.respond_to?(:match) && str =~ /[&<>]/
|
139
|
+
str.gsub("&", '&')
|
140
|
+
.gsub("<", '<')
|
141
|
+
.gsub(">", '>')
|
154
142
|
else
|
155
143
|
str
|
156
144
|
end
|
data/lib/write_xlsx/sheets.rb
CHANGED
@@ -252,9 +252,13 @@ module Writexlsx
|
|
252
252
|
['sheetId', sheet_id]
|
253
253
|
]
|
254
254
|
|
255
|
-
|
255
|
+
if sheet.hidden?
|
256
|
+
attributes << %w[state hidden]
|
257
|
+
elsif sheet.very_hidden?
|
258
|
+
attributes << %w[state veryHidden]
|
259
|
+
end
|
256
260
|
attributes << r_id_attributes(sheet_id)
|
257
|
-
writer.
|
261
|
+
writer.empty_tag('sheet', attributes)
|
258
262
|
end
|
259
263
|
end
|
260
264
|
end
|
data/lib/write_xlsx/sparkline.rb
CHANGED
@@ -43,13 +43,13 @@ module Writexlsx
|
|
43
43
|
# Cleanup the input ranges.
|
44
44
|
@ranges.collect! do |range|
|
45
45
|
# Remove the absolute reference $ symbols.
|
46
|
-
range = range.gsub(
|
46
|
+
range = range.gsub("$", '')
|
47
47
|
# Convert a simple range into a full Sheet1!A1:D1 range.
|
48
48
|
range = "#{sheetname}!#{range}" unless range =~ /!/
|
49
49
|
range
|
50
50
|
end
|
51
51
|
# Cleanup the input locations.
|
52
|
-
@locations.collect! { |location| location.gsub(
|
52
|
+
@locations.collect! { |location| location.gsub("$", '') }
|
53
53
|
|
54
54
|
# Map options.
|
55
55
|
@high = param[:high_point]
|
data/lib/write_xlsx/utility.rb
CHANGED
@@ -31,10 +31,12 @@ module Writexlsx
|
|
31
31
|
#
|
32
32
|
# xl_rowcol_to_cell($row, col, row_absolute, col_absolute)
|
33
33
|
#
|
34
|
-
def xl_rowcol_to_cell(
|
35
|
-
|
34
|
+
def xl_rowcol_to_cell(row_or_name, col, row_absolute = false, col_absolute = false)
|
35
|
+
if row_or_name.is_a?(Integer)
|
36
|
+
row_or_name += 1 # Change from 0-indexed to 1 indexed.
|
37
|
+
end
|
36
38
|
col_str = xl_col_to_name(col, col_absolute)
|
37
|
-
"#{col_str}#{absolute_char(row_absolute)}#{
|
39
|
+
"#{col_str}#{absolute_char(row_absolute)}#{row_or_name}"
|
38
40
|
end
|
39
41
|
|
40
42
|
#
|
@@ -53,7 +55,7 @@ module Writexlsx
|
|
53
55
|
|
54
56
|
# Convert base26 column string to number
|
55
57
|
# All your Base are belong to us.
|
56
|
-
chars = col.split(
|
58
|
+
chars = col.split("")
|
57
59
|
expn = 0
|
58
60
|
col = 0
|
59
61
|
|
@@ -112,7 +114,7 @@ module Writexlsx
|
|
112
114
|
#
|
113
115
|
def xl_string_pixel_width(string)
|
114
116
|
length = 0
|
115
|
-
string.to_s.split(
|
117
|
+
string.to_s.split("").each { |char| length += CHAR_WIDTHS[char] || 8 }
|
116
118
|
|
117
119
|
length
|
118
120
|
end
|
@@ -128,7 +130,7 @@ module Writexlsx
|
|
128
130
|
name = sheetname.dup
|
129
131
|
if name =~ /\W/ && !(name =~ /^'/)
|
130
132
|
# Double quote and single quoted strings.
|
131
|
-
name = name.gsub(
|
133
|
+
name = name.gsub("'", "''")
|
132
134
|
name = "'#{name}'"
|
133
135
|
end
|
134
136
|
name
|
@@ -159,7 +161,7 @@ module Writexlsx
|
|
159
161
|
seconds = 0 # Time expressed as fraction of 24h hours in seconds
|
160
162
|
|
161
163
|
# Split into date and time.
|
162
|
-
date, time = date_time.split(
|
164
|
+
date, time = date_time.split("T")
|
163
165
|
|
164
166
|
# We allow the time portion of the input DateTime to be optional.
|
165
167
|
if time
|
@@ -207,7 +209,7 @@ module Writexlsx
|
|
207
209
|
# becomes 100 for 4 and 100 year leapdays and 400 for 400 year leapdays.
|
208
210
|
#
|
209
211
|
epoch = date_1904? ? 1904 : 1900
|
210
|
-
offset = date_1904? ?
|
212
|
+
offset = date_1904? ? 4 : 0
|
211
213
|
norm = 300
|
212
214
|
range = year - epoch
|
213
215
|
|
@@ -248,7 +250,7 @@ module Writexlsx
|
|
248
250
|
def escape_url(url)
|
249
251
|
unless url =~ /%[0-9a-fA-F]{2}/
|
250
252
|
# Escape the URL escape symbol.
|
251
|
-
url = url.gsub(
|
253
|
+
url = url.gsub("%", "%25")
|
252
254
|
|
253
255
|
# Escape whitespae in URL.
|
254
256
|
url = url.gsub(/[\s\x00]/, '%20')
|
@@ -341,7 +343,7 @@ module Writexlsx
|
|
341
343
|
#
|
342
344
|
# Write the <color> element.
|
343
345
|
#
|
344
|
-
def write_color(
|
346
|
+
def write_color(name, value, writer = @writer) # :nodoc:
|
345
347
|
attributes = [[name, value]]
|
346
348
|
|
347
349
|
writer.empty_tag('color', attributes)
|
@@ -751,8 +753,8 @@ module Writexlsx
|
|
751
753
|
# Adjust the colour index.
|
752
754
|
idx = index - 8
|
753
755
|
|
754
|
-
|
755
|
-
sprintf("%02X%02X%02X",
|
756
|
+
r, g, b = @palette[idx]
|
757
|
+
sprintf("%02X%02X%02X", r, g, b)
|
756
758
|
end
|
757
759
|
|
758
760
|
#
|
data/lib/write_xlsx/version.rb
CHANGED
data/lib/write_xlsx/workbook.rb
CHANGED
@@ -715,7 +715,7 @@ module Writexlsx
|
|
715
715
|
|
716
716
|
# Split the cell range into 2 cells or else use single cell for both.
|
717
717
|
if cells =~ /:/
|
718
|
-
cell_1, cell_2 = cells.split(
|
718
|
+
cell_1, cell_2 = cells.split(":")
|
719
719
|
else
|
720
720
|
cell_1 = cells
|
721
721
|
cell_2 = cells
|
@@ -724,7 +724,7 @@ module Writexlsx
|
|
724
724
|
# Remove leading/trailing apostrophes and convert escaped quotes to single.
|
725
725
|
sheetname.sub!(/^'/, '')
|
726
726
|
sheetname.sub!(/'$/, '')
|
727
|
-
sheetname.gsub!(
|
727
|
+
sheetname.gsub!("''", "'")
|
728
728
|
|
729
729
|
row_start, col_start = xl_cell_to_rowcol(cell_1)
|
730
730
|
row_end, col_end = xl_cell_to_rowcol(cell_2)
|
@@ -988,7 +988,6 @@ module Writexlsx
|
|
988
988
|
num_formats = []
|
989
989
|
unique_num_formats = {}
|
990
990
|
index = 164
|
991
|
-
num_format_count = 0
|
992
991
|
|
993
992
|
(@xf_formats + @dxf_formats).each do |format|
|
994
993
|
num_format = format.num_format
|
@@ -1,6 +1,5 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
-
|
3
|
-
# frozen__literal: true
|
2
|
+
# frozen_string_literal: true
|
4
3
|
|
5
4
|
module Writexlsx
|
6
5
|
class Worksheet
|
@@ -13,10 +12,10 @@ module Writexlsx
|
|
13
12
|
# attributes for the <cell> element. This is the innermost loop so efficiency is
|
14
13
|
# important where possible.
|
15
14
|
#
|
16
|
-
def cell_attributes(worksheet, row, col) # :nodoc:
|
15
|
+
def cell_attributes(worksheet, row, row_name, col) # :nodoc:
|
17
16
|
xf_index = xf ? xf.get_xf_index : 0
|
18
17
|
attributes = [
|
19
|
-
['r', xl_rowcol_to_cell(
|
18
|
+
['r', xl_rowcol_to_cell(row_name, col)]
|
20
19
|
]
|
21
20
|
|
22
21
|
# Add the cell format index.
|
@@ -49,8 +48,8 @@ module Writexlsx
|
|
49
48
|
@token
|
50
49
|
end
|
51
50
|
|
52
|
-
def write_cell(worksheet, row, col)
|
53
|
-
worksheet.writer.tag_elements('c', cell_attributes(worksheet, row, col)) do
|
51
|
+
def write_cell(worksheet, row, row_name, col)
|
52
|
+
worksheet.writer.tag_elements('c', cell_attributes(worksheet, row, row_name, col)) do
|
54
53
|
worksheet.write_cell_value(token)
|
55
54
|
end
|
56
55
|
end
|
@@ -70,8 +69,8 @@ module Writexlsx
|
|
70
69
|
end
|
71
70
|
|
72
71
|
TYPE_STR_ATTRS = %w[t s].freeze
|
73
|
-
def write_cell(worksheet, row, col)
|
74
|
-
attributes = cell_attributes(worksheet, row, col)
|
72
|
+
def write_cell(worksheet, row, row_name, col)
|
73
|
+
attributes = cell_attributes(worksheet, row, row_name, col)
|
75
74
|
attributes << TYPE_STR_ATTRS
|
76
75
|
worksheet.writer.tag_elements('c', attributes) do
|
77
76
|
worksheet.write_cell_value(token)
|
@@ -102,11 +101,11 @@ module Writexlsx
|
|
102
101
|
@result || 0
|
103
102
|
end
|
104
103
|
|
105
|
-
def write_cell(worksheet, row, col)
|
104
|
+
def write_cell(worksheet, row, row_name, col)
|
106
105
|
truefalse = { 'TRUE' => 1, 'FALSE' => 0 }
|
107
106
|
error_code = ['#DIV/0!', '#N/A', '#NAME?', '#NULL!', '#NUM!', '#REF!', '#VALUE!']
|
108
107
|
|
109
|
-
attributes = cell_attributes(worksheet, row, col)
|
108
|
+
attributes = cell_attributes(worksheet, row, row_name, col)
|
110
109
|
if @result && !(@result.to_s =~ /^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/)
|
111
110
|
if truefalse[@result]
|
112
111
|
attributes << %w[t b]
|
@@ -138,8 +137,8 @@ module Writexlsx
|
|
138
137
|
@result || 0
|
139
138
|
end
|
140
139
|
|
141
|
-
def write_cell(worksheet, row, col)
|
142
|
-
worksheet.writer.tag_elements('c', cell_attributes(worksheet, row, col)) do
|
140
|
+
def write_cell(worksheet, row, row_name, col)
|
141
|
+
worksheet.writer.tag_elements('c', cell_attributes(worksheet, row, row_name, col)) do
|
143
142
|
worksheet.write_cell_array_formula(token, range)
|
144
143
|
worksheet.write_cell_value(result)
|
145
144
|
end
|
@@ -160,9 +159,9 @@ module Writexlsx
|
|
160
159
|
@result || 0
|
161
160
|
end
|
162
161
|
|
163
|
-
def write_cell(worksheet, row, col)
|
162
|
+
def write_cell(worksheet, row, row_name, col)
|
164
163
|
# Add metadata linkage for dynamic array formulas.
|
165
|
-
attributes = cell_attributes(worksheet, row, col)
|
164
|
+
attributes = cell_attributes(worksheet, row, row_name, col)
|
166
165
|
attributes << %w[cm 1]
|
167
166
|
|
168
167
|
worksheet.writer.tag_elements('c', attributes) do
|
@@ -184,8 +183,8 @@ module Writexlsx
|
|
184
183
|
@token
|
185
184
|
end
|
186
185
|
|
187
|
-
def write_cell(worksheet, row, col)
|
188
|
-
attributes = cell_attributes(worksheet, row, col)
|
186
|
+
def write_cell(worksheet, row, row_name, col)
|
187
|
+
attributes = cell_attributes(worksheet, row, row_name, col)
|
189
188
|
|
190
189
|
attributes << %w[t b]
|
191
190
|
worksheet.writer.tag_elements('c', attributes) do
|
@@ -203,8 +202,8 @@ module Writexlsx
|
|
203
202
|
''
|
204
203
|
end
|
205
204
|
|
206
|
-
def write_cell(worksheet, row, col)
|
207
|
-
worksheet.writer.empty_tag('c', cell_attributes(worksheet, row, col))
|
205
|
+
def write_cell(worksheet, row, row_name, col)
|
206
|
+
worksheet.writer.empty_tag('c', cell_attributes(worksheet, row, row_name, col))
|
208
207
|
end
|
209
208
|
end
|
210
209
|
end
|