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
@@ -31,13 +31,12 @@ def set_xml_writer(filename)
31
31
  end
32
32
 
33
33
  def assemble_xml_file
34
- write_xml_declaration
35
- write_types do
36
- write_defaults
37
- write_overrides
34
+ write_xml_declaration do
35
+ write_types do
36
+ write_defaults
37
+ write_overrides
38
+ end
38
39
  end
39
- @writer.crlf
40
- @writer.close
41
40
  end
42
41
  #
43
42
  # Add elements to the ContentTypes defaults.
@@ -146,10 +145,6 @@ def add_vba_project
146
145
 
147
146
  private
148
147
 
149
- def write_xml_declaration
150
- @writer.xml_decl
151
- end
152
-
153
148
  def change_the_workbook_xml_content_type_from_xlsx_to_xlsm
154
149
  @overrides.collect! do |arr|
155
150
  if arr[0] == '/xl/workbook.xml'
@@ -164,7 +159,11 @@ def change_the_workbook_xml_content_type_from_xlsx_to_xlsm
164
159
  #
165
160
  def write_defaults
166
161
  @defaults.each do |a|
167
- @writer.empty_tag('Default', ['Extension', a[0], 'ContentType', a[1]])
162
+ @writer.empty_tag('Default',
163
+ [
164
+ ['Extension', a[0]],
165
+ ['ContentType', a[1]]
166
+ ])
168
167
  end
169
168
  end
170
169
 
@@ -173,7 +172,11 @@ def write_defaults
173
172
  #
174
173
  def write_overrides
175
174
  @overrides.each do |a|
176
- @writer.empty_tag('Override', ['PartName', a[0], 'ContentType', a[1]])
175
+ @writer.empty_tag('Override',
176
+ [
177
+ ['PartName', a[0]],
178
+ ['ContentType', a[1]]
179
+ ])
177
180
  end
178
181
  end
179
182
 
@@ -182,7 +185,9 @@ def write_overrides
182
185
  #
183
186
  def write_types
184
187
  xmlns = 'http://schemas.openxmlformats.org/package/2006/content-types'
185
- attributes = ['xmlns', xmlns]
188
+ attributes = [
189
+ ['xmlns', xmlns]
190
+ ]
186
191
 
187
192
  @writer.tag_elements('Types', attributes) { yield }
188
193
  end
@@ -192,8 +197,8 @@ def write_types
192
197
  #
193
198
  def write_default(extension, content_type)
194
199
  attributes = [
195
- 'Extension', extension,
196
- 'ContentType', content_type
200
+ ['Extension', extension],
201
+ ['ContentType', content_type]
197
202
  ]
198
203
 
199
204
  @writer.empty_tag('Default', attributes)
@@ -204,8 +209,8 @@ def write_default(extension, content_type)
204
209
  #
205
210
  def write_override(part_name, content_type)
206
211
  attributes = [
207
- 'PartName', part_name,
208
- 'ContentType', content_type
212
+ ['PartName', part_name],
213
+ ['ContentType', content_type]
209
214
  ]
210
215
 
211
216
  @writer.empty_tag('Override', attributes)
@@ -22,21 +22,20 @@ def set_xml_writer(filename)
22
22
  end
23
23
 
24
24
  def assemble_xml_file
25
- write_xml_declaration
26
- write_cp_core_properties do
27
- write_dc_title
28
- write_dc_subject
29
- write_dc_creator
30
- write_cp_keywords
31
- write_dc_description
32
- write_cp_last_modified_by
33
- write_dcterms_created
34
- write_dcterms_modified
35
- write_cp_category
36
- write_cp_content_status
25
+ write_xml_declaration do
26
+ write_cp_core_properties do
27
+ write_dc_title
28
+ write_dc_subject
29
+ write_dc_creator
30
+ write_cp_keywords
31
+ write_dc_description
32
+ write_cp_last_modified_by
33
+ write_dcterms_created
34
+ write_dcterms_modified
35
+ write_cp_category
36
+ write_cp_content_status
37
+ end
37
38
  end
38
- @writer.crlf
39
- @writer.close
40
39
  end
41
40
 
42
41
  def set_properties(properties)
@@ -54,10 +53,6 @@ def localtime_to_iso8601_date(local_time = nil)
54
53
  local_time.strftime('%Y-%m-%dT%H:%M:%SZ')
55
54
  end
56
55
 
57
- def write_xml_declaration
58
- @writer.xml_decl
59
- end
60
-
61
56
  #
62
57
  # Write the <cp:coreProperties> element.
63
58
  #
@@ -69,11 +64,11 @@ def write_cp_core_properties
69
64
  xmlns_xsi = 'http://www.w3.org/2001/XMLSchema-instance'
70
65
 
71
66
  attributes = [
72
- 'xmlns:cp', xmlns_cp,
73
- 'xmlns:dc', xmlns_dc,
74
- 'xmlns:dcterms', xmlns_dcterms,
75
- 'xmlns:dcmitype', xmlns_dcmitype,
76
- 'xmlns:xsi', xmlns_xsi
67
+ ['xmlns:cp', xmlns_cp],
68
+ ['xmlns:dc', xmlns_dc],
69
+ ['xmlns:dcterms', xmlns_dcterms],
70
+ ['xmlns:dcmitype', xmlns_dcmitype],
71
+ ['xmlns:xsi', xmlns_xsi]
77
72
  ]
78
73
 
79
74
  @writer.tag_elements('cp:coreProperties', attributes) { yield }
@@ -108,7 +103,7 @@ def write_dcterms_modified
108
103
  end
109
104
 
110
105
  def write_dcterms(tag)
111
- @writer.data_element(tag, dcterms_date, ['xsi:type', 'dcterms:W3CDTF'])
106
+ @writer.data_element(tag, dcterms_date, [ ['xsi:type', 'dcterms:W3CDTF'] ])
112
107
  end
113
108
 
114
109
  def dcterms_date
@@ -23,10 +23,9 @@ def set_xml_writer(filename)
23
23
  end
24
24
 
25
25
  def assemble_xml_file
26
- write_xml_declaration
27
- write_relationships
28
- @writer.crlf
29
- @writer.close
26
+ write_xml_declaration do
27
+ write_relationships
28
+ end
30
29
  end
31
30
 
32
31
  #
@@ -71,15 +70,13 @@ def add_worksheet_relationship(type, target, target_mode = nil)
71
70
 
72
71
  private
73
72
 
74
- def write_xml_declaration
75
- @writer.xml_decl
76
- end
77
-
78
73
  #
79
74
  # Write the <Relationships> element.
80
75
  #
81
76
  def write_relationships
82
- attributes = ['xmlns', Package_schema]
77
+ attributes = [
78
+ ['xmlns', Package_schema]
79
+ ]
83
80
 
84
81
  @writer.tag_elements('Relationships', attributes) do
85
82
  @rels.each { |rel| write_relationship(*rel) }
@@ -91,13 +88,13 @@ def write_relationships
91
88
  #
92
89
  def write_relationship(type, target, target_mode = nil)
93
90
  attributes = [
94
- 'Id', "rId#{@id}",
95
- 'Type', type,
96
- 'Target', target
91
+ ['Id', "rId#{@id}"],
92
+ ['Type', type],
93
+ ['Target', target]
97
94
  ]
98
95
  @id += 1
99
96
 
100
- attributes << 'TargetMode' << target_mode if target_mode
97
+ attributes << ['TargetMode', target_mode] if target_mode
101
98
 
102
99
  @writer.empty_tag('Relationship', attributes)
103
100
  end
@@ -42,22 +42,14 @@ def set_xml_writer(filename)
42
42
  end
43
43
 
44
44
  def assemble_xml_file
45
- write_xml_declaration
46
-
47
- # Write the sst table.
48
- write_sst { write_sst_strings }
49
-
50
- # Close the sst tag.
51
- @writer.crlf
52
- @writer.close
45
+ write_xml_declaration do
46
+ # Write the sst table.
47
+ write_sst { write_sst_strings }
48
+ end
53
49
  end
54
50
 
55
51
  private
56
52
 
57
- def write_xml_declaration
58
- @writer.xml_decl
59
- end
60
-
61
53
  #
62
54
  # Write the <sst> element.
63
55
  #
@@ -66,9 +58,9 @@ def write_sst
66
58
 
67
59
  attributes =
68
60
  [
69
- 'xmlns', schema + '/spreadsheetml/2006/main',
70
- 'count', total_count,
71
- 'uniqueCount', unique_count
61
+ ['xmlns', schema + '/spreadsheetml/2006/main'],
62
+ ['count', total_count],
63
+ ['uniqueCount', unique_count]
72
64
  ]
73
65
 
74
66
  @writer.tag_elements('sst', attributes) { yield }
@@ -108,7 +100,7 @@ def write_si(string)
108
100
  end
109
101
 
110
102
  # Add attribute to preserve leading or trailing whitespace.
111
- attributes << 'xml:space' << 'preserve' if string =~ /\A\s|\s\Z/
103
+ attributes << ['xml:space', 'preserve'] if string =~ /\A\s|\s\Z/
112
104
 
113
105
  # Write any rich strings without further tags.
114
106
  if string =~ %r{^<r>} && string =~ %r{</r>$}
@@ -25,21 +25,20 @@ def set_xml_writer(filename)
25
25
  end
26
26
 
27
27
  def assemble_xml_file
28
- write_xml_declaration
29
- write_style_sheet do
30
- write_num_fmts
31
- write_fonts
32
- write_fills
33
- write_borders
34
- write_cell_style_xfs
35
- write_cell_xfs
36
- write_cell_styles
37
- write_dxfs
38
- write_table_styles
39
- write_colors
28
+ write_xml_declaration do
29
+ write_style_sheet do
30
+ write_num_fmts
31
+ write_fonts
32
+ write_fills
33
+ write_borders
34
+ write_cell_style_xfs
35
+ write_cell_xfs
36
+ write_cell_styles
37
+ write_dxfs
38
+ write_table_styles
39
+ write_colors
40
+ end
40
41
  end
41
- @writer.crlf
42
- @writer.close
43
42
  end
44
43
 
45
44
  #
@@ -81,7 +80,7 @@ def get_palette_color(index)
81
80
  def write_style_sheet
82
81
  xmlns = 'http://schemas.openxmlformats.org/spreadsheetml/2006/main'
83
82
 
84
- attributes = ['xmlns', xmlns]
83
+ attributes = [ ['xmlns', xmlns] ]
85
84
 
86
85
  @writer.tag_elements('styleSheet', attributes) { yield }
87
86
  end
@@ -94,7 +93,7 @@ def write_num_fmts
94
93
 
95
94
  return if count == 0
96
95
 
97
- attributes = ['count', count]
96
+ attributes = [ ['count', count] ]
98
97
 
99
98
  @writer.tag_elements('numFmts', attributes) do
100
99
  # Write the numFmts elements.
@@ -159,8 +158,8 @@ def write_num_fmt(num_fmt_id, format_code)
159
158
  end
160
159
 
161
160
  attributes = [
162
- 'numFmtId', num_fmt_id,
163
- 'formatCode', format_code
161
+ ['numFmtId', num_fmt_id],
162
+ ['formatCode', format_code]
164
163
  ]
165
164
 
166
165
  @writer.empty_tag('numFmt', attributes)
@@ -181,7 +180,7 @@ def write_fonts
181
180
  # Write the <color> element.
182
181
  #
183
182
  def write_color(name, value)
184
- attributes = [name, value]
183
+ attributes = [ [name, value] ]
185
184
 
186
185
  @writer.empty_tag('color', attributes)
187
186
  end
@@ -192,7 +191,7 @@ def write_color(name, value)
192
191
  def write_fills
193
192
  count = @fill_count
194
193
 
195
- attributes = ['count', count]
194
+ attributes = [ ['count', count] ]
196
195
 
197
196
  @writer.tag_elements('fills', attributes) do
198
197
  # Write the default fill element.
@@ -211,7 +210,7 @@ def write_fills
211
210
  #
212
211
  def write_default_fill(pattern_type)
213
212
  @writer.tag_elements('fill') do
214
- @writer.empty_tag('patternFill', ['patternType', pattern_type])
213
+ @writer.empty_tag('patternFill', [ ['patternType', pattern_type] ])
215
214
  end
216
215
  end
217
216
 
@@ -257,20 +256,20 @@ def write_fill(format, dxf_format = nil)
257
256
  if dxf_format && format.pattern <= 1
258
257
  attributes = []
259
258
  else
260
- attributes = ['patternType', patterns[format.pattern]]
259
+ attributes = [ ['patternType', patterns[format.pattern]] ]
261
260
  end
262
261
 
263
262
  @writer.tag_elements('patternFill', attributes) do
264
263
  if fg_color && fg_color != 0
265
264
  fg_color = get_palette_color(fg_color)
266
- @writer.empty_tag('fgColor', ['rgb', fg_color])
265
+ @writer.empty_tag('fgColor', [ ['rgb', fg_color] ])
267
266
  end
268
267
 
269
268
  if bg_color && bg_color != 0
270
269
  bg_color = get_palette_color(bg_color)
271
- @writer.empty_tag('bgColor', ['rgb', bg_color])
270
+ @writer.empty_tag('bgColor', [ ['rgb', bg_color] ])
272
271
  else
273
- @writer.empty_tag('bgColor', ['indexed', 64]) if !dxf_format
272
+ @writer.empty_tag('bgColor', [ ['indexed', 64] ]) if !dxf_format
274
273
  end
275
274
  end
276
275
  end
@@ -288,7 +287,7 @@ def write_borders
288
287
  end
289
288
 
290
289
  def write_format_elements(elements, count)
291
- attributes = ['count', count]
290
+ attributes = [ [ 'count', count] ]
292
291
 
293
292
  @writer.tag_elements(elements, attributes) do
294
293
  # Write the border elements for format objects that have them.
@@ -304,12 +303,12 @@ def write_border(format, dxf_format = nil)
304
303
 
305
304
  # Diagonal borders add attributes to the <border> element.
306
305
  if format.diag_type == 1
307
- attributes << 'diagonalUp' << 1
306
+ attributes << ['diagonalUp', 1]
308
307
  elsif format.diag_type == 2
309
- attributes << 'diagonalDown' << 1
308
+ attributes << ['diagonalDown', 1]
310
309
  elsif format.diag_type == 3
311
- attributes << 'diagonalUp' << 1
312
- attributes << 'diagonalDown' << 1
310
+ attributes << ['diagonalUp', 1]
311
+ attributes << ['diagonalDown', 1]
313
312
  end
314
313
 
315
314
  # Ensure that a default diag border is set if the diag type is set.
@@ -361,14 +360,14 @@ def write_sub_border(type, style = 0, color = nil)
361
360
  slantDashDot
362
361
  )
363
362
 
364
- attributes = [:style, border_styles[style]]
363
+ attributes = [ [:style, border_styles[style]] ]
365
364
 
366
365
  @writer.tag_elements(type, attributes) do
367
366
  if color != 0
368
367
  color = get_palette_color(color)
369
- @writer.empty_tag('color', ['rgb', color])
368
+ @writer.empty_tag('color', [ ['rgb', color] ])
370
369
  else
371
- @writer.empty_tag('color', ['auto', 1])
370
+ @writer.empty_tag('color', [ ['auto', 1] ])
372
371
  end
373
372
  end
374
373
  end
@@ -377,7 +376,7 @@ def write_sub_border(type, style = 0, color = nil)
377
376
  # Write the <cellStyleXfs> element.
378
377
  #
379
378
  def write_cell_style_xfs
380
- attributes = ['count', 1]
379
+ attributes = [ ['count', 1] ]
381
380
 
382
381
  @writer.tag_elements('cellStyleXfs', attributes) do
383
382
  # Write the style_xf element.
@@ -397,7 +396,7 @@ def write_cell_xfs
397
396
 
398
397
  formats.pop if last_format && last_format.font_only != 0
399
398
 
400
- attributes = ['count', formats.size]
399
+ attributes = [ ['count', formats.size] ]
401
400
 
402
401
  @writer.tag_elements('cellXfs', attributes) do
403
402
  # Write the xf elements.
@@ -415,10 +414,10 @@ def write_style_xf
415
414
  border_id = 0
416
415
 
417
416
  attributes = [
418
- 'numFmtId', num_fmt_id,
419
- 'fontId', font_id,
420
- 'fillId', fill_id,
421
- 'borderId', border_id
417
+ ['numFmtId', num_fmt_id],
418
+ ['fontId', font_id],
419
+ ['fillId', fill_id],
420
+ ['borderId', border_id]
422
421
  ]
423
422
 
424
423
  @writer.empty_tag('xf', attributes)
@@ -434,23 +433,23 @@ def write_xf(format)
434
433
  has_protect = false
435
434
 
436
435
  attributes = [
437
- 'numFmtId', format.num_format_index,
438
- 'fontId' , format.font_index,
439
- 'fillId' , format.fill_index,
440
- 'borderId', format.border_index,
441
- 'xfId' , 0
436
+ ['numFmtId', format.num_format_index],
437
+ ['fontId' , format.font_index],
438
+ ['fillId' , format.fill_index],
439
+ ['borderId', format.border_index],
440
+ ['xfId' , 0]
442
441
  ]
443
442
 
444
- attributes << 'applyNumberFormat' << 1 if format.num_format_index > 0
443
+ attributes << ['applyNumberFormat', 1] if format.num_format_index > 0
445
444
 
446
445
  # Add applyFont attribute if XF format uses a font element.
447
- attributes << 'applyFont' << 1 if format.font_index > 0
446
+ attributes << ['applyFont', 1] if format.font_index > 0
448
447
 
449
448
  # Add applyFill attribute if XF format uses a fill element.
450
- attributes << 'applyFill' << 1 if format.fill_index > 0
449
+ attributes << ['applyFill', 1] if format.fill_index > 0
451
450
 
452
451
  # Add applyBorder attribute if XF format uses a border element.
453
- attributes << 'applyBorder' << 1 if format.border_index > 0
452
+ attributes << ['applyBorder', 1] if format.border_index > 0
454
453
 
455
454
  # Check if XF format has alignment properties set.
456
455
  apply_align, align = format.get_align_properties
@@ -459,13 +458,13 @@ def write_xf(format)
459
458
  has_align = true if apply_align && !align.empty?
460
459
 
461
460
  # We can also have applyAlignment without a sub-element.
462
- attributes << 'applyAlignment' << 1 if apply_align
461
+ attributes << ['applyAlignment', 1] if apply_align
463
462
 
464
463
  # Check for cell protection properties.
465
464
  protection = format.get_protection_properties
466
465
 
467
466
  if protection
468
- attributes << 'applyProtection' << 1
467
+ attributes << ['applyProtection', 1]
469
468
  has_protect = true
470
469
  end
471
470
 
@@ -484,7 +483,7 @@ def write_xf(format)
484
483
  # Write the <cellStyles> element.
485
484
  #
486
485
  def write_cell_styles
487
- attributes = ['count', 1]
486
+ attributes = [ ['count', 1] ]
488
487
 
489
488
  @writer.tag_elements('cellStyles', attributes) do
490
489
  # Write the cellStyle element.
@@ -501,9 +500,9 @@ def write_cell_style
501
500
  builtin_id = 0
502
501
 
503
502
  attributes = [
504
- 'name', name,
505
- 'xfId', xf_id,
506
- 'builtinId', builtin_id
503
+ ['name', name],
504
+ ['xfId', xf_id],
505
+ ['builtinId', builtin_id]
507
506
  ]
508
507
 
509
508
  @writer.empty_tag('cellStyle', attributes)
@@ -517,7 +516,7 @@ def write_dxfs
517
516
 
518
517
  count = formats.size
519
518
 
520
- attributes = ['count', count]
519
+ attributes = [ ['count', count] ]
521
520
 
522
521
  if !formats.empty?
523
522
  @writer.tag_elements('dxfs', attributes) do
@@ -549,9 +548,9 @@ def write_table_styles
549
548
  default_pivot_style = 'PivotStyleLight16'
550
549
 
551
550
  attributes = [
552
- 'count', count,
553
- 'defaultTableStyle', default_table_style,
554
- 'defaultPivotStyle', default_pivot_style
551
+ ['count', count],
552
+ ['defaultTableStyle', default_table_style],
553
+ ['defaultPivotStyle', default_pivot_style]
555
554
  ]
556
555
 
557
556
  @writer.empty_tag('tableStyles', attributes)
@@ -588,17 +587,13 @@ def write_mru_colors(*args)
588
587
  end
589
588
  end
590
589
 
591
- def write_xml_declaration
592
- @writer.xml_decl
593
- end
594
-
595
590
  #
596
591
  # Write the <condense> element.
597
592
  #
598
593
  def write_condense
599
594
  val = 0
600
595
 
601
- attributes = ['val', val]
596
+ attributes = [ ['val', val] ]
602
597
 
603
598
  @writer.empty_tag('condense', attributes)
604
599
  end
@@ -609,7 +604,7 @@ def write_condense
609
604
  def write_extend
610
605
  val = 0
611
606
 
612
- attributes = ['val', val]
607
+ attributes = [ ['val', val] ]
613
608
 
614
609
  @writer.empty_tag('extend', attributes)
615
610
  end