write_xlsx 0.72.2 → 0.72.3.beta1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/{README.rdoc → Changes} +3 -94
- data/README.md +96 -0
- data/lib/write_xlsx/chart.rb +115 -259
- data/lib/write_xlsx/chart/axis.rb +4 -4
- data/lib/write_xlsx/chart/bar.rb +1 -1
- data/lib/write_xlsx/chart/column.rb +1 -1
- data/lib/write_xlsx/chart/pie.rb +3 -3
- data/lib/write_xlsx/chart/radar.rb +1 -1
- data/lib/write_xlsx/chart/scatter.rb +1 -1
- data/lib/write_xlsx/chart/series.rb +0 -37
- data/lib/write_xlsx/chartsheet.rb +25 -37
- data/lib/write_xlsx/col_name.rb +40 -0
- data/lib/write_xlsx/drawing.rb +95 -85
- data/lib/write_xlsx/format.rb +32 -32
- data/lib/write_xlsx/package/app.rb +18 -23
- data/lib/write_xlsx/package/button.rb +15 -12
- data/lib/write_xlsx/package/comments.rb +33 -30
- data/lib/write_xlsx/package/conditional_format.rb +18 -14
- data/lib/write_xlsx/package/content_types.rb +22 -17
- data/lib/write_xlsx/package/core.rb +19 -24
- data/lib/write_xlsx/package/relationships.rb +10 -13
- data/lib/write_xlsx/package/shared_strings.rb +8 -16
- data/lib/write_xlsx/package/styles.rb +59 -64
- data/lib/write_xlsx/package/table.rb +27 -37
- data/lib/write_xlsx/package/vml.rb +23 -21
- data/lib/write_xlsx/package/xml_writer_simple.rb +3 -6
- data/lib/write_xlsx/sheets.rb +4 -4
- data/lib/write_xlsx/sparkline.rb +22 -22
- data/lib/write_xlsx/utility.rb +61 -33
- data/lib/write_xlsx/version.rb +1 -1
- data/lib/write_xlsx/workbook.rb +46 -50
- data/lib/write_xlsx/worksheet.rb +149 -133
- data/lib/write_xlsx/worksheet/cell_data.rb +8 -6
- data/lib/write_xlsx/worksheet/data_validation.rb +14 -14
- data/lib/write_xlsx/worksheet/hyperlink.rb +97 -65
- data/lib/write_xlsx/worksheet/page_setup.rb +23 -22
- data/test/chart/test_write_a_latin.rb +3 -3
- data/test/regression/test_chart_font01.rb +1 -1
- data/test/regression/test_chart_font02.rb +1 -1
- data/test/regression/test_chart_font03.rb +1 -1
- data/test/regression/test_chart_font04.rb +1 -1
- data/test/regression/test_chart_font05.rb +1 -1
- data/test/regression/test_chart_font06.rb +1 -1
- data/test/test_xml_writer_simple.rb +3 -3
- data/test/worksheet/test_write_hyperlink.rb +4 -4
- data/test/worksheet/test_write_worksheet_attributes.rb +3 -3
- data/write_xlsx.gemspec +2 -1
- metadata +9 -8
- 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
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
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'
|
297
|
+
attributes << ['headerRowCount', 0]
|
308
298
|
end
|
309
299
|
|
310
300
|
if ptrue?(@totals_row_shown)
|
311
|
-
attributes << 'totalsRowCount'
|
301
|
+
attributes << ['totalsRowCount', 1]
|
312
302
|
else
|
313
|
-
attributes << 'totalsRowShown'
|
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
|
341
|
+
attributes << [:totalsRowLabel, col_data.total_string]
|
352
342
|
elsif ptrue?(col_data.total_function)
|
353
|
-
attributes << :totalsRowFunction
|
343
|
+
attributes << [:totalsRowFunction, col_data.total_function]
|
354
344
|
end
|
355
345
|
|
356
346
|
if col_data.format
|
357
|
-
attributes << :dataDxfId
|
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 = [
|
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(
|
114
|
-
|
115
|
-
|
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 = '')
|
data/lib/write_xlsx/sheets.rb
CHANGED
@@ -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'
|
223
|
+
attributes << ['state', 'hidden']
|
224
224
|
end
|
225
|
-
attributes
|
225
|
+
attributes << r_id_attributes(sheet_id)
|
226
226
|
writer.empty_tag_encoded('sheet', attributes)
|
227
227
|
end
|
228
228
|
end
|
data/lib/write_xlsx/sparkline.rb
CHANGED
@@ -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'
|
117
|
-
a << 'manualMin'
|
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'
|
121
|
-
|
122
|
-
a << 'lineWeight'
|
123
|
-
a << 'dateAxis'
|
124
|
-
a << 'displayEmptyCellsAs'
|
125
|
-
|
126
|
-
a << 'markers'
|
127
|
-
a << 'high'
|
128
|
-
a << 'low'
|
129
|
-
a << 'first'
|
130
|
-
a << 'last'
|
131
|
-
a << 'negative'
|
132
|
-
a << 'displayXAxis'
|
133
|
-
a << 'displayHidden'
|
134
|
-
a << 'minAxisType'
|
135
|
-
a << 'maxAxisType'
|
136
|
-
a << 'rightToLeft'
|
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'
|
276
|
-
attr << 'theme'
|
277
|
-
attr << '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
|
data/lib/write_xlsx/utility.rb
CHANGED
@@ -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
|
-
|
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'
|
429
|
-
attributes << 'o: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
|