write_xlsx 0.0.3 → 0.0.4

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.
@@ -85,12 +85,10 @@ def write_shapelayout(data_id)
85
85
 
86
86
  attributes = ['v:ext', ext]
87
87
 
88
- @writer.start_tag('o:shapelayout', attributes)
89
-
90
- # Write the o:idmap element.
91
- write_idmap(data_id)
92
-
93
- @writer.end_tag('o:shapelayout')
88
+ @writer.tag_elements('o:shapelayout', attributes) do
89
+ # Write the o:idmap element.
90
+ write_idmap(data_id)
91
+ end
94
92
  end
95
93
 
96
94
  #
@@ -123,15 +121,12 @@ def write_shapetype
123
121
  'path', path
124
122
  ]
125
123
 
126
- @writer.start_tag('v:shapetype', attributes)
127
-
128
- # Write the v:stroke element.
129
- write_stroke
130
-
131
- # Write the v:path element.
132
- write_path('t', 'rect')
133
-
134
- @writer.end_tag('v:shapetype')
124
+ @writer.tag_elements('v:shapetype', attributes) do
125
+ # Write the v:stroke element.
126
+ write_stroke
127
+ # Write the v:path element.
128
+ write_path('t', 'rect')
129
+ end
135
130
  end
136
131
 
137
132
  #
@@ -203,24 +198,18 @@ def write_shape(id, z_index, comment)
203
198
  'o:insetmode', insetmode
204
199
  ]
205
200
 
206
- @writer.start_tag('v:shape', attributes)
207
-
208
- # Write the v:fill element.
209
- write_fill
210
-
211
- # Write the v:shadow element.
212
- write_shadow
213
-
214
- # Write the v:path element.
215
- write_path(nil, 'none')
216
-
217
- # Write the v:textbox element.
218
- write_textbox
219
-
220
- # Write the x:ClientData element.
221
- write_client_data(comment)
222
-
223
- @writer.end_tag('v:shape')
201
+ @writer.tag_elements('v:shape', attributes) do
202
+ # Write the v:fill element.
203
+ write_fill
204
+ # Write the v:shadow element.
205
+ write_shadow
206
+ # Write the v:path element.
207
+ write_path(nil, 'none')
208
+ # Write the v:textbox element.
209
+ write_textbox
210
+ # Write the x:ClientData element.
211
+ write_client_data(comment)
212
+ end
224
213
  end
225
214
 
226
215
  def float_to_str(float)
@@ -267,12 +256,10 @@ def write_textbox
267
256
 
268
257
  attributes = ['style', style]
269
258
 
270
- @writer.start_tag('v:textbox', attributes)
271
-
272
- # Write the div element.
273
- write_div
274
-
275
- @writer.end_tag('v:textbox')
259
+ @writer.tag_elements('v:textbox', attributes) do
260
+ # Write the div element.
261
+ write_div
262
+ end
276
263
  end
277
264
 
278
265
  #
@@ -282,8 +269,7 @@ def write_div
282
269
  style = 'text-align:left'
283
270
  attributes = ['style', style]
284
271
 
285
- @writer.start_tag('div', attributes)
286
- @writer.end_tag('div')
272
+ @writer.tag_elements('div', attributes) { }
287
273
  end
288
274
 
289
275
  #
@@ -294,30 +280,22 @@ def write_client_data(comment)
294
280
 
295
281
  attributes = ['ObjectType', object_type]
296
282
 
297
- @writer.start_tag('x:ClientData', attributes)
298
-
299
- # Write the x:MoveWithCells element.
300
- write_move_with_cells
301
-
302
- # Write the x:SizeWithCells element.
303
- write_size_with_cells
304
-
305
- # Write the x:Anchor element.
306
- write_anchor(comment.vertices)
307
-
308
- # Write the x:AutoFill element.
309
- write_auto_fill
310
-
311
- # Write the x:Row element.
312
- write_row(comment.row)
313
-
314
- # Write the x:Column element.
315
- write_column(comment.col)
316
-
317
- # Write the x:Visible element.
318
- write_visible if comment.visible != 0 && !comment.visible.nil?
319
-
320
- @writer.end_tag('x:ClientData')
283
+ @writer.tag_elements('x:ClientData', attributes) do
284
+ # Write the x:MoveWithCells element.
285
+ write_move_with_cells
286
+ # Write the x:SizeWithCells element.
287
+ write_size_with_cells
288
+ # Write the x:Anchor element.
289
+ write_anchor(comment.vertices)
290
+ # Write the x:AutoFill element.
291
+ write_auto_fill
292
+ # Write the x:Row element.
293
+ write_row(comment.row)
294
+ # Write the x:Column element.
295
+ write_column(comment.col)
296
+ # Write the x:Visible element.
297
+ write_visible if comment.visible != 0 && !comment.visible.nil?
298
+ end
321
299
  end
322
300
 
323
301
  #
@@ -22,6 +22,12 @@ def xml_decl(encoding = 'UTF-8', standalone = true)
22
22
  io_write(str)
23
23
  end
24
24
 
25
+ def tag_elements(tag, attributes = [])
26
+ start_tag(tag, attributes)
27
+ yield
28
+ end_tag(tag)
29
+ end
30
+
25
31
  def start_tag(tag, attr = [])
26
32
  str = "<#{tag}#{key_vals(attr)}>"
27
33
  io_write(str)
@@ -38,9 +44,7 @@ def empty_tag(tag, attr = [])
38
44
  end
39
45
 
40
46
  def data_element(tag, data, attr = [])
41
- str = start_tag(tag, attr)
42
- str << io_write("#{characters(data)}")
43
- str << end_tag(tag)
47
+ tag_elements(tag, attr) { io_write("#{characters(data)}") }
44
48
  end
45
49
 
46
50
  def characters(data)
@@ -844,7 +844,7 @@ def write_workbook_pr #:nodoc:
844
844
  end
845
845
 
846
846
  def write_book_views #:nodoc:
847
- @writer.start_tag('bookViews') << write_workbook_view << @writer.end_tag('bookViews')
847
+ @writer.tag_elements('bookViews') { write_workbook_view }
848
848
  end
849
849
 
850
850
  def write_workbook_view #:nodoc:
@@ -864,13 +864,13 @@ def write_workbook_view #:nodoc:
864
864
  end
865
865
 
866
866
  def write_sheets #:nodoc:
867
- str = @writer.start_tag('sheets')
868
- id_num = 1
869
- @worksheets.each do |sheet|
870
- str << write_sheet(sheet.name, id_num, sheet.hidden?)
871
- id_num += 1
867
+ @writer.tag_elements('sheets') do
868
+ id_num = 1
869
+ @worksheets.each do |sheet|
870
+ write_sheet(sheet.name, id_num, sheet.hidden?)
871
+ id_num += 1
872
+ end
872
873
  end
873
- str << @writer.end_tag('sheets')
874
874
  end
875
875
 
876
876
  def write_sheet(name, sheet_id, hidden = false) #:nodoc:
@@ -893,7 +893,7 @@ def write_calc_pr #:nodoc:
893
893
 
894
894
  def write_ext_lst #:nodoc:
895
895
  tag = 'extLst'
896
- @writer.start_tag(tag) << write_ext << @writer.end_tag(tag)
896
+ @writer.tag_elements(tag) { write_ext }
897
897
  end
898
898
 
899
899
  def write_ext #:nodoc:
@@ -902,7 +902,7 @@ def write_ext #:nodoc:
902
902
  'xmlns:mx', 'http://schemas.microsoft.com/office/mac/excel/2008/main',
903
903
  'uri', 'http://schemas.microsoft.com/office/mac/excel/2008/main'
904
904
  ]
905
- @writer.start_tag(tag, attributes) << write_mx_arch_id << @writer.end_tag(tag)
905
+ @writer.tag_elements(tag, attributes) { write_mx_arch_id }
906
906
  end
907
907
 
908
908
  def write_mx_arch_id #:nodoc:
@@ -912,9 +912,9 @@ def write_mx_arch_id #:nodoc:
912
912
  def write_defined_names #:nodoc:
913
913
  return if @defined_names.nil? || @defined_names.empty?
914
914
  tag = 'definedNames'
915
- str = @writer.start_tag(tag)
916
- @defined_names.each { |defined_name| str << write_defined_name(defined_name) }
917
- str << @writer.end_tag(tag)
915
+ @writer.tag_elements(tag) do
916
+ @defined_names.each { |defined_name| write_defined_name(defined_name) }
917
+ end
918
918
  end
919
919
 
920
920
  def write_defined_name(data) #:nodoc:
@@ -949,8 +949,6 @@ def defined_names #:nodoc:
949
949
  # Assemble worksheets into a workbook.
950
950
  #
951
951
  def store_workbook #:nodoc:
952
- packager = Package::Packager.new
953
-
954
952
  # Add a default worksheet if non have been added.
955
953
  add_worksheet if @worksheets.empty?
956
954
 
@@ -960,19 +958,13 @@ def store_workbook #:nodoc:
960
958
  # Set the active sheet.
961
959
  @worksheets.each { |sheet| sheet.activate if sheet.index == @activesheet }
962
960
 
963
- # Prepare the worksheet cell comments.
964
- prepare_comments
965
-
966
- # Set the defined names for the worksheets such as Print Titles.
967
- prepare_defined_names
968
-
969
- # Prepare the drawings, charts and images.
970
- prepare_drawings
971
-
972
- # Add cached data to charts.
973
- add_chart_data
961
+ prepare_comments # Prepare the worksheet cell comments.
962
+ prepare_defined_names # Set the defined names for the worksheets such as Print Titles.
963
+ prepare_drawings # Prepare the drawings, charts and images.
964
+ add_chart_data # Add cached data to charts.
974
965
 
975
966
  # Package the workbook.
967
+ packager = Package::Packager.new
976
968
  packager.add_workbook(self)
977
969
  packager.set_package_dir(@tempdir)
978
970
  packager.create_package
@@ -1020,45 +1012,27 @@ def prepare_formats #:nodoc:
1020
1012
  end
1021
1013
  end
1022
1014
 
1023
- #
1024
- # Set the default index for each format. This is mainly used for testing.
1025
- #
1026
- def set_default_xf_indices #:nodoc:
1027
- @formats.each { |format| format.get_xf_index }
1028
- end
1029
-
1030
1015
  #
1031
1016
  # Iterate through the XF Format objects and give them an index to non-default
1032
1017
  # font elements.
1033
1018
  #
1034
1019
  def prepare_fonts #:nodoc:
1035
1020
  fonts = {}
1036
- index = 0
1037
-
1038
1021
  @xf_formats.each do |format|
1039
1022
  key = format.get_font_key
1040
-
1041
- if fonts[key]
1042
- # Font has already been used.
1043
- format.font_index = fonts[key]
1044
- format.has_font = 0
1045
- else
1046
- # This is a new font.
1047
- fonts[key] = index
1048
- format.font_index = index
1049
- format.has_font = 1
1050
- index += 1
1051
- end
1023
+ format.has_font(!fonts[key])
1024
+ format.font_index = fonts[key] || fonts.size
1025
+ fonts[key] ||= fonts.size
1052
1026
  end
1053
1027
 
1054
- @font_count = index
1028
+ @font_count = fonts.size
1055
1029
 
1056
1030
  # For the DXF formats we only need to check if the properties have changed.
1057
1031
  @dxf_formats.each do |format|
1058
1032
  # The only font properties that can change for a DXF format are: color,
1059
1033
  # bold, italic, underline and strikethrough.
1060
1034
  if format.color || format.bold? || format.italic? || format.underline? || format.strikeout?
1061
- format.has_dxf_font = 1
1035
+ format.has_dxf_font(true)
1062
1036
  end
1063
1037
  end
1064
1038
  end
@@ -1110,30 +1084,19 @@ def prepare_num_formats #:nodoc:
1110
1084
  #
1111
1085
  def prepare_borders #:nodoc:
1112
1086
  borders = {}
1113
- index = 0
1114
-
1115
1087
  @xf_formats.each do |format|
1116
1088
  key = format.get_border_key
1117
-
1118
- if borders[key]
1119
- # Border has already been used.
1120
- format.border_index = borders[key]
1121
- format.has_border = 0
1122
- else
1123
- # This is a new border.
1124
- borders[key] = index
1125
- format.border_index = index
1126
- format.has_border = 1
1127
- index += 1
1128
- end
1089
+ format.has_border(!borders[key])
1090
+ format.border_index = borders[key] || borders.size
1091
+ borders[key] ||= borders.size
1129
1092
  end
1130
1093
 
1131
- @border_count = index
1094
+ @border_count = borders.size
1132
1095
 
1133
1096
  # For the DXF formats we only need to check if the properties have changed.
1134
1097
  @dxf_formats.each do |format|
1135
1098
  key = format.get_border_key
1136
- format.has_dxf_border = 1 if key =~ /[^0:]/
1099
+ format.has_dxf_border(true) if key =~ /[^0:]/
1137
1100
  end
1138
1101
  end
1139
1102
 
@@ -1177,12 +1140,12 @@ def prepare_fills #:nodoc:
1177
1140
  if fills[key]
1178
1141
  # Fill has already been used.
1179
1142
  format.fill_index = fills[key]
1180
- format.has_fill = 0
1143
+ format.has_fill(false)
1181
1144
  else
1182
1145
  # This is a new fill.
1183
1146
  fills[key] = index
1184
1147
  format.fill_index = index
1185
- format.has_fill = 1
1148
+ format.has_fill(true)
1186
1149
  index += 1
1187
1150
  end
1188
1151
  end
@@ -1191,7 +1154,7 @@ def prepare_fills #:nodoc:
1191
1154
 
1192
1155
  # For the DXF formats we only need to check if the properties have changed.
1193
1156
  @dxf_formats.each do |format|
1194
- format.has_dxf_fill = 1 if format.pattern || format.bg_color || format.fg_color
1157
+ format.has_dxf_fill(true) if format.pattern || format.bg_color || format.fg_color
1195
1158
  end
1196
1159
  end
1197
1160
 
@@ -109,23 +109,21 @@ class CellData # :nodoc:
109
109
  attr_reader :result, :range, :link_type, :url, :tip
110
110
 
111
111
  #
112
- # Write the <cell> element. This is the innermost loop so efficiency is
112
+ # attributes for the <cell> element. This is the innermost loop so efficiency is
113
113
  # important where possible.
114
114
  #
115
- def write_cell(worksheet) #:nodoc:
116
- xf_index = 0
117
- xf_index = xf.get_xf_index if xf.respond_to?(:get_xf_index)
118
-
115
+ def cell_attributes #:nodoc:
116
+ xf_index = xf ? xf.get_xf_index : 0
119
117
  attributes = ['r', xl_rowcol_to_cell(row, col)]
120
118
 
121
119
  # Add the cell format index.
122
120
  if xf_index != 0
123
121
  attributes << 's' << xf_index
124
- elsif worksheet.set_rows[row] && worksheet.set_rows[row][1]
125
- row_xf = worksheet.set_rows[row][1]
122
+ elsif @worksheet.set_rows[row] && @worksheet.set_rows[row][1]
123
+ row_xf = @worksheet.set_rows[row][1]
126
124
  attributes << 's' << row_xf.get_xf_index
127
- elsif worksheet.col_formats[col]
128
- col_xf = worksheet.col_formats[col]
125
+ elsif @worksheet.col_formats[col]
126
+ col_xf = @worksheet.col_formats[col]
129
127
  attributes << 's' << col_xf.get_xf_index
130
128
  end
131
129
  attributes
@@ -133,7 +131,8 @@ def write_cell(worksheet) #:nodoc:
133
131
  end
134
132
 
135
133
  class NumberCellData < CellData # :nodoc:
136
- def initialize(row, col, num, xf)
134
+ def initialize(worksheet, row, col, num, xf)
135
+ @worksheet = worksheet
137
136
  @row, @col, @token, @xf = row, col, num, xf
138
137
  end
139
138
 
@@ -141,16 +140,16 @@ def data
141
140
  @token
142
141
  end
143
142
 
144
- def write_cell(worksheet)
145
- attributes = super(worksheet)
146
- worksheet.writer.start_tag('c', attributes)
147
- worksheet.write_cell_value(token)
148
- worksheet.writer.end_tag('c')
143
+ def write_cell
144
+ @worksheet.writer.tag_elements('c', cell_attributes) do
145
+ @worksheet.write_cell_value(token)
146
+ end
149
147
  end
150
148
  end
151
149
 
152
150
  class StringCellData < CellData # :nodoc:
153
- def initialize(row, col, index, xf)
151
+ def initialize(worksheet, row, col, index, xf)
152
+ @worksheet = worksheet
154
153
  @row, @col, @token, @xf = row, col, index, xf
155
154
  end
156
155
 
@@ -158,17 +157,18 @@ def data
158
157
  { :sst_id => token }
159
158
  end
160
159
 
161
- def write_cell(worksheet)
162
- attributes = super(worksheet)
160
+ def write_cell
161
+ attributes = cell_attributes
163
162
  attributes << 't' << 's'
164
- worksheet.writer.start_tag('c', attributes)
165
- worksheet.write_cell_value(token)
166
- worksheet.writer.end_tag('c')
163
+ @worksheet.writer.tag_elements('c', attributes) do
164
+ @worksheet.write_cell_value(token)
165
+ end
167
166
  end
168
167
  end
169
168
 
170
169
  class FormulaCellData < CellData # :nodoc:
171
- def initialize(row, col, formula, xf, result)
170
+ def initialize(worksheet, row, col, formula, xf, result)
171
+ @worksheet = worksheet
172
172
  @row, @col, @token, @xf, @result = row, col, formula, xf, result
173
173
  end
174
174
 
@@ -176,17 +176,17 @@ def data
176
176
  @result || 0
177
177
  end
178
178
 
179
- def write_cell(worksheet)
180
- attributes = super(worksheet)
181
- worksheet.writer.start_tag('c', attributes)
182
- worksheet.write_cell_formula(token)
183
- worksheet.write_cell_value(result || 0)
184
- worksheet.writer.end_tag('c')
179
+ def write_cell
180
+ @worksheet.writer.tag_elements('c', cell_attributes) do
181
+ @worksheet.write_cell_formula(token)
182
+ @worksheet.write_cell_value(result || 0)
183
+ end
185
184
  end
186
185
  end
187
186
 
188
187
  class FormulaArrayCellData < CellData # :nodoc:
189
- def initialize(row, col, formula, xf, range, result)
188
+ def initialize(worksheet, row, col, formula, xf, range, result)
189
+ @worksheet = worksheet
190
190
  @row, @col, @token, @xf, @range, @result = row, col, formula, xf, range, result
191
191
  end
192
192
 
@@ -194,17 +194,17 @@ def data
194
194
  @result || 0
195
195
  end
196
196
 
197
- def write_cell(worksheet)
198
- attributes = super(worksheet)
199
- worksheet.writer.start_tag('c', attributes)
200
- worksheet.write_cell_array_formula(token, range)
201
- worksheet.write_cell_value(result)
202
- worksheet.writer.end_tag('c')
197
+ def write_cell
198
+ @worksheet.writer.tag_elements('c', cell_attributes) do
199
+ @worksheet.write_cell_array_formula(token, range)
200
+ @worksheet.write_cell_value(result)
201
+ end
203
202
  end
204
203
  end
205
204
 
206
205
  class HyperlinkCellData < CellData # :nodoc:
207
- def initialize(row, col, index, xf, link_type, url, str, tip)
206
+ def initialize(worksheet, row, col, index, xf, link_type, url, str, tip)
207
+ @worksheet = worksheet
208
208
  @row, @col, @token, @xf, @link_type, @url, @str, @tip =
209
209
  row, col, index, xf, link_type, url, str, tip
210
210
  end
@@ -213,32 +213,33 @@ def data
213
213
  { :sst_id => token }
214
214
  end
215
215
 
216
- def write_cell(worksheet)
217
- attributes = super(worksheet)
216
+ def write_cell
217
+ attributes = cell_attributes
218
218
  attributes << 't' << 's'
219
- worksheet.writer.start_tag('c', attributes)
220
- worksheet.write_cell_value(token)
221
- worksheet.writer.end_tag('c')
219
+ @worksheet.writer.tag_elements('c', attributes) do
220
+ @worksheet.write_cell_value(token)
221
+ end
222
222
 
223
223
  if link_type == 1
224
224
  # External link with rel file relationship.
225
- worksheet.hlink_count += 1
226
- worksheet.hlink_refs <<
225
+ @worksheet.hlink_count += 1
226
+ @worksheet.hlink_refs <<
227
227
  [
228
228
  link_type, row, col,
229
- worksheet.hlink_count, @str, @tip
229
+ @worksheet.hlink_count, @str, @tip
230
230
  ]
231
231
 
232
- worksheet.external_hyper_links << [ '/hyperlink', @url, 'External' ]
232
+ @worksheet.external_hyper_links << [ '/hyperlink', @url, 'External' ]
233
233
  elsif link_type
234
234
  # External link with rel file relationship.
235
- worksheet.hlink_refs << [link_type, row, col, @url, @str, @tip ]
235
+ @worksheet.hlink_refs << [link_type, row, col, @url, @str, @tip ]
236
236
  end
237
237
  end
238
238
  end
239
239
 
240
240
  class BlankCellData < CellData # :nodoc:
241
- def initialize(row, col, index, xf)
241
+ def initialize(worksheet, row, col, index, xf)
242
+ @worksheet = worksheet
242
243
  @row, @col, @xf = row, col, xf
243
244
  end
244
245
 
@@ -246,9 +247,8 @@ def data
246
247
  ''
247
248
  end
248
249
 
249
- def write_cell(worksheet)
250
- attributes = super(worksheet)
251
- worksheet.writer.empty_tag('c', attributes)
250
+ def write_cell
251
+ @worksheet.writer.empty_tag('c', cell_attributes)
252
252
  end
253
253
  end
254
254
 
@@ -724,14 +724,14 @@ def set_column(*args)
724
724
  # the column dimensions in certain cases.
725
725
  ignore_row = 1
726
726
  ignore_col = 1
727
- ignore_col = 0 if format.respond_to?(:get_xf_index) # Column has a format.
727
+ ignore_col = 0 if format.respond_to?(:xf_index) # Column has a format.
728
728
  ignore_col = 0 if width && hidden && hidden != 0 # Column has a width but is hidden
729
729
 
730
730
  check_dimensions_and_update_max_min_values(0, firstcol, ignore_row, ignore_col)
731
731
  check_dimensions_and_update_max_min_values(0, lastcol, ignore_row, ignore_col)
732
732
 
733
733
  # Set the limits for the outline levels (0 <= x <= 7).
734
- level = 0 unless level
734
+ level ||= 0
735
735
  level = 0 if level < 0
736
736
  level = 7 if level > 7
737
737
 
@@ -2072,13 +2072,11 @@ def write_number(*args)
2072
2072
  row, col, num, xf = row_col_notation(args)
2073
2073
  raise WriteXLSXInsufficientArgumentError if [row, col, num].include?(nil)
2074
2074
 
2075
- type = 'n'
2076
-
2077
2075
  # Check that row and col are valid and store max and min values
2078
2076
  check_dimensions(row, col)
2079
2077
  store_row_col_max_min_values(row, col)
2080
2078
 
2081
- store_data_to_table(NumberCellData.new(row, col, num, xf))
2079
+ store_data_to_table(NumberCellData.new(self, row, col, num, xf))
2082
2080
  end
2083
2081
 
2084
2082
  #
@@ -2121,7 +2119,7 @@ def write_string(*args)
2121
2119
 
2122
2120
  index = shared_string_index(str[0, STR_MAX])
2123
2121
 
2124
- store_data_to_table(StringCellData.new(row, col, index, xf))
2122
+ store_data_to_table(StringCellData.new(self, row, col, index, xf))
2125
2123
  end
2126
2124
 
2127
2125
  #
@@ -2222,12 +2220,11 @@ def write_rich_string(*args)
2222
2220
  raise WriteXLSXInsufficientArgumentError if [row, col, rich_strings[0]].include?(nil)
2223
2221
 
2224
2222
  # If the last arg is a format we use it as the cell format.
2225
- if rich_strings[-1].respond_to?(:get_xf_index)
2223
+ if rich_strings[-1].respond_to?(:xf_index)
2226
2224
  xf = rich_strings.pop
2227
2225
  else
2228
- xf = nil
2226
+ xf = nil
2229
2227
  end
2230
- type = 's' # The data type.
2231
2228
 
2232
2229
  # Check that row and col are valid and store max and min values
2233
2230
  check_dimensions(row, col)
@@ -2240,11 +2237,11 @@ def write_rich_string(*args)
2240
2237
  fragments, length = rich_strings_fragments(rich_strings)
2241
2238
 
2242
2239
  # If the first token is a string start the <r> element.
2243
- writer.start_tag('r') if !fragments[0].respond_to?(:get_xf_index)
2240
+ writer.start_tag('r') if !fragments[0].respond_to?(:xf_index)
2244
2241
 
2245
2242
  # Write the XML elements for the format string fragments.
2246
2243
  fragments.each do |token|
2247
- if token.respond_to?(:get_xf_index)
2244
+ if token.respond_to?(:xf_index)
2248
2245
  # Write the font run.
2249
2246
  writer.start_tag('r')
2250
2247
  write_font(writer, token)
@@ -2261,7 +2258,7 @@ def write_rich_string(*args)
2261
2258
  # Add the XML string to the shared string table.
2262
2259
  index = shared_string_index(writer.string)
2263
2260
 
2264
- store_data_to_table(StringCellData.new(row, col, index, xf))
2261
+ store_data_to_table(StringCellData.new(self, row, col, index, xf))
2265
2262
  end
2266
2263
 
2267
2264
  #
@@ -2303,7 +2300,7 @@ def write_blank(*args)
2303
2300
  check_dimensions(row, col)
2304
2301
  store_row_col_max_min_values(row, col)
2305
2302
 
2306
- store_data_to_table(BlankCellData.new(row, col, nil, xf))
2303
+ store_data_to_table(BlankCellData.new(self, row, col, nil, xf))
2307
2304
  end
2308
2305
 
2309
2306
  #
@@ -2343,16 +2340,14 @@ def write_formula(*args)
2343
2340
  raise WriteXLSXInsufficientArgumentError if [row, col, formula].include?(nil)
2344
2341
 
2345
2342
  if formula =~ /^\{=.*\}$/
2346
- return write_array_formula(row, col, row, col, formula, format, value)
2347
- end
2348
-
2349
- # Check that row and col are valid and store max and min values
2350
- check_dimensions(row, col)
2351
- store_row_col_max_min_values(row, col)
2352
-
2353
- formula.sub!(/^=/, '')
2343
+ write_array_formula(row, col, row, col, formula, format, value)
2344
+ else
2345
+ check_dimensions(row, col)
2346
+ store_row_col_max_min_values(row, col)
2347
+ formula.sub!(/^=/, '')
2354
2348
 
2355
- store_data_to_table(FormulaCellData.new(row, col, formula, format, value))
2349
+ store_data_to_table(FormulaCellData.new(self, row, col, formula, format, value))
2350
+ end
2356
2351
  end
2357
2352
 
2358
2353
  #
@@ -2425,7 +2420,7 @@ def write_array_formula(*args)
2425
2420
  formula.sub!(/^\{(.*)\}$/, '\1')
2426
2421
  formula.sub!(/^=/, '')
2427
2422
 
2428
- store_data_to_table(FormulaArrayCellData.new(row1, col1, formula, xf, range, value))
2423
+ store_data_to_table(FormulaArrayCellData.new(self, row1, col1, formula, xf, range, value))
2429
2424
  end
2430
2425
 
2431
2426
  # The outline_settings() method is used to control the appearance of
@@ -2547,7 +2542,6 @@ def write_url(*args)
2547
2542
  xf, str = str, xf if str.respond_to?(:xf_index)
2548
2543
  raise WriteXLSXInsufficientArgumentError if [row, col, url].include?(nil)
2549
2544
 
2550
- type = 'l' # XML data type
2551
2545
  link_type = 1
2552
2546
 
2553
2547
  # Remove the URI scheme from internal links.
@@ -2561,7 +2555,7 @@ def write_url(*args)
2561
2555
  end
2562
2556
 
2563
2557
  # The displayed string defaults to the url string.
2564
- str = url unless str
2558
+ str ||= url
2565
2559
 
2566
2560
  # For external links change the directory separator from Unix to Dos.
2567
2561
  if link_type == 3
@@ -2599,7 +2593,7 @@ def write_url(*args)
2599
2593
  link_type = 1
2600
2594
  end
2601
2595
 
2602
- store_data_to_table(HyperlinkCellData.new(row, col, index, xf, link_type, url, str, tip))
2596
+ store_data_to_table(HyperlinkCellData.new(self, row, col, index, xf, link_type, url, str, tip))
2603
2597
  end
2604
2598
 
2605
2599
  #
@@ -2656,9 +2650,12 @@ def write_date_time(*args)
2656
2650
 
2657
2651
  date_time = convert_date_time(str)
2658
2652
 
2659
- # If the date isn't valid then write it as a string.
2660
- return write_string(args) unless date_time
2661
- store_data_to_table(NumberCellData.new(row, col, date_time, xf))
2653
+ if date_time
2654
+ store_data_to_table(NumberCellData.new(self, row, col, date_time, xf))
2655
+ else
2656
+ # If the date isn't valid then write it as a string.
2657
+ write_string(args) unless date_time
2658
+ end
2662
2659
  end
2663
2660
 
2664
2661
  #
@@ -3048,7 +3045,7 @@ def merge_range(*args)
3048
3045
  row_first, col_first, row_last, col_last, string, format, *extra_args = row_col_notation(args)
3049
3046
 
3050
3047
  raise "Incorrect number of arguments" if [row_first, col_first, row_last, col_last, format].include?(nil)
3051
- raise "Fifth parameter must be a format object" unless format.respond_to?(:get_xf_index)
3048
+ raise "Fifth parameter must be a format object" unless format.respond_to?(:xf_index)
3052
3049
  raise "Can't merge single cell" if row_first == row_last && col_first == col_last
3053
3050
 
3054
3051
  # Swap last row/col with first row/col as necessary
@@ -3081,7 +3078,7 @@ def merge_range_type(type, *args)
3081
3078
  row_first, col_first, row_last, col_last, token, format, *others = row_col_notation(args)
3082
3079
  end
3083
3080
 
3084
- raise "Format object missing or in an incorrect position" unless format.respond_to?(:get_xf_index)
3081
+ raise "Format object missing or in an incorrect position" unless format.respond_to?(:xf_index)
3085
3082
  raise "Can't merge single cell" if row_first == row_last && col_first == col_last
3086
3083
 
3087
3084
  # Swap last row/col with first row/col as necessary
@@ -4344,16 +4341,6 @@ def set_some_defaults(param)
4344
4341
  param[:show_error] ||= 1
4345
4342
  end
4346
4343
 
4347
- # Minor modification to allow comparison testing. Change RGB colors
4348
- # from long format, ffcc00 to short format fc0 used by VML.
4349
- def rgb_color(rgb)
4350
- result = sprintf("%02x%02x%02x", *rgb)
4351
- if result =~ /^([0-9a-f])\1([0-9a-f])\2([0-9a-f])\3$/
4352
- result = "#{$1}#{$2}#{$3}"
4353
- end
4354
- result
4355
- end
4356
-
4357
4344
  # List of valid input parameters.
4358
4345
  def valid_validation_parameter
4359
4346
  [
@@ -4406,7 +4393,7 @@ def rich_strings_fragments(rich_strings) # :nodoc:
4406
4393
 
4407
4394
  fragments = []
4408
4395
  rich_strings.each do |token|
4409
- if token.respond_to?(:get_xf_index)
4396
+ if token.respond_to?(:xf_index)
4410
4397
  raise AugumentError, "Can't allow 2 formats in a row" if last == 'format' && pos > 0
4411
4398
 
4412
4399
  # Token is a format object. Add it to the fragment list.
@@ -4837,10 +4824,10 @@ def write_sheet_pr #:nodoc:
4837
4824
  (attributes << 'filterMode' << 1) if filter_on?
4838
4825
 
4839
4826
  if fit_page? || tab_color?
4840
- @writer.start_tag('sheetPr', attributes)
4841
- write_tab_color
4842
- write_page_set_up_pr
4843
- @writer.end_tag('sheetPr')
4827
+ @writer.tag_elements('sheetPr', attributes) do
4828
+ write_tab_color
4829
+ write_page_set_up_pr
4830
+ end
4844
4831
  else
4845
4832
  @writer.empty_tag('sheetPr', attributes)
4846
4833
  end
@@ -4892,9 +4879,7 @@ def write_dimension #:nodoc:
4892
4879
  # Write the <sheetViews> element.
4893
4880
  #
4894
4881
  def write_sheet_views #:nodoc:
4895
- @writer.start_tag('sheetViews', [])
4896
- write_sheet_view
4897
- @writer.end_tag('sheetViews')
4882
+ @writer.tag_elements('sheetViews', []) { write_sheet_view }
4898
4883
  end
4899
4884
 
4900
4885
  def write_sheet_view #:nodoc:
@@ -4926,10 +4911,10 @@ def write_sheet_view #:nodoc:
4926
4911
  if @panes.empty? && @selections.empty?
4927
4912
  @writer.empty_tag('sheetView', attributes)
4928
4913
  else
4929
- @writer.start_tag('sheetView', attributes)
4930
- write_panes
4931
- write_selections
4932
- @writer.end_tag('sheetView')
4914
+ @writer.tag_elements('sheetView', attributes) do
4915
+ write_panes
4916
+ write_selections
4917
+ end
4933
4918
  end
4934
4919
  end
4935
4920
 
@@ -4972,10 +4957,9 @@ def write_cols #:nodoc:
4972
4957
  # Exit unless some column have been formatted.
4973
4958
  return if @colinfo.empty?
4974
4959
 
4975
- @writer.start_tag('cols')
4976
- @colinfo.each {|col_info| write_col_info(*col_info) }
4977
-
4978
- @writer.end_tag('cols')
4960
+ @writer.tag_elements('cols') do
4961
+ @colinfo.each {|col_info| write_col_info(*col_info) }
4962
+ end
4979
4963
  end
4980
4964
 
4981
4965
  #
@@ -4989,23 +4973,15 @@ def write_col_info(*args) #:nodoc:
4989
4973
  hidden = args[4] || 0 # Hidden flag.
4990
4974
  level = args[5] || 0 # Outline level.
4991
4975
  collapsed = args[6] || 0 # Outline level.
4976
+ xf_index = format ? format.get_xf_index : 0
4992
4977
 
4993
4978
  custom_width = true
4994
- xf_index = 0
4995
- xf_index = format.get_xf_index if format.respond_to?(:get_xf_index)
4979
+ custom_width = false if width.nil? && hidden == 0
4980
+ custom_width = false if width == 8.43
4996
4981
 
4997
- # Set the Excel default col width.
4998
4982
  if width.nil?
4999
- if hidden == 0
5000
- width = 8.43
5001
- custom_width = false
5002
- else
5003
- width = 0
5004
- end
5005
- else
5006
- # Width is defined but same as default.
5007
- custom_width = false if width == 8.43
5008
- end
4983
+ width = hidden == 0 ? 8.43 : 0
4984
+ end
5009
4985
 
5010
4986
  # Convert column width from user units to character width.
5011
4987
  max_digit_width = 7.0 # For Calabri 11.
@@ -5036,9 +5012,7 @@ def write_sheet_data #:nodoc:
5036
5012
  # If the dimensions aren't defined then there is no data to write.
5037
5013
  @writer.empty_tag('sheetData')
5038
5014
  else
5039
- @writer.start_tag('sheetData')
5040
- write_rows
5041
- @writer.end_tag('sheetData')
5015
+ @writer.tag_elements('sheetData') { write_rows }
5042
5016
  end
5043
5017
  end
5044
5018
 
@@ -5112,7 +5086,7 @@ def not_contain_formatting_or_data?(row_num) # :nodoc:
5112
5086
 
5113
5087
  def write_cell_column_dimension(row_num) # :nodoc:
5114
5088
  (@dim_colmin .. @dim_colmax).each do |col_num|
5115
- @cell_data_table[row_num][col_num].write_cell(self) if @cell_data_table[row_num][col_num]
5089
+ @cell_data_table[row_num][col_num].write_cell if @cell_data_table[row_num][col_num]
5116
5090
  end
5117
5091
  end
5118
5092
 
@@ -5125,12 +5099,10 @@ def write_row_element(r, spans = nil, height = 15, format = nil, hidden = false,
5125
5099
  level ||= 0
5126
5100
  collapsed ||= 0
5127
5101
  empty_row ||= 0
5128
- xf_index = 0
5102
+ xf_index = format ? format.get_xf_index : 0
5129
5103
 
5130
5104
  attributes = ['r', r + 1]
5131
5105
 
5132
- xf_index = format.get_xf_index if format
5133
-
5134
5106
  (attributes << 'spans' << spans) if spans
5135
5107
  (attributes << 's' << xf_index) if xf_index != 0
5136
5108
  (attributes << 'customFormat' << 1 ) if format
@@ -5362,9 +5334,7 @@ def write_page_setup #:nodoc:
5362
5334
  # Write the <extLst> element.
5363
5335
  #
5364
5336
  def write_ext_lst #:nodoc:
5365
- @writer.start_tag('extLst')
5366
- write_ext
5367
- @writer.end_tag('extLst')
5337
+ @writer.tag_elements('extLst') { write_ext }
5368
5338
  end
5369
5339
 
5370
5340
  #
@@ -5379,9 +5349,7 @@ def write_ext #:nodoc:
5379
5349
  'uri', uri
5380
5350
  ]
5381
5351
 
5382
- @writer.start_tag('ext', attributes)
5383
- write_mx_plv
5384
- @writer.end_tag('ext')
5352
+ @writer.tag_elements('ext', attributes) { write_mx_plv }
5385
5353
  end
5386
5354
 
5387
5355
  #
@@ -5409,12 +5377,10 @@ def write_merge_cells #:nodoc:
5409
5377
 
5410
5378
  attributes = ['count', @merge.size]
5411
5379
 
5412
- @writer.start_tag('mergeCells', attributes)
5413
-
5414
- # Write the mergeCell element.
5415
- @merge.each { |merged_range| write_merge_cell(merged_range) }
5416
-
5417
- @writer.end_tag('mergeCells')
5380
+ @writer.tag_elements('mergeCells', attributes) do
5381
+ # Write the mergeCell element.
5382
+ @merge.each { |merged_range| write_merge_cell(merged_range) }
5383
+ end
5418
5384
  end
5419
5385
 
5420
5386
 
@@ -5463,10 +5429,10 @@ def write_print_options #:nodoc:
5463
5429
  def write_header_footer #:nodoc:
5464
5430
  return unless header_footer_changed?
5465
5431
 
5466
- @writer.start_tag('headerFooter')
5467
- write_odd_header if @header && @header != ''
5468
- write_odd_footer if @footer && @footer != ''
5469
- @writer.end_tag('headerFooter')
5432
+ @writer.tag_elements('headerFooter') do
5433
+ write_odd_header if @header && @header != ''
5434
+ write_odd_footer if @footer && @footer != ''
5435
+ end
5470
5436
  end
5471
5437
 
5472
5438
  #
@@ -5476,7 +5442,6 @@ def write_odd_header #:nodoc:
5476
5442
  @writer.data_element('oddHeader', @header)
5477
5443
  end
5478
5444
 
5479
- # _write_odd_footer()
5480
5445
  #
5481
5446
  # Write the <oddFooter> element.
5482
5447
  #
@@ -5515,9 +5480,9 @@ def write_breaks(tag) # :nodoc:
5515
5480
 
5516
5481
  attributes = ['count', count, 'manualBreakCount', count]
5517
5482
 
5518
- @writer.start_tag(tag, attributes)
5519
- page_breaks.each { |num| write_brk(num, max) }
5520
- @writer.end_tag(tag)
5483
+ @writer.tag_elements(tag, attributes) do
5484
+ page_breaks.each { |num| write_brk(num, max) }
5485
+ end
5521
5486
  end
5522
5487
  #
5523
5488
  # Write the <brk> element.
@@ -5542,9 +5507,9 @@ def write_auto_filter #:nodoc:
5542
5507
 
5543
5508
  if filter_on?
5544
5509
  # Autofilter defined active filters.
5545
- @writer.start_tag('autoFilter', attributes)
5546
- write_autofilters
5547
- @writer.end_tag('autoFilter')
5510
+ @writer.tag_elements('autoFilter', attributes) do
5511
+ write_autofilters
5512
+ end
5548
5513
  else
5549
5514
  # Autofilter defined without active filters.
5550
5515
  @writer.empty_tag('autoFilter', attributes)
@@ -5576,16 +5541,15 @@ def write_autofilters #:nodoc:
5576
5541
  def write_filter_column(col_id, type, *filters) #:nodoc:
5577
5542
  attributes = ['colId', col_id]
5578
5543
 
5579
- @writer.start_tag('filterColumn', attributes)
5580
- if type == 1
5581
- # Type == 1 is the new XLSX style filter.
5582
- write_filters(*filters)
5583
- else
5584
- # Type == 0 is the classic "custom" filter.
5585
- write_custom_filters(*filters)
5544
+ @writer.tag_elements('filterColumn', attributes) do
5545
+ if type == 1
5546
+ # Type == 1 is the new XLSX style filter.
5547
+ write_filters(*filters)
5548
+ else
5549
+ # Type == 0 is the classic "custom" filter.
5550
+ write_custom_filters(*filters)
5551
+ end
5586
5552
  end
5587
-
5588
- @writer.end_tag('filterColumn')
5589
5553
  end
5590
5554
 
5591
5555
  #
@@ -5597,9 +5561,9 @@ def write_filters(*filters) #:nodoc:
5597
5561
  @writer.empty_tag('filters', ['blank', 1])
5598
5562
  else
5599
5563
  # General case.
5600
- @writer.start_tag('filters')
5601
- filters.each { |filter| write_filter(filter) }
5602
- @writer.end_tag('filters')
5564
+ @writer.tag_elements('filters') do
5565
+ filters.each { |filter| write_filter(filter) }
5566
+ end
5603
5567
  end
5604
5568
  end
5605
5569
 
@@ -5617,9 +5581,7 @@ def write_filter(val) #:nodoc:
5617
5581
  def write_custom_filters(*tokens) #:nodoc:
5618
5582
  if tokens.size == 2
5619
5583
  # One filter expression only.
5620
- @writer.start_tag('customFilters')
5621
- write_custom_filter(*tokens)
5622
- @writer.end_tag('customFilters')
5584
+ @writer.tag_elements('customFilters') { write_custom_filter(*tokens) }
5623
5585
  else
5624
5586
  # Two filter expressions.
5625
5587
 
@@ -5631,10 +5593,10 @@ def write_custom_filters(*tokens) #:nodoc:
5631
5593
  end
5632
5594
 
5633
5595
  # Write the two custom filters.
5634
- @writer.start_tag('customFilters', attributes)
5635
- write_custom_filter(tokens[0], tokens[1])
5636
- write_custom_filter(tokens[3], tokens[4])
5637
- @writer.end_tag('customFilters')
5596
+ @writer.tag_elements('customFilters', attributes) do
5597
+ write_custom_filter(tokens[0], tokens[1])
5598
+ write_custom_filter(tokens[3], tokens[4])
5599
+ end
5638
5600
  end
5639
5601
  end
5640
5602
 
@@ -5675,19 +5637,17 @@ def write_custom_filter(operator, val) #:nodoc:
5675
5637
  def write_hyperlinks #:nodoc:
5676
5638
  return if @hlink_refs.empty?
5677
5639
 
5678
- @writer.start_tag('hyperlinks')
5640
+ @writer.tag_elements('hyperlinks') do
5641
+ @hlink_refs.each do |aref|
5642
+ type, *args = aref
5679
5643
 
5680
- @hlink_refs.each do |aref|
5681
- type, *args = aref
5682
-
5683
- if type == 1
5684
- write_hyperlink_external(*args)
5685
- elsif type == 2
5686
- write_hyperlink_internal(*args)
5644
+ if type == 1
5645
+ write_hyperlink_external(*args)
5646
+ elsif type == 2
5647
+ write_hyperlink_internal(*args)
5648
+ end
5687
5649
  end
5688
5650
  end
5689
-
5690
- @writer.end_tag('hyperlinks')
5691
5651
  end
5692
5652
 
5693
5653
  #
@@ -5798,42 +5758,39 @@ def write_legacy_drawing #:nodoc:
5798
5758
  # Write the <font> element.
5799
5759
  #
5800
5760
  def write_font(writer, format) #:nodoc:
5801
- writer.start_tag('rPr')
5802
-
5803
- writer.empty_tag('b') if format.bold?
5804
- writer.empty_tag('i') if format.italic?
5805
- writer.empty_tag('strike') if format.strikeout?
5806
- writer.empty_tag('outline') if format.outline?
5807
- writer.empty_tag('shadow') if format.shadow?
5808
-
5809
- # Handle the underline variants.
5810
- write_underline(writer, format.underline) if format.underline?
5811
-
5812
- write_vert_align(writer, 'superscript') if format.font_script == 1
5813
- write_vert_align(writer, 'subscript') if format.font_script == 2
5814
-
5815
- writer.empty_tag('sz', ['val', format.size])
5816
-
5817
- theme = format.theme
5818
- color = format.color
5819
- if !theme.nil? && theme != 0
5820
- write_color(writer, 'theme', theme)
5821
- elsif !color.nil? && color != 0
5822
- color = get_palette_color(color)
5823
-
5824
- write_color(writer, 'rgb', color)
5825
- else
5826
- write_color(writer, 'theme', 1)
5827
- end
5761
+ writer.tag_elements('rPr') do
5762
+ writer.empty_tag('b') if format.bold?
5763
+ writer.empty_tag('i') if format.italic?
5764
+ writer.empty_tag('strike') if format.strikeout?
5765
+ writer.empty_tag('outline') if format.outline?
5766
+ writer.empty_tag('shadow') if format.shadow?
5767
+
5768
+ # Handle the underline variants.
5769
+ write_underline(writer, format.underline) if format.underline?
5770
+
5771
+ write_vert_align(writer, 'superscript') if format.font_script == 1
5772
+ write_vert_align(writer, 'subscript') if format.font_script == 2
5773
+
5774
+ writer.empty_tag('sz', ['val', format.size])
5775
+
5776
+ theme = format.theme
5777
+ color = format.color
5778
+ if !theme.nil? && theme != 0
5779
+ write_color(writer, 'theme', theme)
5780
+ elsif !color.nil? && color != 0
5781
+ color = get_palette_color(color)
5782
+ write_color(writer, 'rgb', color)
5783
+ else
5784
+ write_color(writer, 'theme', 1)
5785
+ end
5828
5786
 
5829
- writer.empty_tag('rFont', ['val', format.font])
5830
- writer.empty_tag('family', ['val', format.font_family])
5787
+ writer.empty_tag('rFont', ['val', format.font])
5788
+ writer.empty_tag('family', ['val', format.font_family])
5831
5789
 
5832
- if format.font == 'Calibri' && format.hyperlink == 0
5833
- writer.empty_tag('scheme', ['val', format.font_scheme])
5790
+ if format.font == 'Calibri' && format.hyperlink == 0
5791
+ writer.empty_tag('scheme', ['val', format.font_scheme])
5792
+ end
5834
5793
  end
5835
-
5836
- writer.end_tag('rPr')
5837
5794
  end
5838
5795
 
5839
5796
  #
@@ -5870,9 +5827,9 @@ def write_data_validations #:nodoc:
5870
5827
 
5871
5828
  attributes = ['count', @validations.size]
5872
5829
 
5873
- @writer.start_tag('dataValidations', attributes)
5874
- @validations.each { |validation| write_data_validation(validation) }
5875
- @writer.end_tag('dataValidations')
5830
+ @writer.tag_elements('dataValidations', attributes) do
5831
+ @validations.each { |validation| write_data_validation(validation) }
5832
+ end
5876
5833
  end
5877
5834
 
5878
5835
  #
@@ -5922,15 +5879,12 @@ def write_data_validation(param) #:nodoc:
5922
5879
  attributes << 'prompt' << param[:input_message] if param[:input_message]
5923
5880
  attributes << 'sqref' << sqref
5924
5881
 
5925
- @writer.start_tag('dataValidation', attributes)
5926
-
5927
- # Write the formula1 element.
5928
- write_formula_1(param[:value])
5929
-
5930
- # Write the formula2 element.
5931
- write_formula_2(param[:maximum]) if param[:maximum]
5932
-
5933
- @writer.end_tag('dataValidation')
5882
+ @writer.tag_elements('dataValidation', attributes) do
5883
+ # Write the formula1 element.
5884
+ write_formula_1(param[:value])
5885
+ # Write the formula2 element.
5886
+ write_formula_2(param[:maximum]) if param[:maximum]
5887
+ end
5934
5888
  end
5935
5889
 
5936
5890
  #
@@ -5977,11 +5931,9 @@ def write_conditional_formats #:nodoc:
5977
5931
  def write_conditional_formatting(range, params) #:nodoc:
5978
5932
  attributes = ['sqref', range]
5979
5933
 
5980
- @writer.start_tag('conditionalFormatting', attributes)
5981
-
5982
- params.each { |param| write_cf_rule(param) }
5983
-
5984
- @writer.end_tag('conditionalFormatting')
5934
+ @writer.tag_elements('conditionalFormatting', attributes) do
5935
+ params.each { |param| write_cf_rule(param) }
5936
+ end
5985
5937
  end
5986
5938
 
5987
5939
  #
@@ -5996,18 +5948,16 @@ def write_cf_rule(param) #:nodoc:
5996
5948
  attributes << 'priority' << param[:priority]
5997
5949
  attributes << 'operator' << param[:criteria]
5998
5950
 
5999
- @writer.start_tag('cfRule', attributes)
6000
-
6001
- if param[:type] == 'cellIs'
6002
- if param[:minimum] && param[:maximum]
6003
- write_formula_tag(param[:minimum])
6004
- write_formula_tag(param[:maximum])
6005
- else
6006
- write_formula_tag(param[:value])
5951
+ @writer.tag_elements('cfRule', attributes) do
5952
+ if param[:type] == 'cellIs'
5953
+ if param[:minimum] && param[:maximum]
5954
+ write_formula_tag(param[:minimum])
5955
+ write_formula_tag(param[:maximum])
5956
+ else
5957
+ write_formula_tag(param[:value])
5958
+ end
6007
5959
  end
6008
5960
  end
6009
-
6010
- @writer.end_tag('cfRule')
6011
5961
  end
6012
5962
 
6013
5963
  def store_data_to_table(cell_data) #:nodoc: