listen360-rubyXL 1.2.10.1

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.
@@ -0,0 +1,1493 @@
1
+ module RubyXL
2
+ class Worksheet < PrivateClass
3
+ include Enumerable
4
+
5
+ attr_accessor :sheet_name, :sheet_data, :cols, :merged_cells, :pane,
6
+ :validations, :sheet_view, :legacy_drawing, :extLst, :workbook, :row_styles
7
+
8
+ def initialize(workbook, sheet_name='Sheet1',sheet_data=[[nil]],cols=[], merged_cells=[])
9
+ @workbook = workbook
10
+
11
+ @sheet_name = sheet_name
12
+ @sheet_data = sheet_data
13
+ @cols = cols
14
+ @merged_cells = merged_cells
15
+ @row_styles={}
16
+ @sheet_view = {
17
+ :attributes => {
18
+ :workbookViewId => 0, :zoomScale => 100, :tabSelected => 1, :view=>'normalLayout', :zoomScaleNormal => 100
19
+ }
20
+ }
21
+ @extLst = nil
22
+ @legacy_drawing=nil
23
+ end
24
+
25
+ # allows for easier access to sheet_data
26
+ def [](row=0)
27
+ return @sheet_data[row]
28
+ end
29
+
30
+ def each
31
+ @sheet_data.each {|i| yield i}
32
+ end
33
+
34
+ #returns 2d array of just the cell values (without style or formula information)
35
+ def extract_data(args = {})
36
+ raw_values = args.delete(:raw) || false
37
+ return @sheet_data.map {|row| row.map {|c| if c.is_a?(Cell) then c.value(:raw => raw_values) else nil end}}
38
+ end
39
+
40
+ def get_table(headers=[],opts={})
41
+ validate_workbook
42
+
43
+ if !headers.is_a?(Array)
44
+ headers = [headers]
45
+ end
46
+
47
+ row_num = find_first_row_with_content(headers)
48
+
49
+ if row_num.nil?
50
+ return nil
51
+ end
52
+
53
+ table_hash = {}
54
+ table_hash[:table] = []
55
+
56
+ header_row = @sheet_data[row_num]
57
+ header_row.each_with_index do |header_cell, index|
58
+ break if index>0 && !opts[:last_header].nil? && !header_row[index-1].nil? && !header_row[index-1].value.nil? && header_row[index-1].value.to_s==opts[:last_header]
59
+ next if header_cell.nil? || header_cell.value.nil?
60
+ header = header_cell.value.to_s
61
+ table_hash[:sorted_headers]||=[]
62
+ table_hash[:sorted_headers] << header
63
+ table_hash[header] = []
64
+
65
+ original_row = row_num + 1
66
+ current_row = original_row
67
+
68
+ cell = @sheet_data[current_row][index]
69
+
70
+ # makes array of hashes in table_hash[:table]
71
+ # as well as hash of arrays in table_hash[header]
72
+ table_index = current_row - original_row
73
+ cell_test= (!cell.nil? && !cell.value.nil?)
74
+ while cell_test || !table_hash[:table][table_index].empty?
75
+
76
+ table_hash[header] << (cell_test ? cell.value : nil)
77
+
78
+ table_index = current_row - original_row
79
+
80
+ if table_hash[:table][table_index].nil?
81
+ table_hash[:table][table_index] = {}
82
+ end
83
+
84
+ table_hash[:table][table_index][header] = cell.value if cell_test
85
+
86
+ current_row += 1
87
+ if @sheet_data[current_row].nil?
88
+ cell = nil
89
+ else
90
+ cell = @sheet_data[current_row][index]
91
+ end
92
+ cell_test= (!cell.nil? && !cell.value.nil?)
93
+ end
94
+ end
95
+
96
+ return table_hash
97
+ end
98
+
99
+ #changes color of fill in (zer0 indexed) row
100
+ def change_row_fill(row=0,rgb='ffffff')
101
+ validate_workbook
102
+ validate_nonnegative(row)
103
+ increase_rows(row)
104
+ Color.validate_color(rgb)
105
+ if @row_styles[(Integer(row)+1).to_s].nil?
106
+ @row_styles[(Integer(row)+1).to_s] = {}
107
+ @row_styles[(Integer(row)+1).to_s][:style] = '0'
108
+ end
109
+
110
+ @row_styles[(Integer(row)+1).to_s][:style] = modify_fill(@workbook,Integer(@row_styles[(Integer(row)+1).to_s][:style]),rgb)
111
+
112
+ @sheet_data[Integer(row)].each do |c|
113
+ unless c.nil?
114
+ c.change_fill(rgb)
115
+ end
116
+ end
117
+ end
118
+
119
+ # Changes font name of row
120
+ def change_row_font_name(row=0, font_name='Verdana')
121
+ # Get style object
122
+ xf_id = xf_id(get_row_style(row))
123
+ # Get copy of font object with modified name
124
+ font = deep_copy(@workbook.fonts[xf_id[:fontId].to_s][:font])
125
+ font[:name][:attributes][:val] = font_name.to_s
126
+ # Update font and xf array
127
+ change_row_font(row, Worksheet::NAME, font_name, font, xf_id)
128
+ end
129
+
130
+ # Changes font size of row
131
+ def change_row_font_size(row=0, font_size=10)
132
+ # Get style object
133
+ xf_id = xf_id(get_row_style(row))
134
+ # Get copy of font object with modified size
135
+ font = deep_copy(@workbook.fonts[xf_id[:fontId].to_s][:font])
136
+ font[:sz][:attributes][:val] = font_size
137
+ # Update font and xf array
138
+ change_row_font(row, Worksheet::SIZE, font_size, font, xf_id)
139
+ end
140
+
141
+ # Changes font color of row
142
+ def change_row_font_color(row=0, font_color='000000')
143
+ Color.validate_color(font_color)
144
+ # Get style object
145
+ xf_id = xf_id(get_row_style(row))
146
+ # Get copy of font object with modified color
147
+ font = deep_copy(@workbook.fonts[xf_id[:fontId].to_s][:font])
148
+ font = modify_font_color(font, font_color.to_s)
149
+ # Update font and xf array
150
+ change_row_font(row, Worksheet::COLOR, font_color, font, xf_id)
151
+ end
152
+
153
+ # Changes font italics settings of row
154
+ def change_row_italics(row=0, italicized=false)
155
+ # Get style object
156
+ xf_id = xf_id(get_row_style(row))
157
+ # Get copy of font object with modified italics settings
158
+ font = deep_copy(@workbook.fonts[xf_id[:fontId].to_s][:font])
159
+ font = modify_font_italics(font, italicized)
160
+ # Update font and xf array
161
+ change_row_font(row, Worksheet::ITALICS, italicized, font, xf_id)
162
+ end
163
+
164
+ # Changes font bold settings of row
165
+ def change_row_bold(row=0, bolded=false)
166
+ # Get style object
167
+ xf_id = xf_id(get_row_style(row))
168
+ # Get copy of font object with modified bold settings
169
+ font = deep_copy(@workbook.fonts[xf_id[:fontId].to_s][:font])
170
+ font = modify_font_bold(font, bolded)
171
+ # Update font and xf array
172
+ change_row_font(row, Worksheet::BOLD, bolded, font, xf_id)
173
+ end
174
+
175
+ # Changes font underline settings of row
176
+ def change_row_underline(row=0, underlined=false)
177
+ # Get style object
178
+ xf_id = xf_id(get_row_style(row))
179
+ # Get copy of font object with modified underline settings
180
+ font = deep_copy(@workbook.fonts[xf_id[:fontId].to_s][:font])
181
+ font = modify_font_underline(font, underlined)
182
+ # Update font and xf array
183
+ change_row_font(row, Worksheet::UNDERLINE, underlined, font, xf_id)
184
+ end
185
+
186
+ # Changes font strikethrough settings of row
187
+ def change_row_strikethrough(row=0, struckthrough=false)
188
+ # Get style object
189
+ xf_id = xf_id(get_row_style(row))
190
+ # Get copy of font object with modified strikethrough settings
191
+ font = deep_copy(@workbook.fonts[xf_id[:fontId].to_s][:font])
192
+ font = modify_font_strikethrough(font, struckthrough)
193
+ # Update font and xf array
194
+ change_row_font(row, Worksheet::STRIKETHROUGH, struckthrough, font, xf_id)
195
+ end
196
+
197
+ def change_row_height(row=0,height=10)
198
+ validate_workbook
199
+ validate_nonnegative(row)
200
+
201
+ increase_rows(row)
202
+
203
+ if height.to_i.to_s == height.to_s
204
+ height = Integer(height)
205
+ elsif height.to_f.to_s == height.to_s
206
+ height = Float(height)
207
+ else
208
+ raise 'You must enter a number for the height'
209
+ end
210
+
211
+ if @row_styles[(row+1).to_s].nil?
212
+ @row_styles[(row+1).to_s] = {}
213
+ @row_styles[(row+1).to_s][:style] = '0'
214
+ end
215
+ @row_styles[(row+1).to_s][:height] = height
216
+ @row_styles[(row+1).to_s][:customHeight] = '1'
217
+ end
218
+
219
+ def change_row_horizontal_alignment(row=0,alignment='center')
220
+ validate_workbook
221
+ validate_nonnegative(row)
222
+ validate_horizontal_alignment(alignment)
223
+ change_row_alignment(row,alignment,true)
224
+ end
225
+
226
+ def change_row_vertical_alignment(row=0,alignment='center')
227
+ validate_workbook
228
+ validate_nonnegative(row)
229
+ validate_vertical_alignment(alignment)
230
+ change_row_alignment(row,alignment,false)
231
+ end
232
+
233
+ def change_row_border_top(row=0,weight='thin')
234
+ change_row_border(row, :top, weight)
235
+ end
236
+
237
+ def change_row_border_left(row=0,weight='thin')
238
+ change_row_border(row, :left, weight)
239
+ end
240
+
241
+ def change_row_border_right(row=0,weight='thin')
242
+ change_row_border(row, :right, weight)
243
+ end
244
+
245
+ def change_row_border_bottom(row=0,weight='thin')
246
+ change_row_border(row, :bottom, weight)
247
+ end
248
+
249
+ def change_row_border_diagonal(row=0,weight='thin')
250
+ change_row_border(row, :diagonal, weight)
251
+ end
252
+
253
+ # Changes font name of column
254
+ def change_column_font_name(col=0, font_name='Verdana')
255
+ # Get style object
256
+ xf_id = xf_id(get_col_style(col))
257
+ # Get copy of font object with modified name
258
+ font = deep_copy(@workbook.fonts[xf_id[:fontId].to_s][:font])
259
+ font[:name][:attributes][:val] = font_name.to_s
260
+ # Update font and xf array
261
+ change_column_font(col, Worksheet::NAME, font_name, font, xf_id)
262
+ end
263
+
264
+ # Changes font size of column
265
+ def change_column_font_size(col=0, font_size=10)
266
+ # Get style object
267
+ xf_id = xf_id(get_col_style(col))
268
+ # Get copy of font object with modified size
269
+ font = deep_copy(@workbook.fonts[xf_id[:fontId].to_s][:font])
270
+ font[:sz][:attributes][:val] = font_size
271
+ # Update font and xf array
272
+ change_column_font(col, Worksheet::SIZE, font_size, font, xf_id)
273
+ end
274
+
275
+ # Changes font color of column
276
+ def change_column_font_color(col=0, font_color='000000')
277
+ Color.validate_color(font_color)
278
+ # Get style object
279
+ xf_id = xf_id(get_col_style(col))
280
+ # Get copy of font object with modified color
281
+ font = deep_copy(@workbook.fonts[xf_id[:fontId].to_s][:font])
282
+ font = modify_font_color(font, font_color.to_s)
283
+ # Update font and xf array
284
+ change_column_font(col, Worksheet::COLOR, font_color, font, xf_id)
285
+ end
286
+
287
+ # Changes font italics settings of column
288
+ def change_column_italics(col=0, italicized=false)
289
+ # Get style object
290
+ xf_id = xf_id(get_col_style(col))
291
+ # Get copy of font object with modified italics settings
292
+ font = deep_copy(@workbook.fonts[xf_id[:fontId].to_s][:font])
293
+ font = modify_font_italics(font, italicized)
294
+ # Update font and xf array
295
+ change_column_font(col, Worksheet::ITALICS, italicized, font, xf_id)
296
+ end
297
+
298
+ # Changes font bold settings of column
299
+ def change_column_bold(col=0, bolded=false)
300
+ # Get style object
301
+ xf_id = xf_id(get_col_style(col))
302
+ # Get copy of font object with modified bold settings
303
+ font = deep_copy(@workbook.fonts[xf_id[:fontId].to_s][:font])
304
+ font = modify_font_bold(font, bolded)
305
+ # Update font and xf array
306
+ change_column_font(col, Worksheet::BOLD, bolded, font, xf_id)
307
+ end
308
+
309
+ # Changes font underline settings of column
310
+ def change_column_underline(col=0, underlined=false)
311
+ # Get style object
312
+ xf_id = xf_id(get_col_style(col))
313
+ # Get copy of font object with modified underline settings
314
+ font = deep_copy(@workbook.fonts[xf_id[:fontId].to_s][:font])
315
+ font = modify_font_underline(font, underlined)
316
+ # Update font and xf array
317
+ change_column_font(col, Worksheet::UNDERLINE, underlined, font, xf_id)
318
+ end
319
+
320
+ # Changes font strikethrough settings of column
321
+ def change_column_strikethrough(col=0, struckthrough=false)
322
+ # Get style object
323
+ xf_id = xf_id(get_col_style(col))
324
+ # Get copy of font object with modified strikethrough settings
325
+ font = deep_copy(@workbook.fonts[xf_id[:fontId].to_s][:font])
326
+ font = modify_font_strikethrough(font, struckthrough)
327
+ # Update font and xf array
328
+ change_column_font(col, Worksheet::STRIKETHROUGH, struckthrough, font, xf_id)
329
+ end
330
+
331
+ def change_column_width(col=0,width=13)
332
+ validate_workbook
333
+ validate_nonnegative(col)
334
+ increase_columns(col)
335
+
336
+ i = get_cols_index(col)
337
+
338
+ if width.to_i.to_s == width.to_s
339
+ width = Integer(width)
340
+ elsif width.to_f.to_s == width.to_s
341
+ width = Float(width)
342
+ else
343
+ raise 'You must enter a number for the width'
344
+ end
345
+
346
+ change_cols(i,col)
347
+ @cols.last[:attributes][:width] = width
348
+ @cols.last[:attributes][:customWidth] = '1'
349
+ end
350
+
351
+ def change_column_fill(col=0, color_index='ffffff')
352
+ validate_workbook
353
+ validate_nonnegative(col)
354
+ Color.validate_color(color_index)
355
+ increase_columns(col)
356
+
357
+ i = get_cols_index(col)
358
+
359
+ if cols[i].nil?
360
+ style_index = 0
361
+ else
362
+ #just copies any style if there is none which already exists for this col
363
+ #while it changes style/min/max, width *might* be preserved
364
+ style_index = Integer(@cols[i][:attributes][:style])
365
+ end
366
+
367
+ modify_fill(@workbook,style_index,color_index)
368
+
369
+ change_cols(i,col)
370
+
371
+ @sheet_data.each_with_index do |row,i|
372
+ c = row[Integer(col)]
373
+ unless c.nil?
374
+ c.change_fill(color_index)
375
+ end
376
+ end
377
+
378
+ end
379
+
380
+ def change_column_horizontal_alignment(col=0,alignment='center')
381
+ validate_workbook
382
+ validate_nonnegative(col)
383
+ validate_horizontal_alignment(alignment)
384
+ change_column_alignment(col,alignment,true)
385
+ end
386
+
387
+ def change_column_vertical_alignment(col=0,alignment='center')
388
+ validate_workbook
389
+ validate_nonnegative(col)
390
+ validate_vertical_alignment(alignment)
391
+ change_column_alignment(col,alignment,false)
392
+ end
393
+
394
+ def change_column_border_top(col=0,weight='thin')
395
+ change_column_border(col,:top,weight)
396
+ end
397
+
398
+ def change_column_border_left(col=0,weight='thin')
399
+ change_column_border(col,:left,weight)
400
+ end
401
+
402
+ def change_column_border_right(col=0,weight='thin')
403
+ change_column_border(col,:right,weight)
404
+ end
405
+
406
+ def change_column_border_bottom(col=0,weight='thin')
407
+ change_column_border(col,:bottom,weight)
408
+ end
409
+
410
+ def change_column_border_diagonal(col=0,weight='thin')
411
+ change_column_border(col,:diagonal,weight)
412
+ end
413
+
414
+ # merges cells within a rectangular range
415
+ def merge_cells(row1=0,col1=0,row2=0,col2=0)
416
+ validate_workbook
417
+ @merged_cells << {
418
+ :attributes => {
419
+ :ref => ''
420
+ }
421
+ }
422
+ cell1 = Cell.convert_to_cell(row1,col1)
423
+ cell2 = Cell.convert_to_cell(row2,col2)
424
+ @merged_cells.last[:attributes][:ref] = cell1+':'+cell2
425
+ end
426
+
427
+ def add_cell(row=0, column=0, data='', formula=nil,overwrite=true)
428
+ validate_workbook
429
+ validate_nonnegative(row)
430
+ validate_nonnegative(column)
431
+
432
+ unless @sheet_data.size > row && @sheet_data[row].size > column
433
+ increase_columns(column)
434
+ increase_rows(row)
435
+ end
436
+
437
+ datatype = 'str'
438
+ unless formula.nil?
439
+ datatype = ''
440
+ end
441
+ if overwrite || @sheet_data[row][column].nil?
442
+ @sheet_data[row][column] = Cell.new(self,row,column,data,formula,datatype)
443
+
444
+ if (data.is_a?Integer) || (data.is_a?Float)
445
+ @sheet_data[row][column].datatype = ''
446
+ end
447
+ col = @cols[get_cols_index(column)]
448
+
449
+ if @row_styles[(row+1).to_s] != nil
450
+ @sheet_data[row][column].style_index = @row_styles[(row+1).to_s][:style]
451
+ elsif col != nil
452
+ @sheet_data[row][column].style_index = col[:attributes][:style]
453
+ end
454
+ end
455
+
456
+ add_cell_style(row,column)
457
+
458
+ return @sheet_data[row][column]
459
+ end
460
+
461
+ def add_cell_obj(cell, overwrite=true)
462
+ validate_workbook
463
+
464
+ if cell.nil?
465
+ return cell
466
+ end
467
+
468
+ row = cell.row
469
+ column = cell.column
470
+
471
+ validate_nonnegative(row)
472
+ validate_nonnegative(column)
473
+
474
+ unless @sheet_data.size > row && @sheet_data[row].size > column
475
+ increase_columns(column)
476
+ increase_rows(row)
477
+ end
478
+ if overwrite || @sheet_data[row][column].nil?
479
+ @sheet_data[row][column] = cell
480
+ end
481
+
482
+ add_cell_style(row,column)
483
+
484
+ return @sheet_data[row][column]
485
+ end
486
+
487
+ def delete_row(row_index=0)
488
+ validate_workbook
489
+ validate_nonnegative(row_index)
490
+
491
+ if row_index >= @sheet_data.size
492
+ return nil
493
+ end
494
+
495
+ deleted = @sheet_data.delete_at(row_index)
496
+ row_num = row_index+1
497
+
498
+ row_num.upto(@sheet_data.size) do |index|
499
+ @row_styles[(index-1).to_s] = deep_copy(@row_styles[index.to_s])
500
+ end
501
+ @row_styles.delete(@sheet_data.size.to_s)
502
+
503
+ #change row styles
504
+ # raise row_styles.inspect
505
+
506
+ #change cell row numbers
507
+ (row_index...(@sheet_data.size-1)).each do |index|
508
+ @sheet_data[index].map {|c| c.row -= 1 if c}
509
+ end
510
+
511
+ return deleted
512
+ end
513
+
514
+ #inserts row at row_index, pushes down, copies style from below (row previously at that index)
515
+ #USE OF THIS METHOD will break formulas which reference cells which are being "pushed down"
516
+ def insert_row(row_index=0)
517
+ validate_workbook
518
+ validate_nonnegative(row_index)
519
+
520
+ increase_rows(row_index)
521
+
522
+ @sheet_data.insert(row_index,Array.new(@sheet_data[row_index].size))
523
+
524
+ row_num = row_index+1
525
+
526
+ #copy cell styles from row above, (or below if first row)
527
+ @sheet_data[row_index].each_index do |i|
528
+ if row_index > 0
529
+ old_cell = @sheet_data[row_index-1][i]
530
+ else
531
+ old_cell = @sheet_data[row_index+1][i]
532
+ end
533
+
534
+ unless old_cell.nil?
535
+ #only add cell if style exists, not copying content
536
+
537
+ if @row_styles[(row_num+1).to_s].nil?
538
+ @row_styles[(row_num+1).to_s] = {:style=>0}
539
+ end
540
+ if old_cell.style_index != 0 && old_cell.style_index.to_s != @row_styles[(row_num+1).to_s][:style].to_s
541
+ c = Cell.new(self,row_index,i)
542
+ c.style_index = old_cell.style_index
543
+ @sheet_data[row_index][i] = c
544
+ end
545
+ end
546
+ end
547
+
548
+ #copy row styles from row above, (or below if first row)
549
+ (@row_styles.size+1).downto(row_num+1) do |i|
550
+ @row_styles[i.to_s] = @row_styles[(i-1).to_s]
551
+ end
552
+ if row_index > 0
553
+ @row_styles[row_num.to_s] = @row_styles[(row_num-1).to_s]
554
+ else
555
+ @row_styles[row_num.to_s] = nil#@row_styles[(row_num+1).to_s]
556
+ end
557
+
558
+ #update row value for all rows below
559
+ (row_index+1).upto(@sheet_data.size-1) do |i|
560
+ row = @sheet_data[i]
561
+ row.each do |c|
562
+ unless c.nil?
563
+ c.row += 1
564
+ end
565
+ end
566
+ end
567
+
568
+ return @sheet_data[row_index]
569
+ end
570
+
571
+ def delete_column(col_index=0)
572
+ validate_workbook
573
+ validate_nonnegative(col_index)
574
+
575
+ if col_index >= @sheet_data[0].size
576
+ return nil
577
+ end
578
+
579
+ #delete column
580
+ @sheet_data.map {|r| r.delete_at(col_index)}
581
+
582
+ #change column numbers for cells to right of deleted column
583
+ @sheet_data.each_with_index do |row,row_index|
584
+ (col_index...(row.size)).each do |index|
585
+ if @sheet_data[row_index][index].is_a?(Cell)
586
+ @sheet_data[row_index][index].column -= 1
587
+ end
588
+ end
589
+ end
590
+
591
+ #shift column styles
592
+ #shift col styles 'left'
593
+ @cols.each do |col|
594
+ if Integer(col[:attributes][:min]) >= col_index
595
+ col[:attributes][:min] = (Integer(col[:attributes][:min]) - 1).to_s
596
+ end
597
+ if Integer(col[:attributes][:max]) >= col_index
598
+ col[:attributes][:max] = (Integer(col[:attributes][:max]) - 1).to_s
599
+ end
600
+ end
601
+ end
602
+
603
+ # inserts column at col_index, pushes everything right, takes styles from column to left
604
+ # USE OF THIS METHOD will break formulas which reference cells which are being "pushed down"
605
+ def insert_column(col_index=0)
606
+ validate_workbook
607
+ validate_nonnegative(col_index)
608
+ increase_columns(col_index)
609
+
610
+ old_index = col_index > 0 ? col_index-1 : col_index+1
611
+ old_col = @cols[get_cols_index(old_index)]
612
+ if old_index == 1
613
+ old_col = nil
614
+ end
615
+
616
+ #go through each cell in column
617
+ @sheet_data.each_with_index do |r,i|
618
+ #insert "column" in each row
619
+ r.insert(col_index, nil)
620
+
621
+ #copy styles over to each cell
622
+ old_cell = r[old_index]
623
+ unless old_cell.nil?
624
+ #only add cell if style exists, not copying content
625
+ if old_cell.style_index != 0
626
+ if !old_col.nil? && old_cell.style_index.to_s != old_col[:attributes][:style].to_s
627
+ c = Cell.new(self,i,col_index)
628
+ c.style_index = old_cell.style_index
629
+ @sheet_data[i][col_index] = c
630
+ end
631
+ end
632
+ end
633
+ end
634
+
635
+ #copy over column-level styles
636
+ new_col = change_cols(get_cols_index(old_index),old_index)
637
+ @cols[-1] = deep_copy(old_col)#-1 = last
638
+
639
+ new_col = @cols.last
640
+ if @cols.last.nil?
641
+ @cols.pop
642
+ end
643
+
644
+ #shift col styles 'right'
645
+ @cols.each do |col|
646
+ if Integer(col[:attributes][:min]) > col_index
647
+ col[:attributes][:min] = (1 + Integer(col[:attributes][:min])).to_s
648
+ end
649
+ if Integer(col[:attributes][:max]) > col_index
650
+ col[:attributes][:max] = (1 + Integer(col[:attributes][:max])).to_s
651
+ end
652
+ end
653
+ unless new_col.nil?
654
+ new_col[:attributes][:min] = (1 + Integer(new_col[:attributes][:min])).to_s
655
+ new_col[:attributes][:max] = (1 + Integer(new_col[:attributes][:max])).to_s
656
+ end
657
+
658
+ #update column numbers
659
+ @sheet_data.each do |row|
660
+ (col_index+1).upto(row.size) do |j|
661
+ unless row[j].nil?
662
+ row[j].column += 1
663
+ end
664
+ end
665
+ end
666
+ end
667
+
668
+ def insert_cell(row=0,col=0,data=nil,formula=nil,shift=nil)
669
+ validate_workbook
670
+ validate_nonnegative(row)
671
+ validate_nonnegative(col)
672
+
673
+ increase_rows(row)
674
+ increase_columns(col)
675
+
676
+ if shift && shift != :right && shift != :down
677
+ raise 'invalid shift option'
678
+ end
679
+
680
+ if shift == :right
681
+ @sheet_data[row].insert(col,nil)
682
+ (row...(@sheet_data[row].size)).each do |index|
683
+ if @sheet_data[row][index].is_a?(Cell)
684
+ @sheet_data[row][index].column += 1
685
+ end
686
+ end
687
+ elsif shift == :down
688
+ @sheet_data << Array.new(@sheet_data[row].size)
689
+ (@sheet_data.size-1).downto(row+1) do |index|
690
+ @sheet_data[index][col] = @sheet_data[index-1][col]
691
+ end
692
+ end
693
+
694
+ return add_cell(row,col,data,formula)
695
+ end
696
+
697
+ # by default, only sets cell to nil
698
+ # if :left is specified, method will shift row contents to the right of the deleted cell to the left
699
+ # if :up is specified, method will shift column contents below the deleted cell upward
700
+ def delete_cell(row=0,col=0,shift=nil)
701
+ validate_workbook
702
+ validate_nonnegative(row)
703
+ validate_nonnegative(col)
704
+ if @sheet_data.size <= row || @sheet_data[row].size <= col
705
+ return nil
706
+ end
707
+
708
+ cell = @sheet_data[row][col]
709
+ @sheet_data[row][col]=nil
710
+
711
+ if shift && shift != :left && shift != :up
712
+ raise 'invalid shift option'
713
+ end
714
+
715
+ if shift == :left
716
+ @sheet_data[row].delete_at(col)
717
+ @sheet_data[row] << nil
718
+ (col...(@sheet_data[row].size)).each do |index|
719
+ if @sheet_data[row][index].is_a?(Cell)
720
+ @sheet_data[row][index].column -= 1
721
+ end
722
+ end
723
+ elsif shift == :up
724
+ (row...(@sheet_data.size-1)).each do |index|
725
+ @sheet_data[index][col] = @sheet_data[index+1][col]
726
+ if @sheet_data[index][col].is_a?(Cell)
727
+ @sheet_data[index][col].row -= 1
728
+ end
729
+ end
730
+ if @sheet_data.last[col].is_a?(Cell)
731
+ @sheet_data.last[col].row -= 1
732
+ end
733
+ end
734
+
735
+ return cell
736
+ end
737
+
738
+ def get_row_fill(row=0)
739
+ validate_workbook
740
+ validate_nonnegative(row)
741
+
742
+ if @sheet_data.size <= row
743
+ return nil
744
+ end
745
+
746
+ if @row_styles[(row+1).to_s].nil?
747
+ return "ffffff" #default, white
748
+ end
749
+
750
+ xf = xf_attr_row(row)
751
+
752
+ return @workbook.get_fill_color(xf)
753
+ end
754
+
755
+ def get_row_font_name(row=0)
756
+ validate_workbook
757
+ validate_nonnegative(row)
758
+
759
+ if @sheet_data.size <= row
760
+ return nil
761
+ end
762
+
763
+ if @row_styles[(row+1).to_s].nil?
764
+ return 'Verdana'
765
+ end
766
+
767
+ xf = xf_attr_row(row)
768
+
769
+ return @workbook.fonts[xf[:fontId].to_s][:font][:name][:attributes][:val]
770
+ end
771
+
772
+ def get_row_font_size(row=0)
773
+ validate_workbook
774
+ validate_nonnegative(row)
775
+
776
+ if @sheet_data.size <= row
777
+ return nil
778
+ end
779
+
780
+ if @row_styles[(row+1).to_s].nil?
781
+ return '10'
782
+ end
783
+
784
+ xf = xf_attr_row(row)
785
+
786
+ return @workbook.fonts[xf[:fontId].to_s][:font][:sz][:attributes][:val]
787
+ end
788
+
789
+ def get_row_font_color(row=0)
790
+ validate_workbook
791
+ validate_nonnegative(row)
792
+
793
+ if @sheet_data.size <= row
794
+ return nil
795
+ end
796
+
797
+ if @row_styles[(row+1).to_s].nil?
798
+ return '000000'
799
+ end
800
+
801
+ xf = xf_attr_row(row)
802
+
803
+ color = @workbook.fonts[xf[:fontId].to_s][:font][:color]
804
+
805
+ if color.nil? || color[:attributes].nil? || color[:attributes][:rgb].nil?
806
+ return '000000'
807
+ end
808
+
809
+ return color[:attributes][:rgb]
810
+ end
811
+
812
+ def is_row_italicized(row=0)
813
+ return get_row_bool(row,:i)
814
+ end
815
+
816
+ def is_row_bolded(row=0)
817
+ return get_row_bool(row,:b)
818
+ end
819
+
820
+ def is_row_underlined(row=0)
821
+ return get_row_bool(row,:u)
822
+ end
823
+
824
+ def is_row_struckthrough(row=0)
825
+ return get_row_bool(row,:strike)
826
+ end
827
+
828
+
829
+ def get_row_height(row=0)
830
+ validate_workbook
831
+ validate_nonnegative(row)
832
+
833
+ if @sheet_data.size <= row
834
+ return nil
835
+ end
836
+
837
+ if @row_styles[(row+1).to_s].nil?
838
+ return 13
839
+ else
840
+ @row_styles[(row+1).to_s][:height]
841
+ end
842
+ end
843
+
844
+ def get_row_horizontal_alignment(row=0)
845
+ return get_row_alignment(row,true)
846
+ end
847
+
848
+ def get_row_vertical_alignment(row=0)
849
+ return get_row_alignment(row,false)
850
+ end
851
+
852
+ def get_row_border_top(row=0)
853
+ return get_row_border(row,:top)
854
+ end
855
+
856
+ def get_row_border_left(row=0)
857
+ return get_row_border(row,:left)
858
+ end
859
+
860
+ def get_row_border_right(row=0)
861
+ return get_row_border(row,:right)
862
+ end
863
+
864
+ def get_row_border_bottom(row=0)
865
+ return get_row_border(row,:bottom)
866
+ end
867
+
868
+ def get_row_border_diagonal(row=0)
869
+ return get_row_border(row,:diagonal)
870
+ end
871
+
872
+ def get_column_font_name(col=0)
873
+ validate_workbook
874
+ validate_nonnegative(col)
875
+
876
+ if @sheet_data[0].size <= col
877
+ return nil
878
+ end
879
+
880
+ style_index = get_cols_style_index(col)
881
+
882
+ return @workbook.fonts[font_id( style_index ).to_s][:font][:name][:attributes][:val]
883
+ end
884
+
885
+ def get_column_font_size(col=0)
886
+ validate_workbook
887
+ validate_nonnegative(col)
888
+
889
+ if @sheet_data[0].size <= col
890
+ return nil
891
+ end
892
+
893
+ style_index = get_cols_style_index(col)
894
+
895
+ return @workbook.fonts[font_id( style_index ).to_s][:font][:sz][:attributes][:val]
896
+ end
897
+
898
+ def get_column_font_color(col=0)
899
+ validate_workbook
900
+ validate_nonnegative(col)
901
+
902
+ if @sheet_data[0].size <= col
903
+ return nil
904
+ end
905
+
906
+ style_index = get_cols_style_index(col)
907
+
908
+ font = @workbook.fonts[font_id( style_index ).to_s][:font]
909
+
910
+ if font[:color].nil? || font[:color][:attributes].nil? || font[:color][:attributes][:rgb].nil?
911
+ return '000000'
912
+ end
913
+
914
+ return font[:color][:attributes][:rgb]
915
+
916
+ end
917
+
918
+ def is_column_italicized(col=0)
919
+ get_column_bool(col,:i)
920
+ end
921
+
922
+ def is_column_bolded(col=0)
923
+ get_column_bool(col,:b)
924
+ end
925
+
926
+ def is_column_underlined(col=0)
927
+ get_column_bool(col,:u)
928
+ end
929
+
930
+ def is_column_struckthrough(col=0)
931
+ get_column_bool(col,:strike)
932
+ end
933
+
934
+ def get_column_width(col=0)
935
+ validate_workbook
936
+ validate_nonnegative(col)
937
+
938
+ if @sheet_data[0].size <= col
939
+ return nil
940
+ end
941
+
942
+ cols_index = get_cols_index(col)
943
+
944
+ if @cols[cols_index].nil? || @cols[cols_index][:attributes].nil? || @cols[cols_index][:attributes][:width].to_s == ''
945
+ return 10
946
+ end
947
+
948
+ return @cols[cols_index][:attributes][:width]
949
+ end
950
+
951
+ def get_column_fill(col=0)
952
+ validate_workbook
953
+ validate_nonnegative(col)
954
+
955
+ if @sheet_data[0].size <= col
956
+ return nil
957
+ end
958
+
959
+ style_index = get_cols_style_index(col)
960
+
961
+ if style_index == 0
962
+ return "ffffff" #default, white
963
+ end
964
+
965
+ return @workbook.get_fill_color(@workbook.cell_xfs[:xf][style_index][:attributes])
966
+ end
967
+
968
+ def get_column_horizontal_alignment(col=0)
969
+ get_column_alignment(col, :horizontal)
970
+ end
971
+
972
+ def get_column_vertical_alignment(col=0)
973
+ get_column_alignment(col, :vertical)
974
+ end
975
+
976
+ def get_column_border_top(col=0)
977
+ return get_column_border(col,:top)
978
+ end
979
+
980
+ def get_column_border_left(col=0)
981
+ return get_column_border(col,:left)
982
+ end
983
+
984
+ def get_column_border_right(col=0)
985
+ return get_column_border(col,:right)
986
+ end
987
+
988
+ def get_column_border_bottom(col=0)
989
+ return get_column_border(col,:bottom)
990
+ end
991
+
992
+ def get_column_border_diagonal(col=0)
993
+ return get_column_border(col,:diagonal)
994
+ end
995
+
996
+
997
+ private
998
+
999
+ Worksheet::NAME = 0
1000
+ Worksheet::SIZE = 1
1001
+ Worksheet::COLOR = 2
1002
+ Worksheet::ITALICS = 3
1003
+ Worksheet::BOLD = 4
1004
+ Worksheet::UNDERLINE = 5
1005
+ Worksheet::STRIKETHROUGH = 6
1006
+
1007
+ #row_styles is assumed to not be nil at specified row
1008
+ def xf_attr_row(row)
1009
+ row_style = @row_styles[(row+1).to_s][:style]
1010
+ return @workbook.get_style_attributes(@workbook.get_style(row_style))
1011
+ end
1012
+
1013
+ def xf_attr_col(column)
1014
+ col_style = @cols[get_cols_index(column)][:style]
1015
+ return @workbook.get_style_attributes(@workbook.get_style(Integer(col_style)))
1016
+ end
1017
+
1018
+ def get_row_bool(row,property)
1019
+ validate_workbook
1020
+ validate_nonnegative(row)
1021
+
1022
+ if @sheet_data.size <= row
1023
+ return nil
1024
+ end
1025
+
1026
+ if @row_styles[(row+1).to_s].nil?
1027
+ return false
1028
+ end
1029
+
1030
+ xf = xf_attr_row(row)
1031
+
1032
+ return !@workbook.fonts[xf[:fontId].to_s][:font][property].nil?
1033
+ end
1034
+
1035
+ def get_row_alignment(row,is_horizontal)
1036
+ validate_workbook
1037
+ validate_nonnegative(row)
1038
+
1039
+ if @sheet_data.size <= row || @row_styles[(row+1).to_s].nil?
1040
+ return nil
1041
+ end
1042
+
1043
+ xf_obj = @workbook.get_style(@row_styles[(row+1).to_s][:style])
1044
+
1045
+ if xf_obj[:alignment].nil? || xf_obj[:alignment][:attributes].nil?
1046
+ return nil
1047
+ end
1048
+
1049
+ if is_horizontal
1050
+ return xf_obj[:alignment][:attributes][:horizontal].to_s
1051
+ else
1052
+ return xf_obj[:alignment][:attributes][:vertical].to_s
1053
+ end
1054
+ end
1055
+
1056
+ def get_row_border(row,border_direction)
1057
+ validate_workbook
1058
+ validate_nonnegative(row)
1059
+
1060
+ if @sheet_data.size <= row || @row_styles[(row+1).to_s].nil?
1061
+ return nil
1062
+ end
1063
+
1064
+ if @workbook.borders[xf_attr_row(row)[:borderId]].nil? && !@workbook.borders[xf_attr_row(row)[:borderId].to_s].nil?
1065
+ @workbook.borders[xf_attr_row(row)[:borderId]] = deep_copy(@workbook.borders[xf_attr_row(row)[:borderId].to_s])
1066
+ @workbook.borders.delete(xf_attr_row(row)[:borderId].to_s)
1067
+ end
1068
+
1069
+ if @workbook.borders[xf_attr_row(row)[:borderId]][:border][border_direction][:attributes].nil?
1070
+ return nil
1071
+ end
1072
+
1073
+ return @workbook.borders[xf_attr_row(row)[:borderId]][:border][border_direction][:attributes][:style]
1074
+ end
1075
+
1076
+ def get_column_bool(col,property)
1077
+ validate_workbook
1078
+ validate_nonnegative(col)
1079
+
1080
+ if @sheet_data[0].size <= col
1081
+ return nil
1082
+ end
1083
+
1084
+ style_index = get_cols_style_index(col)
1085
+
1086
+ return !@workbook.fonts[font_id( style_index ).to_s][:font][property].nil?
1087
+ end
1088
+
1089
+ def get_column_alignment(col, type)
1090
+ validate_workbook
1091
+ validate_nonnegative(col)
1092
+
1093
+ if @sheet_data[0].size <= col
1094
+ return nil
1095
+ end
1096
+
1097
+ style_index = get_cols_style_index(col)
1098
+
1099
+ xf_obj = @workbook.get_style(style_index)
1100
+ if xf_obj[:alignment].nil?
1101
+ return nil
1102
+ end
1103
+
1104
+ return xf_obj[:alignment][:attributes][type]
1105
+ end
1106
+
1107
+ def get_column_border(col, border_direction)
1108
+ validate_workbook
1109
+ validate_nonnegative(col)
1110
+ style_index = get_cols_style_index(col)
1111
+ xf = @workbook.get_style_attributes(@workbook.get_style(style_index))
1112
+
1113
+ if @sheet_data[0].size <= col
1114
+ return nil
1115
+ end
1116
+
1117
+ if @workbook.borders[xf[:borderId]].nil? && !@workbook.borders[xf[:borderId].to_s].nil?
1118
+ @workbook.borders[xf[:borderId]] = deep_copy(@workbook.borders[xf[:borderId].to_s])
1119
+ @workbook.borders.delete(xf[:borderId].to_s)
1120
+ end
1121
+
1122
+ if @workbook.borders[xf[:borderId]][:border][border_direction][:attributes].nil?
1123
+ return nil
1124
+ end
1125
+
1126
+ return @workbook.borders[xf[:borderId]][:border][border_direction][:attributes][:style]
1127
+ end
1128
+
1129
+ def deep_copy(hash)
1130
+ Marshal.load(Marshal.dump(hash))
1131
+ end
1132
+
1133
+ #validates Workbook, ensures that this worksheet is in @workbook
1134
+ def validate_workbook()
1135
+ unless @workbook.nil? || @workbook.worksheets.nil?
1136
+ @workbook.worksheets.each do |sheet|
1137
+ if sheet == self
1138
+ return
1139
+ end
1140
+ end
1141
+ end
1142
+ raise "This worksheet #{self} is not in workbook #{@workbook}"
1143
+ end
1144
+
1145
+ # because cols is not ordered by col num, this actually gets
1146
+ # the index in the array based on which column is actually being asked for by the user
1147
+ def get_cols_index(col)
1148
+ i = @cols.size - 1
1149
+
1150
+ @cols.reverse_each do |column|
1151
+ if col >= (Integer(column[:attributes][:min])-1)
1152
+ if col <= (Integer(column[:attributes][:max])-1)
1153
+ break
1154
+ end
1155
+ end
1156
+ i -= 1
1157
+ end
1158
+ if i < 0
1159
+ i = @cols.size #effectively nil
1160
+ end
1161
+ i
1162
+ end
1163
+
1164
+ def get_cols_style_index(col)
1165
+ cols_index = get_cols_index(col)
1166
+ if cols_index == @cols.size
1167
+ return 0
1168
+ end
1169
+ return Integer(@cols[cols_index][:attributes][:style])
1170
+ end
1171
+
1172
+ #change cols array
1173
+ def change_cols(i,col_index)
1174
+ style = '0'
1175
+ if @cols[i].nil?
1176
+ @cols << {:attributes=>{:style=>nil,:min=>nil,:max=>nil,:width=>nil,:customWidth=>nil}}
1177
+ else
1178
+ @cols << deep_copy(@cols[i])
1179
+ style = @cols[i][:attributes][:style]
1180
+ end
1181
+ @cols.last[:attributes][:style] = style
1182
+ @cols.last[:attributes][:min] = (Integer(col_index)+1).to_s
1183
+ @cols.last[:attributes][:max] = (Integer(col_index)+1).to_s
1184
+ @cols.last[:attributes][:width] = '10'
1185
+ @cols.last[:attributes][:customWidth] = '0'
1186
+ end
1187
+
1188
+ # Helper method to update the row styles array
1189
+ # change_type - NAME or SIZE or COLOR etc
1190
+ # main method to change font, called from each separate font mutator method
1191
+ def change_row_font(row, change_type, arg, font, xf_id)
1192
+ validate_workbook
1193
+ validate_nonnegative(row)
1194
+ increase_rows(row)
1195
+
1196
+ # Modify font array and retrieve new font id
1197
+ font_id = modify_font(@workbook, font, xf_id[:fontId].to_s)
1198
+ # Get copy of xf object with modified font id
1199
+ xf = deep_copy(xf_id)
1200
+ xf[:fontId] = Integer(font_id)
1201
+ # Modify xf array and retrieve new xf id
1202
+ @row_styles[(row+1).to_s][:style] = modify_xf(@workbook, xf)
1203
+
1204
+ if @sheet_data[row].nil?
1205
+ @sheet_data[row] = []
1206
+ end
1207
+
1208
+ @sheet_data[Integer(row)].each do |c|
1209
+ unless c.nil?
1210
+ font_switch(c, change_type, arg)
1211
+ end
1212
+ end
1213
+ end
1214
+
1215
+ # Helper method to update the fonts and cell styles array
1216
+ # main method to change font, called from each separate font mutator method
1217
+ def change_column_font(col, change_type, arg, font, xf_id)
1218
+ validate_workbook
1219
+ validate_nonnegative(col)
1220
+ increase_columns(col)
1221
+
1222
+ i = get_cols_index(col)
1223
+
1224
+ # Modify font array and retrieve new font id
1225
+ font_id = modify_font(@workbook, font, xf_id[:fontId].to_s)
1226
+ # Get copy of xf object with modified font id
1227
+ xf = deep_copy(xf_id)
1228
+ xf[:fontId] = Integer(font_id)
1229
+ # Modify xf array and retrieve new xf id
1230
+ modify_xf(@workbook, xf)
1231
+
1232
+ change_cols(i, col)
1233
+
1234
+ @sheet_data.each_with_index do |row, i|
1235
+ c = row[col]
1236
+ unless c.nil?
1237
+ font_switch(c, change_type, arg)
1238
+ end
1239
+ end
1240
+ end
1241
+
1242
+ #performs correct modification based on what type of change_type is specified
1243
+ def font_switch(c,change_type,arg)
1244
+ case change_type
1245
+ when Worksheet::NAME
1246
+ unless arg.is_a?String
1247
+ raise 'Not a String'
1248
+ end
1249
+ c.change_font_name(arg)
1250
+ when Worksheet::SIZE
1251
+ unless arg.is_a?(Integer) || arg.is_a?(Float)
1252
+ raise 'Not a Number'
1253
+ end
1254
+ c.change_font_size(arg)
1255
+ when Worksheet::COLOR
1256
+ Color.validate_color(arg)
1257
+ c.change_font_color(arg)
1258
+ when Worksheet::ITALICS
1259
+ unless arg == !!arg
1260
+ raise 'Not a boolean'
1261
+ end
1262
+ c.change_font_italics(arg)
1263
+ when Worksheet::BOLD
1264
+ unless arg == !!arg
1265
+ raise 'Not a boolean'
1266
+ end
1267
+ c.change_font_bold(arg)
1268
+ when Worksheet::UNDERLINE
1269
+ unless arg == !!arg
1270
+ raise 'Not a boolean'
1271
+ end
1272
+ c.change_font_underline(arg)
1273
+ when Worksheet::STRIKETHROUGH
1274
+ unless arg == !!arg
1275
+ raise 'Not a boolean'
1276
+ end
1277
+ c.change_font_strikethrough(arg)
1278
+ else
1279
+ raise 'Invalid change_type'
1280
+ end
1281
+ end
1282
+
1283
+ #increases number of rows until the array at index row is not nil
1284
+ def increase_rows(row)
1285
+ @sheet_data.size.upto(row) do
1286
+ @sheet_data << Array.new(@sheet_data[0].size)
1287
+ end
1288
+ end
1289
+
1290
+ #increases number of columns until the array at index column is not nil
1291
+ def increase_columns(column)
1292
+ @sheet_data.each do |r|
1293
+ r.size.upto(column) do
1294
+ r << nil
1295
+ end
1296
+ end
1297
+ end
1298
+
1299
+ # Helper method to get the font id for a style index
1300
+ def font_id(style_index)
1301
+ xf_id(style_index)[:fontId]
1302
+ end
1303
+
1304
+ # Helper method to get the style attributes for a style index
1305
+ def xf_id(style_index)
1306
+ @workbook.get_style_attributes(@workbook.get_style(style_index))
1307
+ end
1308
+
1309
+ # Helper method to get the style index for a row
1310
+ def get_row_style(row)
1311
+ if @row_styles[(row+1).to_s].nil?
1312
+ @row_styles[(row+1).to_s] = {}
1313
+ @row_styles[(row+1).to_s][:style] = '0'
1314
+ @workbook.fonts['0'][:count] += 1
1315
+ end
1316
+ return @row_styles[(row+1).to_s][:style]
1317
+ end
1318
+
1319
+ # Helper method to get the style index for a column
1320
+ def get_col_style(col)
1321
+ i = get_cols_index(col)
1322
+ if @cols[i].nil?
1323
+ @workbook.fonts['0'][:count] += 1
1324
+ return 0
1325
+ else
1326
+ return Integer(@cols[i][:attributes][:style])
1327
+ end
1328
+ end
1329
+
1330
+ def change_row_alignment(row,alignment,is_horizontal)
1331
+ validate_workbook
1332
+ validate_nonnegative(row)
1333
+
1334
+ increase_rows(row)
1335
+
1336
+ if @row_styles[(row+1).to_s].nil?
1337
+ @row_styles[(row+1).to_s] = {}
1338
+ @row_styles[(row+1).to_s][:style] = '0'
1339
+ end
1340
+
1341
+ @row_styles[(row+1).to_s][:style] =
1342
+ modify_alignment(@workbook,@row_styles[(row+1).to_s][:style],is_horizontal,alignment)
1343
+
1344
+ @sheet_data[row].each do |c|
1345
+ unless c.nil?
1346
+ if is_horizontal
1347
+ c.change_horizontal_alignment(alignment)
1348
+ else
1349
+ c.change_vertical_alignment(alignment)
1350
+ end
1351
+ end
1352
+ end
1353
+ end
1354
+
1355
+ def change_column_alignment(col,alignment,is_horizontal)
1356
+ validate_workbook
1357
+ validate_nonnegative(col)
1358
+
1359
+ increase_columns(col)
1360
+
1361
+ i = get_cols_index(col)
1362
+
1363
+ if @cols[i].nil?
1364
+ style_index = 0
1365
+ else
1366
+ style_index = Integer(@cols[i][:attributes][:style])
1367
+ end
1368
+
1369
+ style_index = modify_alignment(@workbook,style_index,is_horizontal,alignment)
1370
+
1371
+ change_cols(i,col)
1372
+
1373
+ @cols[i][:attributes][:style] = style_index
1374
+
1375
+ @sheet_data.each_with_index do |row,i|
1376
+ c = row[Integer(col)]
1377
+ unless c.nil?
1378
+ if is_horizontal
1379
+ c.change_horizontal_alignment(alignment)
1380
+ else
1381
+ c.change_vertical_alignment(alignment)
1382
+ end
1383
+ end
1384
+ end
1385
+ end
1386
+
1387
+ def change_row_border(row, direction, weight)
1388
+ validate_workbook
1389
+ validate_nonnegative(row)
1390
+ validate_border(weight)
1391
+ increase_rows(row)
1392
+
1393
+ if @row_styles[(row+1).to_s].nil?
1394
+ @row_styles[(row+1).to_s]= {}
1395
+ @row_styles[(row+1).to_s][:style] = '0'
1396
+ end
1397
+ @row_styles[(row+1).to_s][:style] = modify_border(@workbook,@row_styles[(row+1).to_s][:style])
1398
+
1399
+ if @workbook.borders[xf_attr_row(row)[:borderId]][:border][direction][:attributes].nil?
1400
+ @workbook.borders[xf_attr_row(row)[:borderId]][:border][direction][:attributes] = { :style => nil }
1401
+ end
1402
+ @workbook.borders[xf_attr_row(row)[:borderId]][:border][direction][:attributes][:style] = weight.to_s
1403
+
1404
+ @sheet_data[row].each do |c|
1405
+ unless c.nil?
1406
+ case direction
1407
+ when :top
1408
+ c.change_border_top(weight)
1409
+ when :left
1410
+ c.change_border_left(weight)
1411
+ when :right
1412
+ c.change_border_right(weight)
1413
+ when :bottom
1414
+ c.change_border_bottom(weight)
1415
+ when :diagonal
1416
+ c.change_border_diagonal(weight)
1417
+ else
1418
+ raise 'invalid direction'
1419
+ end
1420
+ end
1421
+ end
1422
+ end
1423
+
1424
+ def change_column_border(col,direction,weight)
1425
+ validate_workbook
1426
+ validate_nonnegative(col)
1427
+ validate_border(weight)
1428
+
1429
+ increase_columns(col)
1430
+
1431
+ i = get_cols_index(col)
1432
+ if @cols[i].nil?
1433
+ style_index = 0
1434
+ else
1435
+ style_index = Integer(@cols[i][:attributes][:style])
1436
+ end
1437
+
1438
+ style_index = modify_border(@workbook,style_index)
1439
+
1440
+ change_cols(i,col)
1441
+
1442
+ xf = @workbook.get_style_attributes(@workbook.get_style(style_index))
1443
+
1444
+ if @workbook.borders[xf[:borderId]][:border][direction][:attributes].nil?
1445
+ @workbook.borders[xf[:borderId]][:border][direction][:attributes] = { :style => nil }
1446
+ end
1447
+ @workbook.borders[xf[:borderId]][:border][direction][:attributes][:style] = weight.to_s
1448
+
1449
+ @sheet_data.each_with_index do |row,i|
1450
+ c = row[Integer(col)]
1451
+ unless c.nil?
1452
+ case direction
1453
+ when :top
1454
+ c.change_border_top(weight)
1455
+ when :left
1456
+ c.change_border_left(weight)
1457
+ when :right
1458
+ c.change_border_right(weight)
1459
+ when :bottom
1460
+ c.change_border_bottom(weight)
1461
+ when :diagonal
1462
+ c.change_border_diagonal(weight)
1463
+ else
1464
+ raise 'invalid direction'
1465
+ end
1466
+ end
1467
+ end
1468
+ end
1469
+
1470
+ def add_cell_style(row,column)
1471
+ xf = @workbook.get_style_attributes(@workbook.get_style(@sheet_data[row][column].style_index))
1472
+ @workbook.fonts[xf[:fontId].to_s][:count] += 1
1473
+ @workbook.fills[xf[:fillId].to_s][:count] += 1
1474
+ @workbook.borders[xf[:borderId].to_s][:count] += 1
1475
+ end
1476
+
1477
+ # finds first row which contains at least all strings in cells_content
1478
+ def find_first_row_with_content(cells_content)
1479
+ validate_workbook
1480
+ index = nil
1481
+
1482
+ @sheet_data.each_with_index do |row, index|
1483
+ cells_content = cells_content.map { |header| header.to_s.downcase.strip }
1484
+ original_cells_content = row.map { |cell| cell.nil? ? '' : cell.value.to_s.downcase.strip }
1485
+ if (cells_content & original_cells_content).size == cells_content.size
1486
+ return index
1487
+ end
1488
+ end
1489
+ return nil
1490
+ end
1491
+
1492
+ end #end class
1493
+ end