write_xlsx 0.72.2 → 0.72.3.beta1

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.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/{README.rdoc → Changes} +3 -94
  3. data/README.md +96 -0
  4. data/lib/write_xlsx/chart.rb +115 -259
  5. data/lib/write_xlsx/chart/axis.rb +4 -4
  6. data/lib/write_xlsx/chart/bar.rb +1 -1
  7. data/lib/write_xlsx/chart/column.rb +1 -1
  8. data/lib/write_xlsx/chart/pie.rb +3 -3
  9. data/lib/write_xlsx/chart/radar.rb +1 -1
  10. data/lib/write_xlsx/chart/scatter.rb +1 -1
  11. data/lib/write_xlsx/chart/series.rb +0 -37
  12. data/lib/write_xlsx/chartsheet.rb +25 -37
  13. data/lib/write_xlsx/col_name.rb +40 -0
  14. data/lib/write_xlsx/drawing.rb +95 -85
  15. data/lib/write_xlsx/format.rb +32 -32
  16. data/lib/write_xlsx/package/app.rb +18 -23
  17. data/lib/write_xlsx/package/button.rb +15 -12
  18. data/lib/write_xlsx/package/comments.rb +33 -30
  19. data/lib/write_xlsx/package/conditional_format.rb +18 -14
  20. data/lib/write_xlsx/package/content_types.rb +22 -17
  21. data/lib/write_xlsx/package/core.rb +19 -24
  22. data/lib/write_xlsx/package/relationships.rb +10 -13
  23. data/lib/write_xlsx/package/shared_strings.rb +8 -16
  24. data/lib/write_xlsx/package/styles.rb +59 -64
  25. data/lib/write_xlsx/package/table.rb +27 -37
  26. data/lib/write_xlsx/package/vml.rb +23 -21
  27. data/lib/write_xlsx/package/xml_writer_simple.rb +3 -6
  28. data/lib/write_xlsx/sheets.rb +4 -4
  29. data/lib/write_xlsx/sparkline.rb +22 -22
  30. data/lib/write_xlsx/utility.rb +61 -33
  31. data/lib/write_xlsx/version.rb +1 -1
  32. data/lib/write_xlsx/workbook.rb +46 -50
  33. data/lib/write_xlsx/worksheet.rb +149 -133
  34. data/lib/write_xlsx/worksheet/cell_data.rb +8 -6
  35. data/lib/write_xlsx/worksheet/data_validation.rb +14 -14
  36. data/lib/write_xlsx/worksheet/hyperlink.rb +97 -65
  37. data/lib/write_xlsx/worksheet/page_setup.rb +23 -22
  38. data/test/chart/test_write_a_latin.rb +3 -3
  39. data/test/regression/test_chart_font01.rb +1 -1
  40. data/test/regression/test_chart_font02.rb +1 -1
  41. data/test/regression/test_chart_font03.rb +1 -1
  42. data/test/regression/test_chart_font04.rb +1 -1
  43. data/test/regression/test_chart_font05.rb +1 -1
  44. data/test/regression/test_chart_font06.rb +1 -1
  45. data/test/test_xml_writer_simple.rb +3 -3
  46. data/test/worksheet/test_write_hyperlink.rb +4 -4
  47. data/test/worksheet/test_write_worksheet_attributes.rb +3 -3
  48. data/write_xlsx.gemspec +2 -1
  49. metadata +9 -8
  50. data/test/package/table/test_write_xml_declaration.rb +0 -20
@@ -325,31 +325,31 @@ def get_align_properties
325
325
 
326
326
  continuous = 'centerContinuous'
327
327
 
328
- align << 'horizontal' << 'left' if @text_h_align == 1
329
- align << 'horizontal' << 'center' if @text_h_align == 2
330
- align << 'horizontal' << 'right' if @text_h_align == 3
331
- align << 'horizontal' << 'fill' if @text_h_align == 4
332
- align << 'horizontal' << 'justify' if @text_h_align == 5
333
- align << 'horizontal' << continuous if @text_h_align == 6
334
- align << 'horizontal' << 'distributed' if @text_h_align == 7
328
+ align << ['horizontal', 'left'] if @text_h_align == 1
329
+ align << ['horizontal', 'center'] if @text_h_align == 2
330
+ align << ['horizontal', 'right'] if @text_h_align == 3
331
+ align << ['horizontal', 'fill'] if @text_h_align == 4
332
+ align << ['horizontal', 'justify'] if @text_h_align == 5
333
+ align << ['horizontal', continuous] if @text_h_align == 6
334
+ align << ['horizontal', 'distributed'] if @text_h_align == 7
335
335
 
336
- align << 'justifyLastLine' << 1 if @just_distrib != 0
336
+ align << ['justifyLastLine', 1] if @just_distrib != 0
337
337
 
338
338
  # Property 'vertical' => 'bottom' is a default. It sets applyAlignment
339
339
  # without an alignment sub-element.
340
- align << 'vertical' << 'top' if @text_v_align == 1
341
- align << 'vertical' << 'center' if @text_v_align == 2
342
- align << 'vertical' << 'justify' if @text_v_align == 4
343
- align << 'vertical' << 'distributed' if @text_v_align == 5
340
+ align << ['vertical', 'top'] if @text_v_align == 1
341
+ align << ['vertical', 'center'] if @text_v_align == 2
342
+ align << ['vertical', 'justify'] if @text_v_align == 4
343
+ align << ['vertical', 'distributed'] if @text_v_align == 5
344
344
 
345
- align << 'indent' << @indent if @indent != 0
346
- align << 'textRotation' << @rotation if @rotation != 0
345
+ align << ['indent', @indent] if @indent != 0
346
+ align << ['textRotation', @rotation] if @rotation != 0
347
347
 
348
- align << 'wrapText' << 1 if @text_wrap != 0
349
- align << 'shrinkToFit' << 1 if @shrink != 0
348
+ align << ['wrapText', 1] if @text_wrap != 0
349
+ align << ['shrinkToFit', 1] if @shrink != 0
350
350
 
351
- align << 'readingOrder' << 1 if @reading_order == 1
352
- align << 'readingOrder' << 2 if @reading_order == 2
351
+ align << ['readingOrder', 1] if @reading_order == 1
352
+ align << ['readingOrder', 2] if @reading_order == 2
353
353
 
354
354
  return changed, align
355
355
  end
@@ -360,8 +360,8 @@ def get_align_properties
360
360
  def get_protection_properties
361
361
  attributes = []
362
362
 
363
- attributes << 'locked' << 0 unless ptrue?(@locked)
364
- attributes << 'hidden' << 1 if ptrue?(@hidden)
363
+ attributes << ['locked', 0] unless ptrue?(@locked)
364
+ attributes << ['hidden', 1] if ptrue?(@hidden)
365
365
 
366
366
  attributes.empty? ? nil : attributes
367
367
  end
@@ -743,7 +743,7 @@ def write_font(writer, worksheet, dxf_format = nil) #:nodoc:
743
743
 
744
744
  write_font_shapes(writer)
745
745
 
746
- writer.empty_tag('sz', ['val', size]) unless dxf_format
746
+ writer.empty_tag('sz', [ ['val', size] ]) unless dxf_format
747
747
 
748
748
  if ptrue?(theme)
749
749
  write_color(writer, 'theme', theme)
@@ -757,7 +757,7 @@ def write_font(writer, worksheet, dxf_format = nil) #:nodoc:
757
757
  end
758
758
 
759
759
  unless ptrue?(dxf_format)
760
- writer.empty_tag('name', ['val', @font])
760
+ writer.empty_tag('name', [ ['val', @font] ])
761
761
  write_font_family_scheme(writer)
762
762
  end
763
763
  end
@@ -766,7 +766,7 @@ def write_font(writer, worksheet, dxf_format = nil) #:nodoc:
766
766
  def write_font_rpr(writer, worksheet) #:nodoc:
767
767
  writer.tag_elements('rPr') do
768
768
  write_font_shapes(writer)
769
- writer.empty_tag('sz', ['val', size])
769
+ writer.empty_tag('sz', [ ['val', size] ])
770
770
 
771
771
  if ptrue?(theme)
772
772
  write_color(writer, 'theme', theme)
@@ -777,7 +777,7 @@ def write_font_rpr(writer, worksheet) #:nodoc:
777
777
  write_color(writer, 'theme', 1)
778
778
  end
779
779
 
780
- writer.empty_tag('rFont', ['val', @font])
780
+ writer.empty_tag('rFont', [ ['val', @font] ])
781
781
  write_font_family_scheme(writer)
782
782
  end
783
783
  end
@@ -799,10 +799,10 @@ def write_font_shapes(writer)
799
799
  end
800
800
 
801
801
  def write_font_family_scheme(writer)
802
- writer.empty_tag('family', ['val', @font_family])
802
+ writer.empty_tag('family', [ ['val', @font_family] ])
803
803
 
804
804
  if @font == 'Calibri' && !ptrue?(@hyperlink)
805
- writer.empty_tag('scheme', ['val', @font_scheme])
805
+ writer.empty_tag('scheme', [ ['val', @font_scheme] ])
806
806
  end
807
807
  end
808
808
 
@@ -821,11 +821,11 @@ def write_underline_attributes(underline)
821
821
  # Handle the underline variants.
822
822
  case underline
823
823
  when 2
824
- [val, 'double']
824
+ [ [val, 'double'] ]
825
825
  when 33
826
- [val, 'singleAccounting']
826
+ [ [val, 'singleAccounting'] ]
827
827
  when 34
828
- [val, 'doubleAccounting']
828
+ [ [val, 'doubleAccounting'] ]
829
829
  else
830
830
  []
831
831
  end
@@ -835,21 +835,21 @@ def write_underline_attributes(underline)
835
835
  # Write the <vertAlign> font sub-element.
836
836
  #
837
837
  def write_vert_align(writer, val) #:nodoc:
838
- writer.empty_tag('vertAlign', ['val', val])
838
+ writer.empty_tag('vertAlign', [ ['val', val] ])
839
839
  end
840
840
 
841
841
  #
842
842
  # Write the <condense> element.
843
843
  #
844
844
  def write_condense(writer)
845
- writer.empty_tag('condense', ['val', 0])
845
+ writer.empty_tag('condense', [ ['val', 0] ])
846
846
  end
847
847
 
848
848
  #
849
849
  # Write the <extend> element.
850
850
  #
851
851
  def write_extend(writer)
852
- writer.empty_tag('extend', ['val', 0])
852
+ writer.empty_tag('extend', [ ['val', 0] ])
853
853
  end
854
854
  end
855
855
  end
@@ -20,22 +20,21 @@ def set_xml_writer(filename)
20
20
  end
21
21
 
22
22
  def assemble_xml_file
23
- write_xml_declaration
24
- write_properties do
25
- write_application
26
- write_doc_security
27
- write_scale_crop
28
- write_heading_pairs
29
- write_titles_of_parts
30
- write_manager
31
- write_company
32
- write_links_up_to_date
33
- write_shared_doc
34
- write_hyperlinks_changed
35
- write_app_version
23
+ write_xml_declaration do
24
+ write_properties do
25
+ write_application
26
+ write_doc_security
27
+ write_scale_crop
28
+ write_heading_pairs
29
+ write_titles_of_parts
30
+ write_manager
31
+ write_company
32
+ write_links_up_to_date
33
+ write_shared_doc
34
+ write_hyperlinks_changed
35
+ write_app_version
36
+ end
36
37
  end
37
- @writer.crlf
38
- @writer.close
39
38
  end
40
39
 
41
40
  def add_part_name(part_name)
@@ -57,10 +56,6 @@ def set_properties(properties)
57
56
 
58
57
  private
59
58
 
60
- def write_xml_declaration
61
- @writer.xml_decl
62
- end
63
-
64
59
  #
65
60
  # Write the <Properties> element.
66
61
  #
@@ -69,8 +64,8 @@ def write_properties
69
64
 
70
65
  schema = 'http://schemas.openxmlformats.org/officeDocument/2006/'
71
66
  attributes = [
72
- 'xmlns', "#{schema}extended-properties",
73
- 'xmlns:vt', "#{schema}docPropsVTypes"
67
+ ['xmlns', "#{schema}extended-properties"],
68
+ ['xmlns:vt', "#{schema}docPropsVTypes"]
74
69
  ]
75
70
 
76
71
  @writer.tag_elements('Properties', attributes) { yield }
@@ -127,8 +122,8 @@ def write_titles_of_parts
127
122
  #
128
123
  def write_vt_vector(base_type, data)
129
124
  attributes = [
130
- 'size', data.size,
131
- 'baseType', base_type
125
+ ['size', data.size],
126
+ ['baseType', base_type]
132
127
  ]
133
128
 
134
129
  @writer.tag_elements('vt:vector', attributes) do
@@ -10,11 +10,12 @@ class Button
10
10
  attr_accessor :font, :macro, :vertices
11
11
 
12
12
  def v_shape_attributes(id, z_index)
13
- v_shape_attributes_base(id, z_index) <<
14
- 'o:button' << 't' <<
15
- 'fillcolor' << color <<
16
- 'strokecolor' << 'windowText [64]' <<
17
- 'o:insetmode' << 'auto'
13
+ attributes = v_shape_attributes_base(id, z_index)
14
+ attributes << ['o:button', 't']
15
+ attributes << ['fillcolor', color]
16
+ attributes << ['strokecolor', 'windowText [64]']
17
+ attributes << ['o:insetmode', 'auto']
18
+ attributes
18
19
  end
19
20
 
20
21
  def type
@@ -49,8 +50,8 @@ def write_shape(writer, id, z_index)
49
50
  # attributes for <v:fill> element.
50
51
  def fill_attributes
51
52
  [
52
- 'color2', 'buttonFace [67]',
53
- 'o:detectmouseclick', 't'
53
+ ['color2', 'buttonFace [67]'],
54
+ ['o:detectmouseclick', 't']
54
55
  ]
55
56
  end
56
57
 
@@ -59,8 +60,8 @@ def fill_attributes
59
60
  #
60
61
  def write_rotation_lock
61
62
  attributes = [
62
- 'v:ext', 'edit',
63
- 'rotation', 't'
63
+ ['v:ext', 'edit'],
64
+ ['rotation', 't']
64
65
  ]
65
66
  @writer.empty_tag('o:lock', attributes)
66
67
  end
@@ -69,7 +70,10 @@ def write_rotation_lock
69
70
  # Write the <v:textbox> element.
70
71
  #
71
72
  def write_textbox
72
- attributes = ['style', 'mso-direction-alt:auto', 'o:singleclick', 'f']
73
+ attributes = [
74
+ ['style', 'mso-direction-alt:auto'],
75
+ ['o:singleclick', 'f']
76
+ ]
73
77
 
74
78
  @writer.tag_elements('v:textbox', attributes) do
75
79
  # Write the div element.
@@ -81,7 +85,7 @@ def write_textbox
81
85
  # Write the <x:ClientData> element.
82
86
  #
83
87
  def write_client_data
84
- attributes = ['ObjectType', 'Button']
88
+ attributes = [ ['ObjectType', 'Button'] ]
85
89
 
86
90
  @writer.tag_elements('x:ClientData', attributes) do
87
91
  # Write the x:Anchor element.
@@ -129,4 +133,3 @@ def write_text_valign
129
133
  end
130
134
  end
131
135
  end
132
-
@@ -118,9 +118,10 @@ def default_y_offset(row)
118
118
  end
119
119
 
120
120
  def v_shape_attributes(id, z_index)
121
- v_shape_attributes_base(id, z_index) <<
122
- 'fillcolor' << color <<
123
- 'o:insetmode' << 'auto'
121
+ attr = v_shape_attributes_base(id, z_index)
122
+ attr << ['fillcolor', color]
123
+ attr << ['o:insetmode', 'auto']
124
+ attr
124
125
  end
125
126
 
126
127
  def type
@@ -158,7 +159,9 @@ def visibility
158
159
  # Write the <v:fill> element.
159
160
  #
160
161
  def fill_attributes
161
- ['color2', '#ffffe1']
162
+ [
163
+ ['color2', '#ffffe1']
164
+ ]
162
165
  end
163
166
 
164
167
  #
@@ -166,9 +169,9 @@ def fill_attributes
166
169
  #
167
170
  def write_shadow
168
171
  attributes = [
169
- 'on', 't',
170
- 'color', 'black',
171
- 'obscured', 't'
172
+ ['on', 't'],
173
+ ['color', 'black'],
174
+ ['obscured', 't']
172
175
  ]
173
176
 
174
177
  @writer.empty_tag('v:shadow', attributes)
@@ -178,7 +181,9 @@ def write_shadow
178
181
  # Write the <v:textbox> element.
179
182
  #
180
183
  def write_textbox
181
- attributes = ['style', 'mso-direction-alt:auto']
184
+ attributes = [
185
+ ['style', 'mso-direction-alt:auto']
186
+ ]
182
187
 
183
188
  @writer.tag_elements('v:textbox', attributes) do
184
189
  # Write the div element.
@@ -190,7 +195,9 @@ def write_textbox
190
195
  # Write the <x:ClientData> element.
191
196
  #
192
197
  def write_client_data
193
- attributes = ['ObjectType', 'Note']
198
+ attributes = [
199
+ ['ObjectType', 'Note']
200
+ ]
194
201
 
195
202
  @writer.tag_elements('x:ClientData', attributes) do
196
203
  @writer.empty_tag('x:MoveWithCells')
@@ -250,14 +257,12 @@ def set_xml_writer(filename)
250
257
  end
251
258
 
252
259
  def assemble_xml_file
253
- write_xml_declaration
254
- write_comments
255
- write_authors(sorted_comments)
256
- write_comment_list(sorted_comments)
257
-
258
- @writer.end_tag('comments')
259
- @writer.crlf
260
- @writer.close
260
+ write_xml_declaration do
261
+ write_comments do
262
+ write_authors(sorted_comments)
263
+ write_comment_list(sorted_comments)
264
+ end
265
+ end
261
266
  end
262
267
 
263
268
  def sorted_comments
@@ -289,19 +294,17 @@ def comments_visible?
289
294
  @worksheet.comments_visible?
290
295
  end
291
296
 
292
- def write_xml_declaration
293
- @writer.xml_decl
294
- end
295
-
296
297
  #
297
298
  # Write the <comments> element.
298
299
  #
299
300
  def write_comments
300
301
  xmlns = 'http://schemas.openxmlformats.org/spreadsheetml/2006/main'
301
302
 
302
- attributes = [ 'xmlns', xmlns]
303
+ attributes = [
304
+ ['xmlns', xmlns]
305
+ ]
303
306
 
304
- @writer.start_tag('comments', attributes)
307
+ @writer.tag_elements('comments', attributes) { yield }
305
308
  end
306
309
 
307
310
  #
@@ -346,10 +349,10 @@ def write_comment_list(comment_data)
346
349
  #
347
350
  def write_comment(comment)
348
351
  ref = xl_rowcol_to_cell( comment.row, comment.col )
349
- attributes = ['ref', ref]
352
+ attributes = [ ['ref', ref] ]
350
353
 
351
354
  author_id = (@author_ids[comment.author] if comment.author) || 0
352
- attributes << 'authorId' << author_id
355
+ attributes << ['authorId', author_id]
353
356
 
354
357
  @writer.tag_elements('comment', attributes) do
355
358
  write_text(comment.string)
@@ -384,7 +387,7 @@ def write_text_r(text)
384
387
  def write_text_t(text)
385
388
  attributes = []
386
389
 
387
- (attributes << 'xml:space' << 'preserve') if text =~ /^\s/ || text =~ /\s$/
390
+ attributes << ['xml:space', 'preserve'] if text =~ /^\s/ || text =~ /\s$/
388
391
 
389
392
  @writer.data_element('t', text, attributes)
390
393
  end
@@ -411,7 +414,7 @@ def write_r_pr
411
414
  def write_sz
412
415
  val = 8
413
416
 
414
- attributes = ['val', val]
417
+ attributes = [ ['val', val] ]
415
418
 
416
419
  @writer.empty_tag('sz', attributes)
417
420
  end
@@ -420,7 +423,7 @@ def write_sz
420
423
  # Write the <color> element.
421
424
  #
422
425
  def write_color
423
- @writer.empty_tag('color', ['indexed', 81])
426
+ @writer.empty_tag('color', [ ['indexed', 81] ])
424
427
  end
425
428
 
426
429
  #
@@ -429,7 +432,7 @@ def write_color
429
432
  def write_r_font
430
433
  val = 'Tahoma'
431
434
 
432
- attributes = ['val', val]
435
+ attributes = [ ['val', val] ]
433
436
 
434
437
  @writer.empty_tag('rFont', attributes)
435
438
  end
@@ -440,7 +443,7 @@ def write_r_font
440
443
  def write_family
441
444
  val = 2
442
445
 
443
- attributes = ['val', val]
446
+ attributes = [ ['val', val] ]
444
447
 
445
448
  @writer.empty_tag('family', attributes)
446
449
  end
@@ -60,13 +60,17 @@ def write_formula_tag(data) #:nodoc:
60
60
  # Write the <cfvo> element.
61
61
  #
62
62
  def write_cfvo(type, val)
63
- @writer.empty_tag('cfvo', ['type', type, 'val', val])
63
+ @writer.empty_tag('cfvo', [
64
+ ['type', type],
65
+ ['val', val]
66
+ ])
64
67
  end
65
68
 
66
69
  def attributes
67
- attr = ['type' , type]
68
- attr << 'dxfId' << format if format
69
- attr << 'priority' << priority
70
+ attr = []
71
+ attr << ['type' , type]
72
+ attr << ['dxfId', format] if format
73
+ attr << ['priority', priority]
70
74
  attr
71
75
  end
72
76
 
@@ -476,7 +480,7 @@ def date_1904?
476
480
 
477
481
  class CellIsFormat < ConditionalFormat
478
482
  def attributes
479
- super << 'operator' << criteria
483
+ super << ['operator', criteria]
480
484
  end
481
485
 
482
486
  def write_cf_rule
@@ -494,10 +498,10 @@ def write_cf_rule
494
498
  class AboveAverageFormat < ConditionalFormat
495
499
  def attributes
496
500
  attr = super
497
- attr << 'aboveAverage' << 0 if criteria =~ /below/
498
- attr << 'equalAverage' << 1 if criteria =~ /equal/
501
+ attr << ['aboveAverage', 0] if criteria =~ /below/
502
+ attr << ['equalAverage', 1] if criteria =~ /equal/
499
503
  if criteria =~ /([123]) std dev/
500
- attr << 'stdDev' << $~[1]
504
+ attr << ['stdDev', $~[1]]
501
505
  end
502
506
  attr
503
507
  end
@@ -506,9 +510,9 @@ def attributes
506
510
  class Top10Format < ConditionalFormat
507
511
  def attributes
508
512
  attr = super
509
- attr << 'percent' << 1 if criteria == '%'
510
- attr << 'bottom' << 1 if direction
511
- attr << 'rank' << (value || 10)
513
+ attr << ['percent', 1] if criteria == '%'
514
+ attr << ['bottom', 1] if direction
515
+ attr << ['rank', (value || 10)]
512
516
  attr
513
517
  end
514
518
  end
@@ -516,8 +520,8 @@ def attributes
516
520
  class TextOrWithFormat < ConditionalFormat
517
521
  def attributes
518
522
  attr = super
519
- attr << 'operator' << criteria
520
- attr << 'text' << value
523
+ attr << ['operator', criteria]
524
+ attr << ['text', value]
521
525
  attr
522
526
  end
523
527
 
@@ -528,7 +532,7 @@ def write_cf_rule
528
532
 
529
533
  class TimePeriodFormat < ConditionalFormat
530
534
  def attributes
531
- super << 'timePeriod' << criteria
535
+ super << ['timePeriod', criteria]
532
536
  end
533
537
 
534
538
  def write_cf_rule