write_xlsx 1.07.0 → 1.08.0
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/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)
|