write_xlsx 1.02.0 → 1.08.1
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/.travis.yml +0 -1
- data/Changes +72 -0
- data/README.md +1 -1
- data/examples/chart_data_labels.rb +320 -0
- data/examples/chart_line.rb +85 -10
- data/examples/tables.rb +77 -42
- data/lib/write_xlsx/chart/line.rb +15 -1
- data/lib/write_xlsx/chart/series.rb +100 -0
- data/lib/write_xlsx/chart.rb +155 -33
- data/lib/write_xlsx/drawing.rb +80 -17
- data/lib/write_xlsx/format.rb +5 -5
- data/lib/write_xlsx/package/app.rb +3 -3
- data/lib/write_xlsx/package/comments.rb +4 -4
- data/lib/write_xlsx/package/conditional_format.rb +2 -8
- data/lib/write_xlsx/package/packager.rb +1 -0
- data/lib/write_xlsx/package/relationships.rb +2 -2
- data/lib/write_xlsx/package/styles.rb +42 -11
- data/lib/write_xlsx/package/table.rb +16 -7
- data/lib/write_xlsx/package/vml.rb +20 -19
- data/lib/write_xlsx/sheets.rb +12 -20
- data/lib/write_xlsx/utility.rb +9 -3
- data/lib/write_xlsx/version.rb +1 -1
- data/lib/write_xlsx/workbook.rb +76 -35
- data/lib/write_xlsx/worksheet/data_validation.rb +1 -6
- data/lib/write_xlsx/worksheet.rb +197 -57
- data/test/drawing/{test_write_ext.rb → test_write_xdr_ext.rb} +2 -2
- data/test/perl_output/chart_data_labels.xlsx +0 -0
- data/test/perl_output/chart_line.xlsx +0 -0
- data/test/perl_output/comments2.xlsx +0 -0
- data/test/perl_output/tables.xlsx +0 -0
- data/test/regression/images/red2.png +0 -0
- data/test/regression/test_array_formula04.rb +31 -0
- 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_labels26.rb +44 -0
- data/test/regression/test_chart_data_labels27.rb +44 -0
- data/test/regression/test_chart_data_labels28.rb +52 -0
- data/test/regression/test_chart_data_labels29.rb +43 -0
- data/test/regression/test_chart_data_labels30.rb +46 -0
- data/test/regression/test_chart_data_labels31.rb +49 -0
- data/test/regression/test_chart_data_labels32.rb +54 -0
- data/test/regression/test_chart_data_labels33.rb +52 -0
- data/test/regression/test_chart_data_labels34.rb +54 -0
- data/test/regression/test_chart_data_labels35.rb +46 -0
- data/test/regression/test_chart_data_labels36.rb +54 -0
- data/test/regression/test_chart_data_labels37.rb +51 -0
- data/test/regression/test_chart_data_labels38.rb +54 -0
- data/test/regression/test_chart_data_labels39.rb +53 -0
- data/test/regression/test_chart_data_labels40.rb +53 -0
- data/test/regression/test_chart_data_labels41.rb +54 -0
- data/test/regression/test_chart_data_labels42.rb +58 -0
- data/test/regression/test_chart_data_labels43.rb +58 -0
- data/test/regression/test_chart_data_labels44.rb +56 -0
- data/test/regression/test_chart_data_labels45.rb +57 -0
- data/test/regression/test_chart_data_labels46.rb +61 -0
- data/test/regression/test_chart_data_labels47.rb +61 -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_chart_line05.rb +43 -0
- data/test/regression/test_chart_line06.rb +43 -0
- data/test/regression/test_comment15.rb +28 -0
- data/test/regression/test_comment16.rb +34 -0
- data/test/regression/test_format16.rb +24 -0
- data/test/regression/test_format17.rb +24 -0
- data/test/regression/test_header04.rb +30 -0
- data/test/regression/test_header_image15.rb +36 -0
- data/test/regression/test_header_image16.rb +42 -0
- data/test/regression/test_header_image17.rb +46 -0
- data/test/regression/test_header_image18.rb +48 -0
- data/test/regression/test_header_image19.rb +36 -0
- data/test/regression/test_hyperlink48.rb +31 -0
- data/test/regression/test_hyperlink49.rb +29 -0
- data/test/regression/test_hyperlink50.rb +27 -0
- data/test/regression/test_hyperlink51.rb +27 -0
- data/test/regression/test_ignore_error01.rb +23 -0
- data/test/regression/test_ignore_error02.rb +24 -0
- data/test/regression/test_ignore_error03.rb +26 -0
- data/test/regression/test_ignore_error04.rb +26 -0
- data/test/regression/test_ignore_error05.rb +32 -0
- data/test/regression/test_ignore_error06.rb +32 -0
- data/test/regression/test_image45.rb +2 -1
- data/test/regression/test_image46.rb +1 -1
- data/test/regression/test_image48.rb +32 -0
- data/test/regression/test_image49.rb +38 -0
- data/test/regression/test_image50.rb +24 -0
- data/test/regression/test_image51.rb +30 -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_object_position12.rb +25 -0
- data/test/regression/test_object_position13.rb +25 -0
- data/test/regression/test_object_position14.rb +25 -0
- data/test/regression/test_object_position15.rb +29 -0
- data/test/regression/test_object_position16.rb +29 -0
- data/test/regression/test_object_position17.rb +29 -0
- data/test/regression/test_object_position18.rb +29 -0
- data/test/regression/test_object_position19.rb +29 -0
- data/test/regression/test_object_position20.rb +29 -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/test_table24.rb +27 -0
- data/test/regression/test_table25.rb +27 -0
- data/test/regression/test_table26.rb +38 -0
- data/test/regression/xlsx_files/array_formula04.xlsx +0 -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_labels26.xlsx +0 -0
- data/test/regression/xlsx_files/chart_data_labels27.xlsx +0 -0
- data/test/regression/xlsx_files/chart_data_labels28.xlsx +0 -0
- data/test/regression/xlsx_files/chart_data_labels29.xlsx +0 -0
- data/test/regression/xlsx_files/chart_data_labels30.xlsx +0 -0
- data/test/regression/xlsx_files/chart_data_labels31.xlsx +0 -0
- data/test/regression/xlsx_files/chart_data_labels32.xlsx +0 -0
- data/test/regression/xlsx_files/chart_data_labels33.xlsx +0 -0
- data/test/regression/xlsx_files/chart_data_labels34.xlsx +0 -0
- data/test/regression/xlsx_files/chart_data_labels35.xlsx +0 -0
- data/test/regression/xlsx_files/chart_data_labels36.xlsx +0 -0
- data/test/regression/xlsx_files/chart_data_labels37.xlsx +0 -0
- data/test/regression/xlsx_files/chart_data_labels38.xlsx +0 -0
- data/test/regression/xlsx_files/chart_data_labels39.xlsx +0 -0
- data/test/regression/xlsx_files/chart_data_labels40.xlsx +0 -0
- data/test/regression/xlsx_files/chart_data_labels41.xlsx +0 -0
- data/test/regression/xlsx_files/chart_data_labels42.xlsx +0 -0
- data/test/regression/xlsx_files/chart_data_labels43.xlsx +0 -0
- data/test/regression/xlsx_files/chart_data_labels44.xlsx +0 -0
- data/test/regression/xlsx_files/chart_data_labels45.xlsx +0 -0
- data/test/regression/xlsx_files/chart_data_labels46.xlsx +0 -0
- data/test/regression/xlsx_files/chart_data_labels47.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/chart_line05.xlsx +0 -0
- data/test/regression/xlsx_files/chart_line06.xlsx +0 -0
- data/test/regression/xlsx_files/comment15.xlsx +0 -0
- data/test/regression/xlsx_files/comment16.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/header04.xlsx +0 -0
- data/test/regression/xlsx_files/header_image15.xlsx +0 -0
- data/test/regression/xlsx_files/header_image16.xlsx +0 -0
- data/test/regression/xlsx_files/header_image17.xlsx +0 -0
- data/test/regression/xlsx_files/header_image18.xlsx +0 -0
- data/test/regression/xlsx_files/header_image19.xlsx +0 -0
- data/test/regression/xlsx_files/hyperlink46.xlsx +0 -0
- data/test/regression/xlsx_files/hyperlink50.xlsx +0 -0
- data/test/regression/xlsx_files/hyperlink51.xlsx +0 -0
- data/test/regression/xlsx_files/ignore_error01.xlsx +0 -0
- data/test/regression/xlsx_files/ignore_error02.xlsx +0 -0
- data/test/regression/xlsx_files/ignore_error03.xlsx +0 -0
- data/test/regression/xlsx_files/ignore_error04.xlsx +0 -0
- data/test/regression/xlsx_files/ignore_error05.xlsx +0 -0
- data/test/regression/xlsx_files/ignore_error06.xlsx +0 -0
- data/test/regression/xlsx_files/image45.xlsx +0 -0
- data/test/regression/xlsx_files/image46.xlsx +0 -0
- data/test/regression/xlsx_files/image48.xlsx +0 -0
- data/test/regression/xlsx_files/image49.xlsx +0 -0
- data/test/regression/xlsx_files/image50.xlsx +0 -0
- data/test/regression/xlsx_files/image51.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/object_position12.xlsx +0 -0
- data/test/regression/xlsx_files/object_position13.xlsx +0 -0
- data/test/regression/xlsx_files/object_position14.xlsx +0 -0
- data/test/regression/xlsx_files/object_position15.xlsx +0 -0
- data/test/regression/xlsx_files/object_position16.xlsx +0 -0
- data/test/regression/xlsx_files/object_position17.xlsx +0 -0
- data/test/regression/xlsx_files/object_position18.xlsx +0 -0
- data/test/regression/xlsx_files/object_position19.xlsx +0 -0
- data/test/regression/xlsx_files/object_position20.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/regression/xlsx_files/table24.xlsx +0 -0
- data/test/regression/xlsx_files/table25.xlsx +0 -0
- data/test/regression/xlsx_files/table26.xlsx +0 -0
- data/test/test_example_match.rb +433 -10
- data/test/utility/test_range.rb +20 -0
- data/test/workbook/test_check_sheetname.rb +0 -10
- data/write_xlsx.gemspec +1 -0
- metadata +323 -8
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
|
data/lib/write_xlsx/format.rb
CHANGED
|
@@ -248,11 +248,11 @@ module Writexlsx
|
|
|
248
248
|
#
|
|
249
249
|
def copy(other)
|
|
250
250
|
reserve = [
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
251
|
+
:xf_index,
|
|
252
|
+
:dxf_index,
|
|
253
|
+
:xdf_format_indices,
|
|
254
|
+
:palette
|
|
255
|
+
]
|
|
256
256
|
(instance_variables - reserve).each do |v|
|
|
257
257
|
instance_variable_set(v, other.instance_variable_get(v))
|
|
258
258
|
end
|
|
@@ -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
|
#
|
|
@@ -155,7 +155,7 @@ module Writexlsx
|
|
|
155
155
|
#
|
|
156
156
|
def fill_attributes
|
|
157
157
|
[
|
|
158
|
-
|
|
158
|
+
['color2', '#ffffe1']
|
|
159
159
|
]
|
|
160
160
|
end
|
|
161
161
|
|
|
@@ -164,9 +164,9 @@ module Writexlsx
|
|
|
164
164
|
#
|
|
165
165
|
def write_shadow
|
|
166
166
|
attributes = [
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
167
|
+
['on', 't'],
|
|
168
|
+
['color', 'black'],
|
|
169
|
+
['obscured', 't']
|
|
170
170
|
]
|
|
171
171
|
|
|
172
172
|
@writer.empty_tag('v:shadow', attributes)
|
|
@@ -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")
|
|
@@ -20,6 +20,7 @@ module Writexlsx
|
|
|
20
20
|
@dxf_formats = []
|
|
21
21
|
@has_hyperlink = 0
|
|
22
22
|
@hyperlink_font_id = 0
|
|
23
|
+
@has_comments = false
|
|
23
24
|
end
|
|
24
25
|
|
|
25
26
|
def set_xml_writer(filename)
|
|
@@ -37,7 +38,7 @@ module Writexlsx
|
|
|
37
38
|
#
|
|
38
39
|
def set_style_properties(
|
|
39
40
|
xf_formats, palette, font_count, num_format_count, border_count,
|
|
40
|
-
fill_count, custom_colors, dxf_formats
|
|
41
|
+
fill_count, custom_colors, dxf_formats, has_comments
|
|
41
42
|
)
|
|
42
43
|
@xf_formats = xf_formats
|
|
43
44
|
@palette = palette
|
|
@@ -47,6 +48,7 @@ module Writexlsx
|
|
|
47
48
|
@fill_count = fill_count
|
|
48
49
|
@custom_colors = custom_colors
|
|
49
50
|
@dxf_formats = dxf_formats
|
|
51
|
+
@has_comments = has_comments
|
|
50
52
|
end
|
|
51
53
|
|
|
52
54
|
#
|
|
@@ -148,7 +150,14 @@ module Writexlsx
|
|
|
148
150
|
# Write the <fonts> element.
|
|
149
151
|
#
|
|
150
152
|
def write_fonts
|
|
151
|
-
|
|
153
|
+
count = @font_count
|
|
154
|
+
|
|
155
|
+
if @has_comments
|
|
156
|
+
# Add an extra font for comments.
|
|
157
|
+
count += 1
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
write_format_elements('fonts', count) do
|
|
152
161
|
write_font_base
|
|
153
162
|
end
|
|
154
163
|
end
|
|
@@ -161,6 +170,21 @@ module Writexlsx
|
|
|
161
170
|
@hyperlink_font_id = format.font_index unless ptrue?(@hyperlink_font_id)
|
|
162
171
|
end
|
|
163
172
|
end
|
|
173
|
+
if @has_comments
|
|
174
|
+
write_comment_font
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
#
|
|
179
|
+
# Write the <font> element used for comments.
|
|
180
|
+
#
|
|
181
|
+
def write_comment_font
|
|
182
|
+
@writer.tag_elements('font') do
|
|
183
|
+
@writer.empty_tag('sz', [['val', 8]])
|
|
184
|
+
write_color('indexed', 81)
|
|
185
|
+
@writer.empty_tag( 'name', [['val', 'Tahoma']])
|
|
186
|
+
@writer.empty_tag( 'family', [['val', 2]])
|
|
187
|
+
end
|
|
164
188
|
end
|
|
165
189
|
|
|
166
190
|
#
|
|
@@ -229,11 +253,22 @@ module Writexlsx
|
|
|
229
253
|
# Write the <fill> element.
|
|
230
254
|
#
|
|
231
255
|
def write_fill(format, dxf_format = nil)
|
|
232
|
-
|
|
233
|
-
|
|
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
|
|
234
263
|
end
|
|
235
264
|
end
|
|
236
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
|
+
|
|
237
272
|
def write_fill_base(format, dxf_format)
|
|
238
273
|
# The "none" pattern is handled differently for dxf formats.
|
|
239
274
|
if dxf_format && format.pattern <= 1
|
|
@@ -257,7 +292,9 @@ module Writexlsx
|
|
|
257
292
|
if bg_color && bg_color != 0
|
|
258
293
|
@writer.empty_tag('bgColor', [ ['rgb', palette_color(bg_color)] ])
|
|
259
294
|
else
|
|
260
|
-
|
|
295
|
+
if !dxf_format && format.pattern <= 1
|
|
296
|
+
@writer.empty_tag('bgColor', [ ['indexed', 64] ])
|
|
297
|
+
end
|
|
261
298
|
end
|
|
262
299
|
end
|
|
263
300
|
|
|
@@ -394,12 +431,6 @@ module Writexlsx
|
|
|
394
431
|
def write_cell_xfs
|
|
395
432
|
formats = @xf_formats
|
|
396
433
|
|
|
397
|
-
# Workaround for when the last format is used for the comment font
|
|
398
|
-
# and shouldn't be used for cellXfs.
|
|
399
|
-
last_format = formats[-1]
|
|
400
|
-
|
|
401
|
-
formats.pop if last_format && last_format.font_only != 0
|
|
402
|
-
|
|
403
434
|
attributes = [ ['count', formats.size] ]
|
|
404
435
|
|
|
405
436
|
@writer.tag_elements('cellXfs', attributes) do
|
|
@@ -189,6 +189,14 @@ module Writexlsx
|
|
|
189
189
|
param[:header_row] ||= 1
|
|
190
190
|
param[:autofilter] ||= 1
|
|
191
191
|
|
|
192
|
+
# Check that there are enough rows.
|
|
193
|
+
num_rows = row2 - row1
|
|
194
|
+
num_rows -= 1 if ptrue?(param[:header_row])
|
|
195
|
+
|
|
196
|
+
if num_rows < 0
|
|
197
|
+
raise "Must have at least one data row in in add_table()"
|
|
198
|
+
end
|
|
199
|
+
|
|
192
200
|
# If the header row if off the default is to turn autofilter off.
|
|
193
201
|
param[:autofilter] = 0 if param[:header_row] == 0
|
|
194
202
|
|
|
@@ -398,13 +406,14 @@ module Writexlsx
|
|
|
398
406
|
# Write the <tableStyleInfo> element.
|
|
399
407
|
#
|
|
400
408
|
def write_table_style_info
|
|
401
|
-
attributes = [
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
409
|
+
attributes = []
|
|
410
|
+
if @style && @style != '' && @style != 'None'
|
|
411
|
+
attributes << ['name', @style]
|
|
412
|
+
end
|
|
413
|
+
attributes << ['showFirstColumn', @show_first_col]
|
|
414
|
+
attributes << ['showLastColumn', @show_last_col]
|
|
415
|
+
attributes << ['showRowStripes', @show_row_stripes]
|
|
416
|
+
attributes << ['showColumnStripes', @show_col_stripes]
|
|
408
417
|
|
|
409
418
|
@writer.empty_tag('tableStyleInfo', attributes)
|
|
410
419
|
end
|
|
@@ -17,9 +17,9 @@ module Writexlsx
|
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
def assemble_xml_file(
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
data_id, vml_shape_id, comments_data,
|
|
21
|
+
buttons_data, header_images_data = []
|
|
22
|
+
)
|
|
23
23
|
return unless @writer
|
|
24
24
|
|
|
25
25
|
write_xml_namespace do
|
|
@@ -29,9 +29,9 @@ module Writexlsx
|
|
|
29
29
|
z_index = 1
|
|
30
30
|
unless buttons_data.empty?
|
|
31
31
|
vml_shape_id, z_index =
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
write_shape_type_and_shape(
|
|
33
|
+
buttons_data,
|
|
34
|
+
vml_shape_id, z_index) do
|
|
35
35
|
write_button_shapetype
|
|
36
36
|
end
|
|
37
37
|
end
|
|
@@ -277,6 +277,7 @@ module Writexlsx
|
|
|
277
277
|
position = image_data[3]
|
|
278
278
|
x_dpi = image_data[4]
|
|
279
279
|
y_dpi = image_data[5]
|
|
280
|
+
ref_id = image_data[6]
|
|
280
281
|
|
|
281
282
|
# Scale the height/width by the resolution, relative to 72dpi.
|
|
282
283
|
width = width * 72.0 / x_dpi
|
|
@@ -294,20 +295,20 @@ module Writexlsx
|
|
|
294
295
|
end
|
|
295
296
|
|
|
296
297
|
style = [
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
298
|
+
"position:absolute", "margin-left:0", "margin-top:0",
|
|
299
|
+
"width:#{width}pt", "height:#{height}pt",
|
|
300
|
+
"z-index:#{index}"
|
|
301
|
+
].join(';')
|
|
301
302
|
attributes = [
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
303
|
+
['id', position],
|
|
304
|
+
['o:spid', "_x0000_s#{id}"],
|
|
305
|
+
['type', type],
|
|
306
|
+
['style', style]
|
|
307
|
+
]
|
|
307
308
|
|
|
308
309
|
@writer.tag_elements('v:shape', attributes) do
|
|
309
310
|
# Write the v:imagedata element.
|
|
310
|
-
write_imagedata(
|
|
311
|
+
write_imagedata(ref_id, name)
|
|
311
312
|
|
|
312
313
|
# Write the o:lock element.
|
|
313
314
|
write_rotation_lock
|
|
@@ -319,9 +320,9 @@ module Writexlsx
|
|
|
319
320
|
#
|
|
320
321
|
def write_imagedata(index, o_title)
|
|
321
322
|
attributes = [
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
323
|
+
['o:relid', "rId#{index}"],
|
|
324
|
+
['o:title', o_title]
|
|
325
|
+
]
|
|
325
326
|
|
|
326
327
|
@writer.empty_tag('v:imagedata', attributes)
|
|
327
328
|
end
|
data/lib/write_xlsx/sheets.rb
CHANGED
|
@@ -67,18 +67,18 @@ module Writexlsx
|
|
|
67
67
|
vml = Package::Vml.new
|
|
68
68
|
vml.set_xml_writer("#{dir}/vmlDrawing#{index}.vml")
|
|
69
69
|
vml.assemble_xml_file(
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
70
|
+
sheet.vml_data_id, sheet.vml_shape_id,
|
|
71
|
+
sheet.sorted_comments, sheet.buttons_data
|
|
72
|
+
)
|
|
73
73
|
index += 1
|
|
74
74
|
end
|
|
75
75
|
if sheet.has_header_vml?
|
|
76
76
|
vml = Package::Vml.new
|
|
77
77
|
vml.set_xml_writer("#{dir}/vmlDrawing#{index}.vml")
|
|
78
78
|
vml.assemble_xml_file(
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
79
|
+
sheet.vml_header_id, sheet.vml_header_id * 1024,
|
|
80
|
+
[], [], sheet.header_images_data
|
|
81
|
+
)
|
|
82
82
|
write_vml_drawing_rels_files(package_dir, sheet, index)
|
|
83
83
|
index += 1
|
|
84
84
|
end
|
|
@@ -106,16 +106,12 @@ module Writexlsx
|
|
|
106
106
|
end
|
|
107
107
|
|
|
108
108
|
def write_chartsheet_rels_files(package_dir)
|
|
109
|
-
write_sheet_rels_files_base(
|
|
110
|
-
|
|
109
|
+
write_sheet_rels_files_base(
|
|
110
|
+
chartsheets, "#{package_dir}/xl/chartsheets/_rels", 'sheet'
|
|
111
|
+
)
|
|
111
112
|
end
|
|
112
113
|
|
|
113
114
|
def write_drawing_rels_files(package_dir)
|
|
114
|
-
# write_rels_files_base(
|
|
115
|
-
# self.reject { |sheet| sheet.drawing_links[0].empty? },
|
|
116
|
-
# "#{package_dir}/xl/drawings/_rels",
|
|
117
|
-
|
|
118
|
-
# )
|
|
119
115
|
dir = "#{package_dir}/xl/drawings/_rels"
|
|
120
116
|
|
|
121
117
|
index = 0
|
|
@@ -159,8 +155,9 @@ module Writexlsx
|
|
|
159
155
|
end
|
|
160
156
|
|
|
161
157
|
def write_worksheet_rels_files(package_dir)
|
|
162
|
-
write_sheet_rels_files_base(
|
|
163
|
-
|
|
158
|
+
write_sheet_rels_files_base(
|
|
159
|
+
worksheets, "#{package_dir}/xl/worksheets/_rels", 'sheet'
|
|
160
|
+
)
|
|
164
161
|
end
|
|
165
162
|
|
|
166
163
|
def write_sheet_rels_files_base(sheets, dir, body)
|
|
@@ -235,11 +232,6 @@ module Writexlsx
|
|
|
235
232
|
raise "Worksheet name #{name} cannot start or end with an "
|
|
236
233
|
end
|
|
237
234
|
|
|
238
|
-
# Check that sheetname isn't a reserved word.
|
|
239
|
-
if name =~ /history/i
|
|
240
|
-
raise "Worksheet name cannot be Excel reserved word 'History'"
|
|
241
|
-
end
|
|
242
|
-
|
|
243
235
|
# Check that the worksheet name doesn't already exist since this is a fatal
|
|
244
236
|
# error in Excel 97. The check must also exclude case insensitive matches.
|
|
245
237
|
unless is_sheetname_uniq?(name)
|
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)
|
|
@@ -804,9 +808,9 @@ module Writexlsx
|
|
|
804
808
|
#
|
|
805
809
|
# Write the <c:txPr> element.
|
|
806
810
|
#
|
|
807
|
-
def write_tx_pr(
|
|
811
|
+
def write_tx_pr(font, is_y_axis = nil) # :nodoc:
|
|
808
812
|
rotation = nil
|
|
809
|
-
if font && font[:_rotation]
|
|
813
|
+
if font && font.respond_to?(:[]) && font[:_rotation]
|
|
810
814
|
rotation = font[:_rotation]
|
|
811
815
|
end
|
|
812
816
|
@writer.tag_elements('c:txPr') do
|
|
@@ -903,6 +907,7 @@ module Writexlsx
|
|
|
903
907
|
#
|
|
904
908
|
def get_font_latin_attributes(font)
|
|
905
909
|
return [] unless font
|
|
910
|
+
return [] unless font.respond_to?(:[])
|
|
906
911
|
|
|
907
912
|
attributes = []
|
|
908
913
|
attributes << ['typeface', font[:_name]] if ptrue?(font[:_name])
|
|
@@ -959,6 +964,7 @@ module Writexlsx
|
|
|
959
964
|
#
|
|
960
965
|
def get_font_style_attributes(font)
|
|
961
966
|
return [] unless font
|
|
967
|
+
return [] unless font.respond_to?(:[])
|
|
962
968
|
|
|
963
969
|
attributes = []
|
|
964
970
|
attributes << ['sz', font[:_size]] if ptrue?(font[:_size])
|
data/lib/write_xlsx/version.rb
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
WriteXLSX_VERSION = "1.
|
|
1
|
+
WriteXLSX_VERSION = "1.08.1"
|