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
@@ -57,17 +57,14 @@ def set_xml_writer(filename)
57
57
  # Assemble and writes the XML file.
58
58
  #
59
59
  def assemble_xml_file
60
- write_xml_declaration
61
- # Write the table element.
62
- @writer.tag_elements('table', write_table_attributes) do
63
- write_auto_filter
64
- write_table_columns
65
- write_table_style_info
60
+ write_xml_declaration do
61
+ # Write the table element.
62
+ @writer.tag_elements('table', write_table_attributes) do
63
+ write_auto_filter
64
+ write_table_columns
65
+ write_table_style_info
66
+ end
66
67
  end
67
-
68
- # Close the XML writer object and filehandle.
69
- @writer.crlf
70
- @writer.close
71
68
  end
72
69
 
73
70
  def add_the_table_columns
@@ -284,33 +281,26 @@ def set_the_autofilter_range
284
281
  @autofilter = @a_range if ptrue?(@param[:autofilter])
285
282
  end
286
283
 
287
- #
288
- # Write the XML declaration.
289
- #
290
- def write_xml_declaration
291
- @writer.xml_decl('UTF-8', 1)
292
- end
293
-
294
284
  def write_table_attributes
295
285
  schema = 'http://schemas.openxmlformats.org/'
296
286
  xmlns = "#{schema}spreadsheetml/2006/main"
297
287
 
298
288
  attributes = [
299
- 'xmlns', xmlns,
300
- 'id', @id,
301
- 'name', @name,
302
- 'displayName', @name,
303
- 'ref', @range
289
+ ['xmlns', xmlns],
290
+ ['id', @id],
291
+ ['name', @name],
292
+ ['displayName', @name],
293
+ ['ref', @range]
304
294
  ]
305
295
 
306
296
  unless ptrue?(@header_row_count)
307
- attributes << 'headerRowCount' << 0
297
+ attributes << ['headerRowCount', 0]
308
298
  end
309
299
 
310
300
  if ptrue?(@totals_row_shown)
311
- attributes << 'totalsRowCount' << 1
301
+ attributes << ['totalsRowCount', 1]
312
302
  else
313
- attributes << 'totalsRowShown' << 0
303
+ attributes << ['totalsRowShown', 0]
314
304
  end
315
305
  end
316
306
 
@@ -320,7 +310,7 @@ def write_table_attributes
320
310
  def write_auto_filter
321
311
  return unless ptrue?(@autofilter)
322
312
 
323
- attributes = ['ref', @autofilter]
313
+ attributes = [ ['ref', @autofilter] ]
324
314
 
325
315
  @writer.empty_tag('autoFilter', attributes)
326
316
  end
@@ -331,7 +321,7 @@ def write_auto_filter
331
321
  def write_table_columns
332
322
  count = @columns.size
333
323
 
334
- attributes = ['count', count]
324
+ attributes = [ ['count', count] ]
335
325
 
336
326
  @writer.tag_elements('tableColumns', attributes) do
337
327
  @columns.each {|col_data| write_table_column(col_data)}
@@ -343,18 +333,18 @@ def write_table_columns
343
333
  #
344
334
  def write_table_column(col_data)
345
335
  attributes = [
346
- 'id', col_data.id,
347
- 'name', col_data.name
336
+ ['id', col_data.id],
337
+ ['name', col_data.name]
348
338
  ]
349
339
 
350
340
  if ptrue?(col_data.total_string)
351
- attributes << :totalsRowLabel << col_data.total_string
341
+ attributes << [:totalsRowLabel, col_data.total_string]
352
342
  elsif ptrue?(col_data.total_function)
353
- attributes << :totalsRowFunction << col_data.total_function
343
+ attributes << [:totalsRowFunction, col_data.total_function]
354
344
  end
355
345
 
356
346
  if col_data.format
357
- attributes << :dataDxfId << col_data.format
347
+ attributes << [:dataDxfId, col_data.format]
358
348
  end
359
349
 
360
350
  if ptrue?(col_data.formula)
@@ -372,11 +362,11 @@ def write_table_column(col_data)
372
362
  #
373
363
  def write_table_style_info
374
364
  attributes = [
375
- 'name', @style,
376
- 'showFirstColumn', @show_first_col,
377
- 'showLastColumn', @show_last_col,
378
- 'showRowStripes', @show_row_stripes,
379
- 'showColumnStripes', @show_col_stripes
365
+ ['name', @style],
366
+ ['showFirstColumn', @show_first_col],
367
+ ['showLastColumn', @show_last_col],
368
+ ['showRowStripes', @show_row_stripes],
369
+ ['showColumnStripes', @show_col_stripes]
380
370
  ]
381
371
 
382
372
  @writer.empty_tag('tableStyleInfo', attributes)
@@ -72,9 +72,9 @@ def write_xml_namespace
72
72
  def xml_attributes
73
73
  schema = 'urn:schemas-microsoft-com:'
74
74
  [
75
- 'xmlns:v', "#{schema}vml",
76
- 'xmlns:o', "#{schema}office:office",
77
- 'xmlns:x', "#{schema}office:excel"
75
+ ['xmlns:v', "#{schema}vml"],
76
+ ['xmlns:o', "#{schema}office:office"],
77
+ ['xmlns:x', "#{schema}office:excel"]
78
78
  ]
79
79
  end
80
80
 
@@ -82,7 +82,9 @@ def xml_attributes
82
82
  # Write the <o:shapelayout> element.
83
83
  #
84
84
  def write_shapelayout(data_id)
85
- attributes = ['v:ext', 'edit']
85
+ attributes = [
86
+ ['v:ext', 'edit']
87
+ ]
86
88
 
87
89
  @writer.tag_elements('o:shapelayout', attributes) do
88
90
  # Write the o:idmap element.
@@ -95,8 +97,8 @@ def write_shapelayout(data_id)
95
97
  #
96
98
  def write_idmap(data_id)
97
99
  attributes = [
98
- 'v:ext', 'edit',
99
- 'data', data_id
100
+ ['v:ext', 'edit'],
101
+ ['data', data_id]
100
102
  ]
101
103
 
102
104
  @writer.empty_tag('o:idmap', attributes)
@@ -107,10 +109,10 @@ def write_idmap(data_id)
107
109
  #
108
110
  def write_comment_shapetype
109
111
  attributes = [
110
- 'id', '_x0000_t202',
111
- 'coordsize', '21600,21600',
112
- 'o:spt', 202,
113
- 'path', 'm,l,21600r21600,l21600,xe'
112
+ ['id', '_x0000_t202'],
113
+ ['coordsize', '21600,21600'],
114
+ ['o:spt', 202],
115
+ ['path', 'm,l,21600r21600,l21600,xe']
114
116
  ]
115
117
 
116
118
  @writer.tag_elements('v:shapetype', attributes) do
@@ -126,10 +128,10 @@ def write_comment_shapetype
126
128
  #
127
129
  def write_button_shapetype
128
130
  attributes = [
129
- 'id', '_x0000_t201',
130
- 'coordsize', '21600,21600',
131
- 'o:spt', 201,
132
- 'path', 'm,l,21600r21600,l21600,xe'
131
+ ['id', '_x0000_t201'],
132
+ ['coordsize', '21600,21600'],
133
+ ['o:spt', 201],
134
+ ['path', 'm,l,21600r21600,l21600,xe']
133
135
  ]
134
136
 
135
137
  @writer.tag_elements('v:shapetype', attributes) do
@@ -147,11 +149,11 @@ def write_button_shapetype
147
149
  #
148
150
  def write_button_path
149
151
  attributes = [
150
- 'shadowok', 'f',
151
- 'o:extrusionok', 'f',
152
- 'strokeok', 'f',
153
- 'fillok', 'f',
154
- 'o:connecttype', 'rect'
152
+ ['shadowok', 'f'],
153
+ ['o:extrusionok', 'f'],
154
+ ['strokeok', 'f'],
155
+ ['fillok', 'f'],
156
+ ['o:connecttype', 'rect']
155
157
  ]
156
158
  @writer.empty_tag('v:path', attributes)
157
159
  end
@@ -161,8 +163,8 @@ def write_button_path
161
163
  #
162
164
  def write_shapetype_lock
163
165
  attributes = [
164
- 'v:ext', 'edit',
165
- 'shapetype', 't'
166
+ ['v:ext', 'edit'],
167
+ ['shapetype', 't']
166
168
  ]
167
169
  @writer.empty_tag('o:lock', attributes)
168
170
  end
@@ -110,12 +110,9 @@ def key_val(key, val)
110
110
  %Q{ #{key}="#{val}"}
111
111
  end
112
112
 
113
- def key_vals(attr)
114
- array = []
115
- (0 .. attr.size-1).step(2) do |i|
116
- array << key_val(attr[i], escape_attributes(attr[i+1]))
117
- end
118
- array.join('')
113
+ def key_vals(attribute)
114
+ attribute.
115
+ inject('') { |str, attr| str + key_val(attr.first, escape_attributes(attr.last)) }
119
116
  end
120
117
 
121
118
  def escape_attributes(str = '')
@@ -215,14 +215,14 @@ def write_sheet_files(dir, sheet, index)
215
215
 
216
216
  def write_sheet(writer, sheet, sheet_id) #:nodoc:
217
217
  attributes = [
218
- 'name', sheet.name,
219
- 'sheetId', sheet_id
218
+ ['name', sheet.name],
219
+ ['sheetId', sheet_id]
220
220
  ]
221
221
 
222
222
  if sheet.hidden?
223
- attributes << 'state' << 'hidden'
223
+ attributes << ['state', 'hidden']
224
224
  end
225
- attributes += r_id_attributes(sheet_id)
225
+ attributes << r_id_attributes(sheet_id)
226
226
  writer.empty_tag_encoded('sheet', attributes)
227
227
  end
228
228
  end
@@ -113,27 +113,27 @@ def group_attributes
113
113
  cust_min = cust_max_min(@min) if @min
114
114
 
115
115
  a = []
116
- a << 'manualMax' << @max if @max && @max != 'group'
117
- a << 'manualMin' << @min if @min && @min != 'group'
116
+ a << ['manualMax', @max] if @max && @max != 'group'
117
+ a << ['manualMin', @min] if @min && @min != 'group'
118
118
 
119
119
  # Ignore the default type attribute (line).
120
- a << 'type' << @type if @type != 'line'
121
-
122
- a << 'lineWeight' << @weight if @weight
123
- a << 'dateAxis' << 1 if @date_axis
124
- a << 'displayEmptyCellsAs' << @empty if ptrue?(@empty)
125
-
126
- a << 'markers' << 1 if @markers
127
- a << 'high' << 1 if @high
128
- a << 'low' << 1 if @low
129
- a << 'first' << 1 if @first
130
- a << 'last' << 1 if @last
131
- a << 'negative' << 1 if @negative
132
- a << 'displayXAxis' << 1 if @axis
133
- a << 'displayHidden' << 1 if @hidden
134
- a << 'minAxisType' << cust_min if cust_min
135
- a << 'maxAxisType' << cust_max if cust_max
136
- a << 'rightToLeft' << 1 if @reverse
120
+ a << ['type', @type] if @type != 'line'
121
+
122
+ a << ['lineWeight', @weight] if @weight
123
+ a << ['dateAxis', 1] if @date_axis
124
+ a << ['displayEmptyCellsAs', @empty] if ptrue?(@empty)
125
+
126
+ a << ['markers', 1] if @markers
127
+ a << ['high', 1] if @high
128
+ a << ['low', 1] if @low
129
+ a << ['first', 1] if @first
130
+ a << ['last', 1] if @last
131
+ a << ['negative', 1] if @negative
132
+ a << ['displayXAxis', 1] if @axis
133
+ a << ['displayHidden', 1] if @hidden
134
+ a << ['minAxisType', cust_min] if cust_min
135
+ a << ['maxAxisType', cust_max] if cust_max
136
+ a << ['rightToLeft', 1] if @reverse
137
137
  a
138
138
  end
139
139
 
@@ -272,9 +272,9 @@ def write_sparklines # :nodoc:
272
272
  def write_spark_color(element, color) # :nodoc:
273
273
  attr = []
274
274
 
275
- attr << 'rgb' << color[:_rgb] if color[:_rgb]
276
- attr << 'theme' << color[:_theme] if color[:_theme]
277
- attr << 'tint' << color[:_tint] if color[:_tint]
275
+ attr << ['rgb', color[:_rgb]] if color[:_rgb]
276
+ attr << ['theme', color[:_theme]] if color[:_theme]
277
+ attr << ['tint', color[:_tint]] if color[:_tint]
278
278
 
279
279
  @writer.empty_tag(element, attr)
280
280
  end
@@ -1,4 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
+ require 'write_xlsx/col_name'
3
+
2
4
  module Writexlsx
3
5
  module Utility
4
6
  ROW_MAX = 1048576 # :nodoc:
@@ -50,25 +52,7 @@ def xl_cell_to_rowcol(cell)
50
52
  end
51
53
 
52
54
  def xl_col_to_name(col, col_absolute)
53
- # Change from 0-indexed to 1 indexed.
54
- col += 1
55
- col_str = ''
56
-
57
- while col > 0
58
- # Set remainder from 1 .. 26
59
- remainder = col % 26
60
- remainder = 26 if remainder == 0
61
-
62
- # Convert the remainder to a character. C-ishly.
63
- col_letter = ("A".ord + remainder - 1).chr
64
-
65
- # Accumulate the column letters, right to left.
66
- col_str = col_letter + col_str
67
-
68
- # Get the next order of magnitude.
69
- col = (col - 1) / 26
70
- end
71
-
55
+ col_str = ColName.instance.col_str(col)
72
56
  "#{absolute_char(col_absolute)}#{col_str}"
73
57
  end
74
58
 
@@ -285,11 +269,11 @@ def substitute_cellref(cell, *args) #:nodoc:
285
269
 
286
270
  def underline_attributes(underline)
287
271
  if underline == 2
288
- ['val', 'double']
272
+ [['val', 'double']]
289
273
  elsif underline == 33
290
- ['val', 'singleAccounting']
274
+ [['val', 'singleAccounting']]
291
275
  elsif underline == 34
292
- ['val', 'doubleAccounting']
276
+ [['val', 'doubleAccounting']]
293
277
  else
294
278
  [] # Default to single underline.
295
279
  end
@@ -299,7 +283,7 @@ def underline_attributes(underline)
299
283
  # Write the <color> element.
300
284
  #
301
285
  def write_color(writer, name, value) #:nodoc:
302
- attributes = [name, value]
286
+ attributes = [[name, value]]
303
287
 
304
288
  writer.empty_tag('color', attributes)
305
289
  end
@@ -378,9 +362,9 @@ def pixels_to_points(vertices)
378
362
 
379
363
  def v_shape_attributes_base(id, z_index)
380
364
  [
381
- 'id', "_x0000_s#{id}",
382
- 'type', type,
383
- 'style', (v_shape_style_base(z_index, vertices) + style_addition).join,
365
+ ['id', "_x0000_s#{id}"],
366
+ ['type', type],
367
+ ['style', (v_shape_style_base(z_index, vertices) + style_addition).join]
384
368
  ]
385
369
  end
386
370
 
@@ -425,8 +409,8 @@ def write_fill
425
409
  def write_comment_path(gradientshapeok, connecttype)
426
410
  attributes = []
427
411
 
428
- attributes << 'gradientshapeok' << 't' if gradientshapeok
429
- attributes << 'o:connecttype' << connecttype
412
+ attributes << ['gradientshapeok', 't'] if gradientshapeok
413
+ attributes << ['o:connecttype', connecttype]
430
414
 
431
415
  @writer.empty_tag('v:path', attributes)
432
416
  end
@@ -453,7 +437,7 @@ def write_auto_fill
453
437
  #
454
438
  def write_div(align, font = nil)
455
439
  style = "text-align:#{align}"
456
- attributes = ['style', style]
440
+ attributes = [['style', style]]
457
441
 
458
442
  @writer.tag_elements('div', attributes) do
459
443
  if font
@@ -473,9 +457,9 @@ def write_font(font)
473
457
  color = '#000000'
474
458
 
475
459
  attributes = [
476
- 'face', face,
477
- 'size', size,
478
- 'color', color
460
+ ['face', face],
461
+ ['size', size],
462
+ ['color', color]
479
463
  ]
480
464
  @writer.data_element('font', caption, attributes)
481
465
  end
@@ -484,7 +468,7 @@ def write_font(font)
484
468
  # Write the <v:stroke> element.
485
469
  #
486
470
  def write_stroke
487
- attributes = ['joinstyle', 'miter']
471
+ attributes = [['joinstyle', 'miter']]
488
472
 
489
473
  @writer.empty_tag('v:stroke', attributes)
490
474
  end
@@ -492,5 +476,49 @@ def write_stroke
492
476
  def r_id_attributes(id)
493
477
  ['r:id', "rId#{id}"]
494
478
  end
479
+
480
+ def write_xml_declaration
481
+ @writer.xml_decl
482
+ yield
483
+ @writer.crlf
484
+ @writer.close
485
+ end
486
+
487
+ #
488
+ # Convert user defined line properties to the structure required internally.
489
+ #
490
+ def line_properties(line) # :nodoc:
491
+ return { :_defined => 0 } unless line
492
+
493
+ dash_types = {
494
+ :solid => 'solid',
495
+ :round_dot => 'sysDot',
496
+ :square_dot => 'sysDash',
497
+ :dash => 'dash',
498
+ :dash_dot => 'dashDot',
499
+ :long_dash => 'lgDash',
500
+ :long_dash_dot => 'lgDashDot',
501
+ :long_dash_dot_dot => 'lgDashDotDot',
502
+ :dot => 'dot',
503
+ :system_dash_dot => 'sysDashDot',
504
+ :system_dash_dot_dot => 'sysDashDotDot'
505
+ }
506
+
507
+ # Check the dash type.
508
+ dash_type = line[:dash_type]
509
+
510
+ if dash_type
511
+ line[:dash_type] = value_or_raise(dash_types, dash_type, 'dash type')
512
+ end
513
+
514
+ line[:_defined] = 1
515
+
516
+ line
517
+ end
518
+
519
+ def value_or_raise(hash, key, msg)
520
+ raise "Unknown #{msg} '#{key}'" unless hash[key.to_sym]
521
+ hash[key.to_sym]
522
+ end
495
523
  end
496
524
  end