write_xlsx 1.07.0 → 1.08.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Changes +31 -0
- data/README.md +1 -1
- data/lib/write_xlsx/chart.rb +3 -5
- data/lib/write_xlsx/drawing.rb +80 -17
- data/lib/write_xlsx/package/app.rb +3 -3
- data/lib/write_xlsx/package/conditional_format.rb +2 -8
- data/lib/write_xlsx/package/packager.rb +1 -0
- data/lib/write_xlsx/package/styles.rb +16 -3
- data/lib/write_xlsx/utility.rb +5 -1
- data/lib/write_xlsx/version.rb +1 -1
- data/lib/write_xlsx/workbook.rb +23 -0
- data/lib/write_xlsx/worksheet/data_validation.rb +1 -6
- data/lib/write_xlsx/worksheet.rb +71 -20
- data/test/drawing/{test_write_ext.rb → test_write_xdr_ext.rb} +2 -2
- data/test/regression/test_chart_crossing01.rb +1 -1
- data/test/regression/test_chart_crossing05.rb +46 -0
- data/test/regression/test_chart_crossing06.rb +46 -0
- data/test/regression/test_chart_data_labels48.rb +55 -0
- data/test/regression/test_chart_data_labels49.rb +55 -0
- data/test/regression/test_chart_data_labels50.rb +57 -0
- data/test/regression/test_format16.rb +24 -0
- data/test/regression/test_format17.rb +24 -0
- data/test/regression/test_image52.rb +26 -0
- data/test/regression/test_image53.rb +26 -0
- data/test/regression/test_image54.rb +26 -0
- data/test/regression/test_image55.rb +27 -0
- data/test/regression/test_protect04.rb +32 -0
- data/test/regression/test_protect05.rb +35 -0
- data/test/regression/test_protect06.rb +35 -0
- data/test/regression/test_protect07.rb +23 -0
- data/test/regression/xlsx_files/chart_crossing05.xlsx +0 -0
- data/test/regression/xlsx_files/chart_crossing06.xlsx +0 -0
- data/test/regression/xlsx_files/chart_data_labels48.xlsx +0 -0
- data/test/regression/xlsx_files/chart_data_labels49.xlsx +0 -0
- data/test/regression/xlsx_files/chart_data_labels50.xlsx +0 -0
- data/test/regression/xlsx_files/format16.xlsx +0 -0
- data/test/regression/xlsx_files/format17.xlsx +0 -0
- data/test/regression/xlsx_files/image52.xlsx +0 -0
- data/test/regression/xlsx_files/image53.xlsx +0 -0
- data/test/regression/xlsx_files/image54.xlsx +0 -0
- data/test/regression/xlsx_files/image55.xlsx +0 -0
- data/test/regression/xlsx_files/protect04.xlsx +0 -0
- data/test/regression/xlsx_files/protect05.xlsx +0 -0
- data/test/regression/xlsx_files/protect06.xlsx +0 -0
- data/test/regression/xlsx_files/protect07.xlsx +0 -0
- data/test/utility/test_range.rb +20 -0
- metadata +70 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0bce1d8cc8f140d38ac7d9149e644d8b1d5133c80933fc2faa2a33d25dcbd168
|
4
|
+
data.tar.gz: 4edf0897d13ec8cee0b545177fe4117286067ba2e14b89c2866192885414633b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 267233a3a8222f817bc455b5d8723bf29808854a7b5410c090becd44baee604201b53792f03b29db84c2fa82f9a4085e11175893abb11bab50b1a74c9f0526e8
|
7
|
+
data.tar.gz: bc5138fcae79f92aaa9a5d6d708575e9615cec51e4c229ec46e0e75e45bc1eca37056f27466f321c8ad6376119bd37c61754b8809c991fd2352ca8a1108089f0
|
data/Changes
CHANGED
@@ -1,5 +1,36 @@
|
|
1
1
|
Change history of write_xlsx rubygem.
|
2
2
|
|
3
|
+
2021-11-19 v1.08.0
|
4
|
+
|
5
|
+
Added ability to add accessibility options "description" and
|
6
|
+
"decorative" to images via insert_image().
|
7
|
+
|
8
|
+
Added the workbook read_only_recommended() method to set the Excel
|
9
|
+
"Read-only Recommended" option that is available when saving a file.
|
10
|
+
|
11
|
+
Added option to set a chart crossing to 'min' as well as the existing
|
12
|
+
'max' option. The 'min' option isn't available in the Excel interface
|
13
|
+
but can be enabled via VBA.
|
14
|
+
|
15
|
+
Added option to unprotect ranges in protected worksheets.
|
16
|
+
|
17
|
+
Added check, and warning, for worksheet tables with no data row. Either
|
18
|
+
with or without a header row.
|
19
|
+
|
20
|
+
Added ignore_errors() worksheet method to ignore Excel worksheet
|
21
|
+
errors/warnings in user defined ranges.
|
22
|
+
|
23
|
+
Fixed issue where pattern formats without colours where given a default
|
24
|
+
black fill colour.
|
25
|
+
|
26
|
+
Fix issue where custom chart data labels didn't inherit the position for
|
27
|
+
the data labels in the series.
|
28
|
+
|
29
|
+
Fixed issue with relative url links in images.
|
30
|
+
|
31
|
+
Fixed issue where headers/footers were restricted to 254 characters
|
32
|
+
instead of 255.
|
33
|
+
|
3
34
|
2021-02-17 v1.07.0
|
4
35
|
|
5
36
|
Added support for Border, Fill, Pattern and Gradient formatting to chart
|
data/README.md
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
|
6
6
|
gem to create a new file in the Excel 2007+ XLSX format, and you can use the
|
7
7
|
same interface as writeexcel gem. write_xlsx is converted from Perl's module
|
8
|
-
[Excel::Writer::XLSX-1.
|
8
|
+
[Excel::Writer::XLSX-1.08](https://github.com/jmcnamara/excel-writer-xlsx/tree/CPAN_1.08)
|
9
9
|
|
10
10
|
## Description
|
11
11
|
|
data/lib/write_xlsx/chart.rb
CHANGED
@@ -1397,7 +1397,7 @@ module Writexlsx
|
|
1397
1397
|
|
1398
1398
|
def write_crossing(crossing)
|
1399
1399
|
# Note, the category crossing comes from the value axis.
|
1400
|
-
if
|
1400
|
+
if [nil, 'max', 'min'].include?(crossing)
|
1401
1401
|
# Write the c:crosses element.
|
1402
1402
|
write_crosses(crossing)
|
1403
1403
|
else
|
@@ -2418,12 +2418,14 @@ module Writexlsx
|
|
2418
2418
|
elsif label[:formula]
|
2419
2419
|
write_custom_label_formula(label)
|
2420
2420
|
|
2421
|
+
write_d_lbl_pos(parent[:position]) if parent[:position]
|
2421
2422
|
write_show_val if parent[:value]
|
2422
2423
|
write_show_cat_name if parent[:category]
|
2423
2424
|
write_show_ser_name if parent[:series_name]
|
2424
2425
|
elsif label[:value]
|
2425
2426
|
write_custom_label_str(label)
|
2426
2427
|
|
2428
|
+
write_d_lbl_pos(parent[:position]) if parent[:position]
|
2427
2429
|
write_show_val if parent[:value]
|
2428
2430
|
write_show_cat_name if parent[:category]
|
2429
2431
|
write_show_ser_name if parent[:series_name]
|
@@ -2926,9 +2928,5 @@ module Writexlsx
|
|
2926
2928
|
@writer.empty_tag(tag)
|
2927
2929
|
end
|
2928
2930
|
end
|
2929
|
-
|
2930
|
-
def nil_or_max?(val) # :nodoc:
|
2931
|
-
val.nil? || val == 'max'
|
2932
|
-
end
|
2933
2931
|
end
|
2934
2932
|
end
|
data/lib/write_xlsx/drawing.rb
CHANGED
@@ -5,11 +5,11 @@ require 'write_xlsx/utility'
|
|
5
5
|
module Writexlsx
|
6
6
|
class Drawing
|
7
7
|
attr_accessor :type, :dimensions, :width, :height, :description, :shape, :anchor, :rel_index, :url_rel_index
|
8
|
-
attr_reader :tip
|
8
|
+
attr_reader :tip, :decorative
|
9
9
|
|
10
|
-
def initialize(type, dimensions, width, height, description, shape, anchor, rel_index = nil, url_rel_index = nil, tip = nil)
|
11
|
-
@type, @dimensions, @width, @height, @description, @shape, @anchor, @rel_index, @url_rel_index, @tip =
|
12
|
-
type, dimensions, width, height, description, shape, anchor, rel_index, url_rel_index, tip
|
10
|
+
def initialize(type, dimensions, width, height, description, shape, anchor, rel_index = nil, url_rel_index = nil, tip = nil, decorative = nil)
|
11
|
+
@type, @dimensions, @width, @height, @description, @shape, @anchor, @rel_index, @url_rel_index, @tip, @decorative =
|
12
|
+
type, dimensions, width, height, description, shape, anchor, rel_index, url_rel_index, tip, decorative
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
@@ -92,6 +92,7 @@ module Writexlsx
|
|
92
92
|
rel_index = drawing.rel_index
|
93
93
|
url_rel_index = drawing.url_rel_index
|
94
94
|
tip = drawing.tip
|
95
|
+
decorative = drawing.decorative
|
95
96
|
|
96
97
|
col_from, row_from, col_from_offset, row_from_offset,
|
97
98
|
col_to, row_to, col_to_offset, row_to_offset, col_absolute, row_absolute = drawing.dimensions
|
@@ -124,7 +125,7 @@ module Writexlsx
|
|
124
125
|
write_pic(
|
125
126
|
index, rel_index, col_absolute,
|
126
127
|
row_absolute, width, height,
|
127
|
-
description, url_rel_index , tip
|
128
|
+
description, url_rel_index , tip, decorative
|
128
129
|
)
|
129
130
|
else
|
130
131
|
# Write the xdr:sp element for shapes.
|
@@ -148,13 +149,13 @@ module Writexlsx
|
|
148
149
|
write_pos(0, 0)
|
149
150
|
|
150
151
|
# Write the xdr:ext element.
|
151
|
-
|
152
|
+
write_xdr_ext(9308969, 6078325)
|
152
153
|
else
|
153
154
|
# Write the xdr:pos element.
|
154
155
|
write_pos(0, -47625)
|
155
156
|
|
156
157
|
# Write the xdr:ext element.
|
157
|
-
|
158
|
+
write_xdr_ext(6162675, 6124575)
|
158
159
|
end
|
159
160
|
|
160
161
|
# Write the xdr:graphicFrame element.
|
@@ -242,7 +243,7 @@ module Writexlsx
|
|
242
243
|
#
|
243
244
|
# Write the <xdr:ext> element.
|
244
245
|
#
|
245
|
-
def
|
246
|
+
def write_xdr_ext(cx, cy)
|
246
247
|
attributes = [
|
247
248
|
['cx', cx],
|
248
249
|
['cy', cy]
|
@@ -286,19 +287,25 @@ module Writexlsx
|
|
286
287
|
#
|
287
288
|
# Write the <xdr:cNvPr> element.
|
288
289
|
#
|
289
|
-
def write_c_nv_pr(index, name, description = nil, url_rel_index = nil, tip = nil)
|
290
|
+
def write_c_nv_pr(index, name, description = nil, url_rel_index = nil, tip = nil, decorative = nil)
|
290
291
|
attributes = [
|
291
292
|
['id', index],
|
292
293
|
['name', name]
|
293
294
|
]
|
294
295
|
|
295
296
|
# Add description attribute for images.
|
296
|
-
attributes << ['descr', description] if description
|
297
|
+
attributes << ['descr', description] if ptrue?(description) && !ptrue?(decorative)
|
297
298
|
|
298
|
-
if ptrue?(url_rel_index)
|
299
|
+
if ptrue?(url_rel_index) || ptrue?(decorative)
|
299
300
|
@writer.tag_elements('xdr:cNvPr', attributes) do
|
300
|
-
|
301
|
-
|
301
|
+
if ptrue?(url_rel_index)
|
302
|
+
# Write the a:hlinkClick element.
|
303
|
+
write_a_hlink_click(url_rel_index, tip)
|
304
|
+
end
|
305
|
+
if ptrue?(decorative)
|
306
|
+
# Write the adec:decorative element.
|
307
|
+
write_decorative
|
308
|
+
end
|
302
309
|
end
|
303
310
|
else
|
304
311
|
@writer.empty_tag('xdr:cNvPr', attributes)
|
@@ -323,6 +330,62 @@ module Writexlsx
|
|
323
330
|
@writer.empty_tag('a:hlinkClick', attributes)
|
324
331
|
end
|
325
332
|
|
333
|
+
#
|
334
|
+
# Write the <adec:decorative> element.
|
335
|
+
#
|
336
|
+
def write_decorative
|
337
|
+
@writer.tag_elements('a:extLst') do
|
338
|
+
write_a_uri_ext('{FF2B5EF4-FFF2-40B4-BE49-F238E27FC236}')
|
339
|
+
write_a16_creation_id
|
340
|
+
@writer.end_tag('a:ext')
|
341
|
+
|
342
|
+
write_a_uri_ext('{C183D7F6-B498-43B3-948B-1728B52AA6E4}')
|
343
|
+
write_adec_decorative
|
344
|
+
@writer.end_tag('a:ext')
|
345
|
+
end
|
346
|
+
end
|
347
|
+
|
348
|
+
#
|
349
|
+
# Write the <a:ext> element.
|
350
|
+
#
|
351
|
+
def write_a_uri_ext(uri)
|
352
|
+
attributes = [
|
353
|
+
['uri', uri]
|
354
|
+
]
|
355
|
+
|
356
|
+
@writer.start_tag('a:ext', attributes)
|
357
|
+
end
|
358
|
+
|
359
|
+
#
|
360
|
+
# Write the <adec:decorative> element.
|
361
|
+
#
|
362
|
+
def write_adec_decorative
|
363
|
+
xmlns_adec = 'http://schemas.microsoft.com/office/drawing/2017/decorative'
|
364
|
+
val = 1
|
365
|
+
|
366
|
+
attributes = [
|
367
|
+
['xmlns:adec', xmlns_adec],
|
368
|
+
['val', val]
|
369
|
+
]
|
370
|
+
|
371
|
+
@writer.empty_tag('adec:decorative', attributes)
|
372
|
+
end
|
373
|
+
|
374
|
+
#
|
375
|
+
# Write the <a16:creationId> element.
|
376
|
+
#
|
377
|
+
def write_a16_creation_id
|
378
|
+
xmlns_a_16 = 'http://schemas.microsoft.com/office/drawing/2014/main'
|
379
|
+
id = '{00000000-0008-0000-0000-000002000000}'
|
380
|
+
|
381
|
+
attributes = [
|
382
|
+
['xmlns:a16', xmlns_a_16],
|
383
|
+
['id', id]
|
384
|
+
]
|
385
|
+
|
386
|
+
@writer.empty_tag('a16:creationId', attributes)
|
387
|
+
end
|
388
|
+
|
326
389
|
#
|
327
390
|
# Write the <xdr:cNvGraphicFramePr> element.
|
328
391
|
#
|
@@ -527,10 +590,10 @@ module Writexlsx
|
|
527
590
|
#
|
528
591
|
# Write the <xdr:pic> element.
|
529
592
|
#
|
530
|
-
def write_pic(index, rel_index, col_absolute, row_absolute, width, height, description, url_rel_index, tip)
|
593
|
+
def write_pic(index, rel_index, col_absolute, row_absolute, width, height, description, url_rel_index, tip, decorative)
|
531
594
|
@writer.tag_elements('xdr:pic') do
|
532
595
|
# Write the xdr:nvPicPr element.
|
533
|
-
write_nv_pic_pr(index, rel_index, description, url_rel_index, tip)
|
596
|
+
write_nv_pic_pr(index, rel_index, description, url_rel_index, tip, decorative)
|
534
597
|
# Write the xdr:blipFill element.
|
535
598
|
write_blip_fill(rel_index)
|
536
599
|
|
@@ -546,12 +609,12 @@ module Writexlsx
|
|
546
609
|
#
|
547
610
|
# Write the <xdr:nvPicPr> element.
|
548
611
|
#
|
549
|
-
def write_nv_pic_pr(index, rel_index, description, url_rel_index, tip)
|
612
|
+
def write_nv_pic_pr(index, rel_index, description, url_rel_index, tip, decorative)
|
550
613
|
@writer.tag_elements('xdr:nvPicPr') do
|
551
614
|
# Write the xdr:cNvPr element.
|
552
615
|
write_c_nv_pr(
|
553
616
|
index + 1, "Picture #{index}", description,
|
554
|
-
url_rel_index, tip
|
617
|
+
url_rel_index, tip, decorative
|
555
618
|
)
|
556
619
|
# Write the xdr:cNvPicPr element.
|
557
620
|
write_c_nv_pic_pr
|
@@ -7,6 +7,7 @@ module Writexlsx
|
|
7
7
|
class App
|
8
8
|
|
9
9
|
include Writexlsx::Utility
|
10
|
+
attr_writer :doc_security
|
10
11
|
|
11
12
|
def initialize(workbook)
|
12
13
|
@writer = Package::XMLWriterSimple.new
|
@@ -14,6 +15,7 @@ module Writexlsx
|
|
14
15
|
@part_names = []
|
15
16
|
@heading_pairs = []
|
16
17
|
@properties = {}
|
18
|
+
@doc_security = 0
|
17
19
|
end
|
18
20
|
|
19
21
|
def set_xml_writer(filename)
|
@@ -123,9 +125,7 @@ module Writexlsx
|
|
123
125
|
# Write the <DocSecurity> element.
|
124
126
|
#
|
125
127
|
def write_doc_security
|
126
|
-
|
127
|
-
|
128
|
-
@writer.data_element('DocSecurity', data)
|
128
|
+
@writer.data_element('DocSecurity', @doc_security)
|
129
129
|
end
|
130
130
|
|
131
131
|
#
|
@@ -397,14 +397,8 @@ module Writexlsx
|
|
397
397
|
def range_start_cell_for_conditional_formatting(*args) # :nodoc:
|
398
398
|
row1, row2, col1, col2, user_range, param =
|
399
399
|
row_col_param_for_conditional_formatting(*args)
|
400
|
-
|
401
|
-
|
402
|
-
range = xl_rowcol_to_cell(row1, col1)
|
403
|
-
@start_cell = range
|
404
|
-
else
|
405
|
-
range = xl_range(row1, row2, col1, col2)
|
406
|
-
@start_cell = xl_rowcol_to_cell(row1, col1)
|
407
|
-
end
|
400
|
+
range = xl_range(row1, row2, col1, col2)
|
401
|
+
@start_cell = xl_rowcol_to_cell(row1, col1)
|
408
402
|
|
409
403
|
# Override with user defined multiple range if provided.
|
410
404
|
range = user_range if user_range
|
@@ -155,6 +155,7 @@ module Writexlsx
|
|
155
155
|
app.add_named_ranges_parts
|
156
156
|
|
157
157
|
app.set_properties(@workbook.doc_properties)
|
158
|
+
app.doc_security = @workbook.read_only
|
158
159
|
|
159
160
|
FileUtils.mkdir_p("#{@package_dir}/docProps")
|
160
161
|
app.set_xml_writer("#{@package_dir}/docProps/app.xml")
|
@@ -253,11 +253,22 @@ module Writexlsx
|
|
253
253
|
# Write the <fill> element.
|
254
254
|
#
|
255
255
|
def write_fill(format, dxf_format = nil)
|
256
|
-
|
257
|
-
|
256
|
+
# Special handling for pattern only case.
|
257
|
+
if pattern_only_case?(format, dxf_format)
|
258
|
+
write_default_fill(PATTERNS[format.pattern])
|
259
|
+
else
|
260
|
+
@writer.tag_elements('fill' ) do
|
261
|
+
write_fill_base(format, dxf_format)
|
262
|
+
end
|
258
263
|
end
|
259
264
|
end
|
260
265
|
|
266
|
+
def pattern_only_case?(format, dxf_format)
|
267
|
+
bg_color, fg_color = bg_and_fg_color(format, dxf_format)
|
268
|
+
|
269
|
+
!ptrue?(fg_color) && !ptrue?(bg_color) && ptrue?(format.pattern)
|
270
|
+
end
|
271
|
+
|
261
272
|
def write_fill_base(format, dxf_format)
|
262
273
|
# The "none" pattern is handled differently for dxf formats.
|
263
274
|
if dxf_format && format.pattern <= 1
|
@@ -281,7 +292,9 @@ module Writexlsx
|
|
281
292
|
if bg_color && bg_color != 0
|
282
293
|
@writer.empty_tag('bgColor', [ ['rgb', palette_color(bg_color)] ])
|
283
294
|
else
|
284
|
-
|
295
|
+
if !dxf_format && format.pattern <= 1
|
296
|
+
@writer.empty_tag('bgColor', [ ['indexed', 64] ])
|
297
|
+
end
|
285
298
|
end
|
286
299
|
end
|
287
300
|
|
data/lib/write_xlsx/utility.rb
CHANGED
@@ -60,7 +60,11 @@ module Writexlsx
|
|
60
60
|
range1 = xl_rowcol_to_cell(row_1, col_1, row_abs_1, col_abs_1)
|
61
61
|
range2 = xl_rowcol_to_cell(row_2, col_2, row_abs_2, col_abs_2)
|
62
62
|
|
63
|
-
|
63
|
+
if range1 == range2
|
64
|
+
range1
|
65
|
+
else
|
66
|
+
"#{range1}:#{range2}"
|
67
|
+
end
|
64
68
|
end
|
65
69
|
|
66
70
|
def xl_range_formula(sheetname, row_1, row_2, col_1, col_2)
|
data/lib/write_xlsx/version.rb
CHANGED
@@ -1 +1 @@
|
|
1
|
-
WriteXLSX_VERSION = "1.
|
1
|
+
WriteXLSX_VERSION = "1.08.0"
|
data/lib/write_xlsx/workbook.rb
CHANGED
@@ -52,6 +52,7 @@ module Writexlsx
|
|
52
52
|
attr_reader :max_url_length # :nodoc:
|
53
53
|
attr_reader :strings_to_urls # :nodoc:
|
54
54
|
attr_reader :default_url_format # :nodoc:
|
55
|
+
attr_reader :read_only # :nodoc:
|
55
56
|
|
56
57
|
#
|
57
58
|
# A new Excel workbook is created using the +new+ constructor
|
@@ -133,6 +134,7 @@ module Writexlsx
|
|
133
134
|
|
134
135
|
@max_url_length = 2079
|
135
136
|
@has_comments = false
|
137
|
+
@read_only = 0
|
136
138
|
if options[:max_url_length]
|
137
139
|
@max_url_length = options[:max_url_length]
|
138
140
|
|
@@ -292,6 +294,9 @@ module Writexlsx
|
|
292
294
|
# Write the XLSX file version.
|
293
295
|
write_file_version
|
294
296
|
|
297
|
+
# Write the fileSharing element.
|
298
|
+
write_file_sharing
|
299
|
+
|
295
300
|
# Write the workbook properties.
|
296
301
|
write_workbook_pr
|
297
302
|
|
@@ -954,6 +959,13 @@ module Writexlsx
|
|
954
959
|
end
|
955
960
|
end
|
956
961
|
|
962
|
+
#
|
963
|
+
# Set the Excel "Read-only recommended" save option.
|
964
|
+
#
|
965
|
+
def read_only_recommended
|
966
|
+
@read_only = 2
|
967
|
+
end
|
968
|
+
|
957
969
|
#
|
958
970
|
# set_calc_mode()
|
959
971
|
#
|
@@ -1311,6 +1323,17 @@ module Writexlsx
|
|
1311
1323
|
@writer.empty_tag('fileVersion', attributes)
|
1312
1324
|
end
|
1313
1325
|
|
1326
|
+
#
|
1327
|
+
# Write the <fileSharing> element.
|
1328
|
+
#
|
1329
|
+
def write_file_sharing
|
1330
|
+
return if !ptrue?(@read_only)
|
1331
|
+
|
1332
|
+
attributes = []
|
1333
|
+
attributes << ['readOnlyRecommended', 1]
|
1334
|
+
@writer.empty_tag('fileSharing', attributes)
|
1335
|
+
end
|
1336
|
+
|
1314
1337
|
def write_workbook_pr #:nodoc:
|
1315
1338
|
attributes = []
|
1316
1339
|
attributes << ['codeName', @vba_codename] if ptrue?(@vba_codename)
|
@@ -138,12 +138,7 @@ module Writexlsx
|
|
138
138
|
row_first, row_last = row_last, row_first if row_first > row_last
|
139
139
|
col_first, col_last = col_last, col_first if col_first > col_last
|
140
140
|
|
141
|
-
|
142
|
-
if row_first == row_last && col_first == col_last
|
143
|
-
sqref += xl_rowcol_to_cell(row_first, col_first)
|
144
|
-
else
|
145
|
-
sqref += xl_range(row_first, row_last, col_first, col_last)
|
146
|
-
end
|
141
|
+
sqref += xl_range(row_first, row_last, col_first, col_last)
|
147
142
|
end
|
148
143
|
|
149
144
|
if @validate != 'none'
|
data/lib/write_xlsx/worksheet.rb
CHANGED
@@ -388,6 +388,9 @@ module Writexlsx
|
|
388
388
|
@data_bars_2010 = []
|
389
389
|
@dxf_priority = 1
|
390
390
|
|
391
|
+
@protected_ranges = []
|
392
|
+
@num_protected_ranges = 0
|
393
|
+
|
391
394
|
if excel2003_style?
|
392
395
|
@original_row_height = 12.75
|
393
396
|
@default_row_height = 12.75
|
@@ -414,6 +417,7 @@ module Writexlsx
|
|
414
417
|
write_cols
|
415
418
|
write_sheet_data
|
416
419
|
write_sheet_protection
|
420
|
+
write_protected_ranges
|
417
421
|
# write_sheet_calc_pr
|
418
422
|
write_phonetic_pr if excel2003_style?
|
419
423
|
write_auto_filter
|
@@ -616,7 +620,25 @@ module Writexlsx
|
|
616
620
|
|
617
621
|
# Set the password after the user defined values.
|
618
622
|
@protect[:password] =
|
619
|
-
|
623
|
+
encode_password(password) if password && password != ''
|
624
|
+
end
|
625
|
+
|
626
|
+
#
|
627
|
+
# Unprotect ranges within a protected worksheet.
|
628
|
+
#
|
629
|
+
def unprotect_range(range, range_name = nil, password = nil)
|
630
|
+
if range.nil?
|
631
|
+
raise "The range must be defined in unprotect_range())\n"
|
632
|
+
else
|
633
|
+
range.gsub!(/\$/, "")
|
634
|
+
range.sub!(/^=/, "")
|
635
|
+
@num_protected_ranges += 1
|
636
|
+
end
|
637
|
+
|
638
|
+
range_name ||= "Range#{@num_protected_ranges}"
|
639
|
+
password &&= encode_password(password)
|
640
|
+
|
641
|
+
@protected_ranges << [range, range_name, password]
|
620
642
|
end
|
621
643
|
|
622
644
|
def protect_default_settings # :nodoc:
|
@@ -818,12 +840,7 @@ module Writexlsx
|
|
818
840
|
row_first, row_last = row_last, row_first if row_first > row_last
|
819
841
|
col_first, col_last = col_last, col_first if col_first > col_last
|
820
842
|
|
821
|
-
|
822
|
-
if row_first == row_last && col_first == col_last
|
823
|
-
sqref = active_cell
|
824
|
-
else
|
825
|
-
sqref = xl_range(row_first, row_last, col_first, col_last)
|
826
|
-
end
|
843
|
+
sqref = xl_range(row_first, row_last, col_first, col_last)
|
827
844
|
else # Single cell selection.
|
828
845
|
sqref = active_cell
|
829
846
|
end
|
@@ -3048,14 +3065,16 @@ module Writexlsx
|
|
3048
3065
|
|
3049
3066
|
if options.first.class == Hash
|
3050
3067
|
# Newer hash bashed options
|
3051
|
-
params
|
3052
|
-
x_offset
|
3053
|
-
y_offset
|
3054
|
-
x_scale
|
3055
|
-
y_scale
|
3056
|
-
anchor
|
3057
|
-
url
|
3058
|
-
tip
|
3068
|
+
params = options.first
|
3069
|
+
x_offset = params[:x_offset]
|
3070
|
+
y_offset = params[:y_offset]
|
3071
|
+
x_scale = params[:x_scale]
|
3072
|
+
y_scale = params[:y_scale]
|
3073
|
+
anchor = params[:object_position]
|
3074
|
+
url = params[:url]
|
3075
|
+
tip = params[:tip]
|
3076
|
+
description = params[:description]
|
3077
|
+
decorative = params[:decorative]
|
3059
3078
|
else
|
3060
3079
|
x_offset, y_offset, x_scale, y_scale, anchor = options
|
3061
3080
|
end
|
@@ -3067,7 +3086,7 @@ module Writexlsx
|
|
3067
3086
|
|
3068
3087
|
@images << [
|
3069
3088
|
row, col, image, x_offset, y_offset,
|
3070
|
-
x_scale, y_scale, url, tip, anchor
|
3089
|
+
x_scale, y_scale, url, tip, anchor, description, decorative
|
3071
3090
|
]
|
3072
3091
|
end
|
3073
3092
|
|
@@ -5744,7 +5763,7 @@ module Writexlsx
|
|
5744
5763
|
name = chart.name
|
5745
5764
|
|
5746
5765
|
# Create a Drawing object to use with worksheet unless one already exists.
|
5747
|
-
drawing = Drawing.new(drawing_type, dimensions, 0, 0, name, nil, anchor, drawing_rel_index, 0, nil)
|
5766
|
+
drawing = Drawing.new(drawing_type, dimensions, 0, 0, name, nil, anchor, drawing_rel_index, 0, nil, 0)
|
5748
5767
|
if !drawings?
|
5749
5768
|
@drawings = Drawings.new
|
5750
5769
|
@drawings.add_drawing_object(drawing)
|
@@ -6470,7 +6489,7 @@ module Writexlsx
|
|
6470
6489
|
drawing_type = 2
|
6471
6490
|
|
6472
6491
|
row, col, image, x_offset, y_offset,
|
6473
|
-
x_scale, y_scale, url, tip, anchor = @images[index]
|
6492
|
+
x_scale, y_scale, url, tip, anchor, description, decorative = @images[index]
|
6474
6493
|
|
6475
6494
|
width *= x_scale
|
6476
6495
|
height *= y_scale
|
@@ -6485,7 +6504,7 @@ module Writexlsx
|
|
6485
6504
|
height = (0.5 + (height * 9_525)).to_i
|
6486
6505
|
|
6487
6506
|
# Create a Drawing object to use with worksheet unless one already exists.
|
6488
|
-
drawing = Drawing.new(drawing_type, dimensions, width, height, name, nil, anchor, 0, 0, tip)
|
6507
|
+
drawing = Drawing.new(drawing_type, dimensions, width, height, name, nil, anchor, 0, 0, tip, decorative)
|
6489
6508
|
if !drawings?
|
6490
6509
|
drawings = Drawings.new
|
6491
6510
|
drawings.embedded = 1
|
@@ -6498,6 +6517,10 @@ module Writexlsx
|
|
6498
6517
|
end
|
6499
6518
|
drawings.add_drawing_object(drawing)
|
6500
6519
|
|
6520
|
+
if description
|
6521
|
+
drawing.description = description
|
6522
|
+
end
|
6523
|
+
|
6501
6524
|
if url
|
6502
6525
|
rel_type = '/hyperlink'
|
6503
6526
|
target_mode = 'External'
|
@@ -6651,7 +6674,7 @@ EOS
|
|
6651
6674
|
shape.calc_position_emus(self)
|
6652
6675
|
|
6653
6676
|
drawing_type = 3
|
6654
|
-
drawing = Drawing.new(drawing_type, shape.dimensions, shape.width_emu, shape.height_emu, shape.name, shape, shape.anchor, drawing_rel_index, 0, nil)
|
6677
|
+
drawing = Drawing.new(drawing_type, shape.dimensions, shape.width_emu, shape.height_emu, shape.name, shape, shape.anchor, drawing_rel_index, 0, nil, 0)
|
6655
6678
|
drawings.add_drawing_object(drawing)
|
6656
6679
|
end
|
6657
6680
|
public :prepare_shape
|
@@ -6741,6 +6764,8 @@ EOS
|
|
6741
6764
|
chars.each { |c| encoded_password ^= c }
|
6742
6765
|
encoded_password ^= count
|
6743
6766
|
encoded_password ^= 0xCE4B
|
6767
|
+
|
6768
|
+
sprintf("%X", encoded_password)
|
6744
6769
|
end
|
6745
6770
|
|
6746
6771
|
#
|
@@ -7556,6 +7581,32 @@ EOS
|
|
7556
7581
|
@writer.empty_tag('sheetProtection', attributes)
|
7557
7582
|
end
|
7558
7583
|
|
7584
|
+
#
|
7585
|
+
# Write the <protectedRanges> element.
|
7586
|
+
#
|
7587
|
+
def write_protected_ranges
|
7588
|
+
return if @num_protected_ranges == 0
|
7589
|
+
|
7590
|
+
@writer.tag_elements('protectedRanges') do
|
7591
|
+
@protected_ranges.each do |protected_range|
|
7592
|
+
write_protected_range(*protected_range)
|
7593
|
+
end
|
7594
|
+
end
|
7595
|
+
end
|
7596
|
+
|
7597
|
+
#
|
7598
|
+
# Write the <protectedRange> element.
|
7599
|
+
#
|
7600
|
+
def write_protected_range(sqref, name, password)
|
7601
|
+
attributes = []
|
7602
|
+
|
7603
|
+
attributes << ['password', password] if password
|
7604
|
+
attributes << ['sqref', sqref]
|
7605
|
+
attributes << ['name', name]
|
7606
|
+
|
7607
|
+
@writer.empty_tag('protectedRange', attributes)
|
7608
|
+
end
|
7609
|
+
|
7559
7610
|
#
|
7560
7611
|
# Write the <drawing> elements.
|
7561
7612
|
#
|
@@ -2,7 +2,7 @@
|
|
2
2
|
require 'helper'
|
3
3
|
require 'write_xlsx/drawing'
|
4
4
|
|
5
|
-
class
|
5
|
+
class TestWriteXdrExt < Minitest::Test
|
6
6
|
def setup
|
7
7
|
@drawing = Writexlsx::Drawings.new
|
8
8
|
end
|
@@ -10,7 +10,7 @@ class TestWriteExt < Minitest::Test
|
|
10
10
|
def test_write_ext
|
11
11
|
expected = '<xdr:ext cx="9308969" cy="6078325"/>'
|
12
12
|
|
13
|
-
@drawing.__send__(:
|
13
|
+
@drawing.__send__(:write_xdr_ext, 9308969, 6078325)
|
14
14
|
result = @drawing.instance_variable_get(:@writer).string
|
15
15
|
|
16
16
|
assert_equal(expected, result)
|
@@ -33,7 +33,7 @@ class TestRegressionChartCrossing01 < Minitest::Test
|
|
33
33
|
|
34
34
|
chart.set_y_axis(:crossing => 'max')
|
35
35
|
|
36
|
-
# Not
|
36
|
+
# Not strictly required. Just to match reference file.
|
37
37
|
chart.set_x_axis(:position => 't')
|
38
38
|
|
39
39
|
worksheet.insert_chart('E9', chart)
|