write_xlsx 0.85.11 → 0.86.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Changes +17 -0
- data/examples/colors.rb +47 -0
- data/examples/comments2.rb +1 -1
- data/examples/conditional_format.rb +60 -9
- data/examples/data_validate.rb +7 -7
- data/examples/panes.rb +1 -1
- data/examples/tab_colors.rb +1 -1
- data/lib/write_xlsx/format.rb +1 -1
- data/lib/write_xlsx/package/app.rb +12 -0
- data/lib/write_xlsx/package/comments.rb +4 -2
- data/lib/write_xlsx/package/conditional_format.rb +6 -0
- data/lib/write_xlsx/package/table.rb +17 -5
- data/lib/write_xlsx/package/xml_writer_simple.rb +3 -2
- data/lib/write_xlsx/version.rb +1 -1
- data/lib/write_xlsx/workbook.rb +12 -11
- data/lib/write_xlsx/worksheet.rb +20 -4
- data/lib/write_xlsx/worksheet/data_validation.rb +22 -10
- data/lib/write_xlsx/worksheet/hyperlink.rb +12 -8
- data/test/regression/images/red_208.png +0 -0
- data/test/regression/test_data_validation08.rb +24 -0
- data/test/regression/test_hyperlink22.rb +24 -0
- data/test/regression/test_hyperlink23.rb +24 -0
- data/test/regression/test_hyperlink24.rb +24 -0
- data/test/regression/test_image28.rb +27 -0
- data/test/regression/test_image29.rb +27 -0
- data/test/regression/test_image30.rb +27 -0
- data/test/regression/test_image31.rb +30 -0
- data/test/regression/test_image32.rb +28 -0
- data/test/regression/test_image33.rb +32 -0
- data/test/regression/test_properties02.rb +28 -0
- data/test/regression/xlsx_files/data_validation08.xlsx +0 -0
- data/test/regression/xlsx_files/hyperlink22.xlsx +0 -0
- data/test/regression/xlsx_files/hyperlink23.xlsx +0 -0
- data/test/regression/xlsx_files/hyperlink24.xlsx +0 -0
- data/test/regression/xlsx_files/image28.xlsx +0 -0
- data/test/regression/xlsx_files/image29.xlsx +0 -0
- data/test/regression/xlsx_files/image30.xlsx +0 -0
- data/test/regression/xlsx_files/image31.xlsx +0 -0
- data/test/regression/xlsx_files/image32.xlsx +0 -0
- data/test/regression/xlsx_files/image33.xlsx +0 -0
- data/test/regression/xlsx_files/properties02.xlsx +0 -0
- data/test/regression/xlsx_files/table18.xlsx +0 -0
- data/test/regression/xlsx_files/table19.xlsx +0 -0
- data/test/worksheet/test_cond_format_21.rb +90 -0
- data/test/worksheet/test_sparkline_12.rb +94 -0
- data/test/worksheet/test_write_data_validation_02.rb +14 -1
- metadata +56 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 794b9b3028ff50abeab1e2c85d951fdc38526887ef6e2d64c6125afe697b4f92
|
4
|
+
data.tar.gz: 0a460f71a4cb05d4f72d7ad77308dbcda504b06f0e56ceceb7d0a9a6e0c0514f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b51f580ca37d7586f3faa6bafebeb76f2b14129070a0e7e70fe9d648e75e504983ad2ad97976ba49b3a8bb5af598826f54aa982dd73a7044132f32044bac6469
|
7
|
+
data.tar.gz: 661206fe8a1eeb9878329559ee9bf5f2a8f12db9515fba264368fe2f9df8711bffe4bb2457a51fb993dcb7aa74ce1c1fcd9740b6b05c6666edebae9288e2e66c
|
data/Changes
CHANGED
@@ -1,5 +1,22 @@
|
|
1
1
|
Change history of write_xlsx rubygem.
|
2
2
|
|
3
|
+
2020-11-01 v0.86.0
|
4
|
+
Fix for images with negative offsets.
|
5
|
+
|
6
|
+
Allow hyperlinks longer than 255 characters when the link and anchor
|
7
|
+
are each less than or equal to 255 characters.
|
8
|
+
|
9
|
+
Added hyperlink_base document property.
|
10
|
+
|
11
|
+
Added option to allow data validation input messages with the ‘any’
|
12
|
+
validate parameter.
|
13
|
+
|
14
|
+
Added "stop if true" feature to conditional formatting.
|
15
|
+
|
16
|
+
Added better support and documentation for html colours throughout
|
17
|
+
the module. The use of the Excel97 colour palette is supported for
|
18
|
+
backward compatibility but deprecated.
|
19
|
+
|
3
20
|
2020-10-23 v0.85.11
|
4
21
|
Added Worksheet#update_range_format_with_params
|
5
22
|
|
data/examples/colors.rb
CHANGED
@@ -126,4 +126,51 @@
|
|
126
126
|
end
|
127
127
|
end
|
128
128
|
|
129
|
+
|
130
|
+
#
|
131
|
+
# Demonstrate the Html colors.
|
132
|
+
#
|
133
|
+
|
134
|
+
colors = {
|
135
|
+
'#000000' => 'black',
|
136
|
+
'#0000FF' => 'blue',
|
137
|
+
'#800000' => 'brown',
|
138
|
+
'#00FFFF' => 'cyan',
|
139
|
+
'#808080' => 'gray',
|
140
|
+
'#008000' => 'green',
|
141
|
+
'#00FF00' => 'lime',
|
142
|
+
'#FF00FF' => 'magenta',
|
143
|
+
'#000080' => 'navy',
|
144
|
+
'#FF6600' => 'orange',
|
145
|
+
'#FF00FF' => 'pink',
|
146
|
+
'#800080' => 'purple',
|
147
|
+
'#FF0000' => 'red',
|
148
|
+
'#C0C0C0' => 'silver',
|
149
|
+
'#FFFFFF' => 'white',
|
150
|
+
'#FFFF00' => 'yellow'
|
151
|
+
}
|
152
|
+
|
153
|
+
worksheet3 = workbook.add_worksheet('Html colors')
|
154
|
+
|
155
|
+
worksheet3.set_column(0, 3, 15)
|
156
|
+
|
157
|
+
worksheet3.write(0, 0, "Html", heading)
|
158
|
+
worksheet3.write(0, 1, "Name", heading)
|
159
|
+
worksheet3.write(0, 2, "Color", heading)
|
160
|
+
|
161
|
+
i = 1
|
162
|
+
|
163
|
+
colors.each do |html_color, color|
|
164
|
+
format = workbook.add_format(
|
165
|
+
:fg_color => html_color,
|
166
|
+
:pattern => 1,
|
167
|
+
:border => 1
|
168
|
+
)
|
169
|
+
|
170
|
+
worksheet3.write(i + 1, 1, html_color, center)
|
171
|
+
worksheet3.write(i + 1, 2, color, center)
|
172
|
+
worksheet3.write(i + 1, 3, '', format)
|
173
|
+
i += 1
|
174
|
+
end
|
175
|
+
|
129
176
|
workbook.close
|
data/examples/comments2.rb
CHANGED
@@ -247,7 +247,7 @@
|
|
247
247
|
comment = 'Hello.'
|
248
248
|
|
249
249
|
worksheet6.write( 'C9', cell_text, text_wrap )
|
250
|
-
worksheet6.write_comment( 'C9', comment, :color =>
|
250
|
+
worksheet6.write_comment( 'C9', comment, :color => '#FF6600' )
|
251
251
|
|
252
252
|
|
253
253
|
###############################################################################
|
@@ -12,6 +12,7 @@
|
|
12
12
|
worksheet6 = workbook.add_worksheet
|
13
13
|
worksheet7 = workbook.add_worksheet
|
14
14
|
worksheet8 = workbook.add_worksheet
|
15
|
+
worksheet9 = workbook.add_worksheet
|
15
16
|
|
16
17
|
# Light red fill with dark red text.
|
17
18
|
format1 = workbook.add_format(
|
@@ -25,6 +26,12 @@
|
|
25
26
|
:color => '#006100'
|
26
27
|
)
|
27
28
|
|
29
|
+
# Blue fill with dark blue text.
|
30
|
+
format3 = workbook.add_format(
|
31
|
+
:bg_color => '#C6CEFF',
|
32
|
+
:color => '#0000FF'
|
33
|
+
)
|
34
|
+
|
28
35
|
# Some sample data to run the conditional formatting against.
|
29
36
|
data = [
|
30
37
|
[ 34, 72, 38, 30, 75, 48, 75, 66, 84, 86 ],
|
@@ -219,18 +226,19 @@
|
|
219
226
|
#
|
220
227
|
caption = 'Examples of color scales and data bars. Default colors.'
|
221
228
|
|
222
|
-
data
|
229
|
+
# Use different sample data for examples 7 and 8
|
230
|
+
data7 = 1 .. 12
|
223
231
|
|
224
232
|
worksheet7.write('A1', caption)
|
225
233
|
|
226
234
|
worksheet7.write('B2', "2 Color Scale")
|
227
|
-
worksheet7.write_col('B3',
|
235
|
+
worksheet7.write_col('B3', data7)
|
228
236
|
|
229
237
|
worksheet7.write('D2', "3 Color Scale")
|
230
|
-
worksheet7.write_col('D3',
|
238
|
+
worksheet7.write_col('D3', data7)
|
231
239
|
|
232
240
|
worksheet7.write('F2', "Data Bars")
|
233
|
-
worksheet7.write_col('F3',
|
241
|
+
worksheet7.write_col('F3', data7)
|
234
242
|
|
235
243
|
|
236
244
|
worksheet7.conditional_formatting('B3:B14',
|
@@ -258,18 +266,16 @@
|
|
258
266
|
#
|
259
267
|
caption = 'Examples of color scales and data bars. Modified colors.'
|
260
268
|
|
261
|
-
data = 1 .. 12
|
262
|
-
|
263
269
|
worksheet8.write('A1', caption)
|
264
270
|
|
265
271
|
worksheet8.write('B2', "2 Color Scale")
|
266
|
-
worksheet8.write_col('B3',
|
272
|
+
worksheet8.write_col('B3', data7)
|
267
273
|
|
268
274
|
worksheet8.write('D2', "3 Color Scale")
|
269
|
-
worksheet8.write_col('D3',
|
275
|
+
worksheet8.write_col('D3', data7)
|
270
276
|
|
271
277
|
worksheet8.write('F2', "Data Bars")
|
272
|
-
worksheet8.write_col('F3',
|
278
|
+
worksheet8.write_col('F3', data7)
|
273
279
|
|
274
280
|
|
275
281
|
worksheet8.conditional_formatting('B3:B14',
|
@@ -296,4 +302,49 @@
|
|
296
302
|
}
|
297
303
|
)
|
298
304
|
|
305
|
+
###############################################################################
|
306
|
+
#
|
307
|
+
# Example 9
|
308
|
+
#
|
309
|
+
caption = 'Cells with values >= 100 are always in blue. ' +
|
310
|
+
'Otherwise, cells with values >= 50 are in light red ' +
|
311
|
+
'and values < 50 are in light green.'
|
312
|
+
|
313
|
+
# Write the data.
|
314
|
+
worksheet9.write('A1', caption)
|
315
|
+
worksheet9.write_col('B3', data)
|
316
|
+
|
317
|
+
# Write a conditional format over a range.
|
318
|
+
# Use stopIfTrue to prevent previous formats from being used
|
319
|
+
# if the conditions of this format are met.
|
320
|
+
worksheet9.conditional_formatting('B3:K12',
|
321
|
+
{
|
322
|
+
:type => 'cell',
|
323
|
+
:criteria => '>=',
|
324
|
+
:value => 100,
|
325
|
+
:format => format3,
|
326
|
+
:stop_if_true => 1
|
327
|
+
}
|
328
|
+
)
|
329
|
+
|
330
|
+
# Write another conditional format over the same range.
|
331
|
+
worksheet9.conditional_formatting('B3:K12',
|
332
|
+
{
|
333
|
+
:type => 'cell',
|
334
|
+
:criteria => '>=',
|
335
|
+
:value => 50,
|
336
|
+
:format => format1
|
337
|
+
}
|
338
|
+
)
|
339
|
+
|
340
|
+
# Write another conditional format over the same range.
|
341
|
+
worksheet9.conditional_formatting('B3:K12',
|
342
|
+
{
|
343
|
+
:type => 'cell',
|
344
|
+
:criteria => '<',
|
345
|
+
:value => 50,
|
346
|
+
:format => format2
|
347
|
+
}
|
348
|
+
)
|
349
|
+
|
299
350
|
workbook.close
|
data/examples/data_validate.rb
CHANGED
@@ -19,13 +19,13 @@
|
|
19
19
|
|
20
20
|
# Add a format for the header cells.
|
21
21
|
header_format = workbook.add_format(
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
22
|
+
:border => 1,
|
23
|
+
:bg_color => '#C6EFCE',
|
24
|
+
:bold => 1,
|
25
|
+
:text_wrap => 1,
|
26
|
+
:valign => 'vcenter',
|
27
|
+
:indent => 1
|
28
|
+
)
|
29
29
|
|
30
30
|
# Set up layout of the worksheet.
|
31
31
|
worksheet.set_column('A:A', 68)
|
data/examples/panes.rb
CHANGED
data/examples/tab_colors.rb
CHANGED
data/lib/write_xlsx/format.rb
CHANGED
@@ -582,7 +582,7 @@ def set_border_color(color)
|
|
582
582
|
def set_rotation(rotation)
|
583
583
|
if rotation == 270
|
584
584
|
rotation = 255
|
585
|
-
elsif rotation >= -90
|
585
|
+
elsif rotation >= -90 && rotation <= 90
|
586
586
|
rotation = -rotation + 90 if rotation < 0
|
587
587
|
else
|
588
588
|
raise "Rotation #{rotation} outside range: -90 <= angle <= 90"
|
@@ -32,6 +32,7 @@ def assemble_xml_file
|
|
32
32
|
write_company
|
33
33
|
write_links_up_to_date
|
34
34
|
write_shared_doc
|
35
|
+
write_hyperlink_base
|
35
36
|
write_hyperlinks_changed
|
36
37
|
write_app_version
|
37
38
|
end
|
@@ -220,6 +221,17 @@ def write_shared_doc
|
|
220
221
|
@writer.data_element('SharedDoc', data)
|
221
222
|
end
|
222
223
|
|
224
|
+
#
|
225
|
+
# Write the <HyperlinkBase> element.
|
226
|
+
#
|
227
|
+
def write_hyperlink_base
|
228
|
+
data = @properties[:hyperlink_base]
|
229
|
+
|
230
|
+
return unless data
|
231
|
+
|
232
|
+
@writer.data_element('HyperlinkBase', data)
|
233
|
+
end
|
234
|
+
|
223
235
|
#
|
224
236
|
# Write the <HyperlinksChanged> element.
|
225
237
|
#
|
@@ -41,11 +41,13 @@ def initialize(workbook, worksheet, row, col, string, options = {})
|
|
41
41
|
def backgrount_color(color)
|
42
42
|
color_id = Format.color(color)
|
43
43
|
|
44
|
-
if color_id
|
44
|
+
if color_id.to_s =~ /^#[0-9A-F]{6}/i
|
45
|
+
@color = color_id.to_s
|
46
|
+
elsif color_id == 0
|
45
47
|
@color = '#ffffe1'
|
46
48
|
else
|
47
49
|
rgb = @workbook.palette[color_id - 8]
|
48
|
-
@color = "##{rgb_color(rgb)} [#{color_id}]
|
50
|
+
@color = "##{rgb_color(rgb)} [#{color_id}]"
|
49
51
|
end
|
50
52
|
end
|
51
53
|
|
@@ -71,6 +71,7 @@ def attributes
|
|
71
71
|
attr << ['type' , type]
|
72
72
|
attr << ['dxfId', format] if format
|
73
73
|
attr << ['priority', priority]
|
74
|
+
attr << ['stopIfTrue', 1] if stop_if_true
|
74
75
|
attr
|
75
76
|
end
|
76
77
|
|
@@ -86,6 +87,10 @@ def priority
|
|
86
87
|
@param[:priority]
|
87
88
|
end
|
88
89
|
|
90
|
+
def stop_if_true
|
91
|
+
@param[:stop_if_true]
|
92
|
+
end
|
93
|
+
|
89
94
|
def criteria
|
90
95
|
@param[:criteria]
|
91
96
|
end
|
@@ -401,6 +406,7 @@ def valid_parameter_for_conditional_formatting
|
|
401
406
|
:value,
|
402
407
|
:minimum,
|
403
408
|
:maximum,
|
409
|
+
:stop_if_true,
|
404
410
|
:min_type,
|
405
411
|
:mid_type,
|
406
412
|
:max_type,
|
@@ -10,7 +10,7 @@ class Table
|
|
10
10
|
|
11
11
|
class ColumnData
|
12
12
|
attr_reader :id
|
13
|
-
attr_accessor :name, :format, :formula
|
13
|
+
attr_accessor :name, :format, :formula, :name_format
|
14
14
|
attr_accessor :total_string, :total_function
|
15
15
|
|
16
16
|
def initialize(id, param = {})
|
@@ -20,6 +20,7 @@ def initialize(id, param = {})
|
|
20
20
|
@total_function = ''
|
21
21
|
@formula = ''
|
22
22
|
@format = nil
|
23
|
+
@name_format = nil
|
23
24
|
@user_data = param[id-1] if param
|
24
25
|
end
|
25
26
|
end
|
@@ -93,10 +94,14 @@ def overrite_the_defaults_with_any_use_defined_values(col_id, col_data, col_num)
|
|
93
94
|
if user_data[:header] && !user_data[:header].empty?
|
94
95
|
col_data.name = user_data[:header]
|
95
96
|
end
|
97
|
+
|
98
|
+
# Get the header format if defined.
|
99
|
+
col_data.name_format = user_data[:header_format]
|
100
|
+
|
96
101
|
# Handle the column formula.
|
97
102
|
handle_the_column_formula(
|
98
|
-
|
99
|
-
|
103
|
+
col_data, col_num, user_data[:formula], user_data[:format]
|
104
|
+
)
|
100
105
|
|
101
106
|
# Handle the function for the total row.
|
102
107
|
if user_data[:total_function]
|
@@ -123,7 +128,9 @@ def overrite_the_defaults_with_any_use_defined_values(col_id, col_data, col_num)
|
|
123
128
|
|
124
129
|
def write_the_column_headers_to_the_worksheet(col_num, col_data)
|
125
130
|
if @param[:header_row] != 0
|
126
|
-
@worksheet.write_string(
|
131
|
+
@worksheet.write_string(
|
132
|
+
@row1, col_num, col_data.name, col_data.name_format
|
133
|
+
)
|
127
134
|
end
|
128
135
|
end
|
129
136
|
|
@@ -268,7 +275,12 @@ def set_the_table_style
|
|
268
275
|
end
|
269
276
|
|
270
277
|
def set_the_table_name
|
271
|
-
|
278
|
+
if @param[:name]
|
279
|
+
name = @param[:name]
|
280
|
+
|
281
|
+
raise "Name '#{name} in add_table cannot contain spaces" if name =~ /\s/
|
282
|
+
@name = @param[:name]
|
283
|
+
end
|
272
284
|
end
|
273
285
|
|
274
286
|
def set_the_table_and_autofilter_ranges
|
@@ -118,13 +118,14 @@ def key_vals(attribute)
|
|
118
118
|
end
|
119
119
|
|
120
120
|
def escape_attributes(str = '')
|
121
|
-
return str if !(str.to_s =~ /["
|
121
|
+
return str if !(str.to_s =~ /["&<>\n]/)
|
122
122
|
|
123
123
|
str.
|
124
124
|
gsub(/&/, "&").
|
125
125
|
gsub(/"/, """).
|
126
126
|
gsub(/</, "<").
|
127
|
-
gsub(/>/, ">")
|
127
|
+
gsub(/>/, ">").
|
128
|
+
gsub(/\n/, "
")
|
128
129
|
end
|
129
130
|
|
130
131
|
def escape_data(str = '')
|
data/lib/write_xlsx/version.rb
CHANGED
@@ -1 +1 @@
|
|
1
|
-
WriteXLSX_VERSION = "0.
|
1
|
+
WriteXLSX_VERSION = "0.86.0"
|
data/lib/write_xlsx/workbook.rb
CHANGED
@@ -786,17 +786,18 @@ def set_properties(params)
|
|
786
786
|
|
787
787
|
# List of valid input parameters.
|
788
788
|
valid = {
|
789
|
-
:title
|
790
|
-
:subject
|
791
|
-
:author
|
792
|
-
:keywords
|
793
|
-
:comments
|
794
|
-
:last_author
|
795
|
-
:created
|
796
|
-
:category
|
797
|
-
:manager
|
798
|
-
:company
|
799
|
-
:status
|
789
|
+
:title => 1,
|
790
|
+
:subject => 1,
|
791
|
+
:author => 1,
|
792
|
+
:keywords => 1,
|
793
|
+
:comments => 1,
|
794
|
+
:last_author => 1,
|
795
|
+
:created => 1,
|
796
|
+
:category => 1,
|
797
|
+
:manager => 1,
|
798
|
+
:company => 1,
|
799
|
+
:status => 1,
|
800
|
+
:hyperlink_base => 1
|
800
801
|
}
|
801
802
|
|
802
803
|
# Check for valid input parameters.
|
data/lib/write_xlsx/worksheet.rb
CHANGED
@@ -296,6 +296,7 @@ class Worksheet
|
|
296
296
|
attr_reader :comments, :comments_author # :nodoc:
|
297
297
|
attr_accessor :dxf_priority # :nodoc:
|
298
298
|
attr_reader :vba_codename # :nodoc:
|
299
|
+
attr_writer :excel_version
|
299
300
|
|
300
301
|
def initialize(workbook, index, name) #:nodoc:
|
301
302
|
@writer = Package::XMLWriterSimple.new
|
@@ -4288,7 +4289,7 @@ def conditional_formatting(*args)
|
|
4288
4289
|
# :header
|
4289
4290
|
# :formula
|
4290
4291
|
# :total_string
|
4291
|
-
# :
|
4292
|
+
# :
|
4292
4293
|
# :format
|
4293
4294
|
#
|
4294
4295
|
# The column data must be specified as an array of hash. For example to
|
@@ -4916,9 +4917,8 @@ def insert_button(*args)
|
|
4916
4917
|
# :custom
|
4917
4918
|
#
|
4918
4919
|
# +:any+ is used to specify that the type of data is unrestricted.
|
4919
|
-
# This is
|
4920
|
-
#
|
4921
|
-
# context of WriteXLSX.
|
4920
|
+
# This is usefl to display an input message without restricting the data
|
4921
|
+
# that can be entered.
|
4922
4922
|
#
|
4923
4923
|
# +:integer+ restricts the cell to integer values. Excel refers to this
|
4924
4924
|
# as 'whole number'.
|
@@ -5802,6 +5802,22 @@ def get_range_data(row_start, col_start, row_end, col_end) # :nodoc:
|
|
5802
5802
|
# width # Width of object frame.
|
5803
5803
|
# height # Height of object frame.
|
5804
5804
|
def position_object_pixels(col_start, row_start, x1, y1, width, height) #:nodoc:
|
5805
|
+
# Adjust start column for negative offsets.
|
5806
|
+
while x1 < 0 && col_start > 0
|
5807
|
+
x1 += size_col(col_start - 1)
|
5808
|
+
col_start -= 1
|
5809
|
+
end
|
5810
|
+
|
5811
|
+
# Adjust start row for negative offsets.
|
5812
|
+
while y1 < 0 && row_start > 0
|
5813
|
+
y1 += size_row(row_start - 1)
|
5814
|
+
row_start -= 1
|
5815
|
+
end
|
5816
|
+
|
5817
|
+
# Ensure that the image isn't shifted off the page at top left.
|
5818
|
+
x1 = 0 if x1 < 0
|
5819
|
+
y1 = 0 if y1 < 0
|
5820
|
+
|
5805
5821
|
# Calculate the absolute x offset of the top-left vertex.
|
5806
5822
|
if @col_size_changed
|
5807
5823
|
x_abs = (0 .. col_start-1).inject(0) {|sum, col| sum += size_col(col)}
|