rubyXL-git-ref-6002046 2.0.0
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.
- checksums.yaml +7 -0
- data/Gemfile +20 -0
- data/Gemfile.lock +63 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +197 -0
- data/Rakefile +58 -0
- data/VERSION +1 -0
- data/lib/rubyXL.rb +21 -0
- data/lib/rubyXL/cell.rb +325 -0
- data/lib/rubyXL/generic_storage.rb +40 -0
- data/lib/rubyXL/objects/border.rb +53 -0
- data/lib/rubyXL/objects/cell_style.rb +73 -0
- data/lib/rubyXL/objects/color.rb +23 -0
- data/lib/rubyXL/objects/column_range.rb +88 -0
- data/lib/rubyXL/objects/data_validation.rb +31 -0
- data/lib/rubyXL/objects/defined_name.rb +27 -0
- data/lib/rubyXL/objects/fill.rb +42 -0
- data/lib/rubyXL/objects/font.rb +109 -0
- data/lib/rubyXL/objects/formula.rb +8 -0
- data/lib/rubyXL/objects/ooxml_object.rb +177 -0
- data/lib/rubyXL/objects/reference.rb +98 -0
- data/lib/rubyXL/objects/sheet_view.rb +62 -0
- data/lib/rubyXL/objects/worksheet.rb +11 -0
- data/lib/rubyXL/parser.rb +307 -0
- data/lib/rubyXL/private_class.rb +95 -0
- data/lib/rubyXL/shared_strings.rb +35 -0
- data/lib/rubyXL/workbook.rb +342 -0
- data/lib/rubyXL/worksheet.rb +1118 -0
- data/lib/rubyXL/writer/app_writer.rb +51 -0
- data/lib/rubyXL/writer/calc_chain_writer.rb +18 -0
- data/lib/rubyXL/writer/content_types_writer.rb +113 -0
- data/lib/rubyXL/writer/core_writer.rb +34 -0
- data/lib/rubyXL/writer/generic_writer.rb +33 -0
- data/lib/rubyXL/writer/root_rels_writer.rb +17 -0
- data/lib/rubyXL/writer/shared_strings_writer.rb +21 -0
- data/lib/rubyXL/writer/styles_writer.rb +64 -0
- data/lib/rubyXL/writer/theme_writer.rb +337 -0
- data/lib/rubyXL/writer/workbook_rels_writer.rb +43 -0
- data/lib/rubyXL/writer/workbook_writer.rb +73 -0
- data/lib/rubyXL/writer/worksheet_writer.rb +164 -0
- data/lib/rubyXL/zip.rb +20 -0
- data/rdoc/created.rid +36 -0
- data/rdoc/fonts.css +167 -0
- data/rdoc/fonts/Lato-Light.ttf +0 -0
- data/rdoc/fonts/Lato-LightItalic.ttf +0 -0
- data/rdoc/fonts/Lato-Regular.ttf +0 -0
- data/rdoc/fonts/Lato-RegularItalic.ttf +0 -0
- data/rdoc/fonts/SourceCodePro-Bold.ttf +0 -0
- data/rdoc/fonts/SourceCodePro-Regular.ttf +0 -0
- data/rdoc/images/add.png +0 -0
- data/rdoc/images/arrow_up.png +0 -0
- data/rdoc/images/brick.png +0 -0
- data/rdoc/images/brick_link.png +0 -0
- data/rdoc/images/bug.png +0 -0
- data/rdoc/images/bullet_black.png +0 -0
- data/rdoc/images/bullet_toggle_minus.png +0 -0
- data/rdoc/images/bullet_toggle_plus.png +0 -0
- data/rdoc/images/date.png +0 -0
- data/rdoc/images/delete.png +0 -0
- data/rdoc/images/find.png +0 -0
- data/rdoc/images/loadingAnimation.gif +0 -0
- data/rdoc/images/macFFBgHack.png +0 -0
- data/rdoc/images/package.png +0 -0
- data/rdoc/images/page_green.png +0 -0
- data/rdoc/images/page_white_text.png +0 -0
- data/rdoc/images/page_white_width.png +0 -0
- data/rdoc/images/plugin.png +0 -0
- data/rdoc/images/ruby.png +0 -0
- data/rdoc/images/tag_blue.png +0 -0
- data/rdoc/images/tag_green.png +0 -0
- data/rdoc/images/transparent.png +0 -0
- data/rdoc/images/wrench.png +0 -0
- data/rdoc/images/wrench_orange.png +0 -0
- data/rdoc/images/zoom.png +0 -0
- data/rdoc/js/darkfish.js +140 -0
- data/rdoc/js/jquery.js +18 -0
- data/rdoc/js/navigation.js +142 -0
- data/rdoc/js/search.js +109 -0
- data/rdoc/js/search_index.js +1 -0
- data/rdoc/js/searcher.js +228 -0
- data/rdoc/rdoc.css +580 -0
- data/rubyXL-git-ref-6002046.gemspec +143 -0
- data/spec/lib/cell_spec.rb +407 -0
- data/spec/lib/color_spec.rb +14 -0
- data/spec/lib/parser_spec.rb +80 -0
- data/spec/lib/workbook_spec.rb +73 -0
- data/spec/lib/worksheet_spec.rb +1789 -0
- metadata +231 -0
@@ -0,0 +1,1118 @@
|
|
1
|
+
module RubyXL
|
2
|
+
class Worksheet < PrivateClass
|
3
|
+
include Enumerable
|
4
|
+
|
5
|
+
attr_accessor :sheet_name, :sheet_id, :sheet_data, :column_ranges, :merged_cells, :pane,
|
6
|
+
:validations, :sheet_views, :legacy_drawings, :extLst, :workbook,
|
7
|
+
:row_styles, :drawings
|
8
|
+
|
9
|
+
SHEET_NAME_TEMPLATE = 'Sheet%d'
|
10
|
+
|
11
|
+
def initialize(workbook, sheet_name = nil, sheet_data= [[nil]], cols=[], merged_cells=[])
|
12
|
+
@workbook = workbook
|
13
|
+
|
14
|
+
@sheet_name = sheet_name || get_default_name
|
15
|
+
@sheet_id = nil
|
16
|
+
@sheet_data = sheet_data
|
17
|
+
@column_ranges = cols
|
18
|
+
@merged_cells = merged_cells || []
|
19
|
+
@row_styles = []
|
20
|
+
@sheet_views = [ RubyXL::SheetView.new ]
|
21
|
+
@extLst = nil
|
22
|
+
@legacy_drawings = []
|
23
|
+
@drawings = []
|
24
|
+
@validations = []
|
25
|
+
end
|
26
|
+
|
27
|
+
def get_default_name
|
28
|
+
n = 0
|
29
|
+
|
30
|
+
begin
|
31
|
+
name = SHEET_NAME_TEMPLATE % (n += 1)
|
32
|
+
end until @workbook[name].nil?
|
33
|
+
|
34
|
+
name
|
35
|
+
end
|
36
|
+
private :get_default_name
|
37
|
+
|
38
|
+
# allows for easier access to sheet_data
|
39
|
+
def [](row = 0)
|
40
|
+
@sheet_data[row]
|
41
|
+
end
|
42
|
+
|
43
|
+
def each
|
44
|
+
@sheet_data.each { |row| yield(row) }
|
45
|
+
end
|
46
|
+
|
47
|
+
#returns 2d array of just the cell values (without style or formula information)
|
48
|
+
def extract_data(args = {})
|
49
|
+
raw_values = args.delete(:raw) || false
|
50
|
+
return @sheet_data.map {|row| row.map {|c| if c.is_a?(Cell) then c.value(:raw => raw_values) else nil end}}
|
51
|
+
end
|
52
|
+
|
53
|
+
def get_table(headers = [], opts = {})
|
54
|
+
validate_workbook
|
55
|
+
|
56
|
+
headers = [headers] unless headers.is_a?(Array)
|
57
|
+
row_num = find_first_row_with_content(headers)
|
58
|
+
|
59
|
+
return nil if row_num.nil?
|
60
|
+
|
61
|
+
table_hash = {}
|
62
|
+
table_hash[:table] = []
|
63
|
+
|
64
|
+
header_row = @sheet_data[row_num]
|
65
|
+
header_row.each_with_index { |header_cell, index|
|
66
|
+
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]
|
67
|
+
next if header_cell.nil? || header_cell.value.nil?
|
68
|
+
header = header_cell.value.to_s
|
69
|
+
table_hash[:sorted_headers]||=[]
|
70
|
+
table_hash[:sorted_headers] << header
|
71
|
+
table_hash[header] = []
|
72
|
+
|
73
|
+
original_row = row_num + 1
|
74
|
+
current_row = original_row
|
75
|
+
|
76
|
+
cell = @sheet_data[current_row][index]
|
77
|
+
|
78
|
+
# makes array of hashes in table_hash[:table]
|
79
|
+
# as well as hash of arrays in table_hash[header]
|
80
|
+
table_index = current_row - original_row
|
81
|
+
cell_test = (!cell.nil? && !cell.value.nil?)
|
82
|
+
|
83
|
+
while cell_test || (table_hash[:table][table_index] && !table_hash[:table][table_index].empty?)
|
84
|
+
table_hash[header] << cell.value if cell_test
|
85
|
+
table_index = current_row - original_row
|
86
|
+
|
87
|
+
if cell_test then
|
88
|
+
table_hash[:table][table_index] ||= {}
|
89
|
+
table_hash[:table][table_index][header] = cell.value
|
90
|
+
end
|
91
|
+
|
92
|
+
current_row += 1
|
93
|
+
if @sheet_data[current_row].nil? then
|
94
|
+
cell = nil
|
95
|
+
else
|
96
|
+
cell = @sheet_data[current_row][index]
|
97
|
+
end
|
98
|
+
cell_test = (!cell.nil? && !cell.value.nil?)
|
99
|
+
end
|
100
|
+
}
|
101
|
+
|
102
|
+
return table_hash
|
103
|
+
end
|
104
|
+
|
105
|
+
#changes color of fill in (zer0 indexed) row
|
106
|
+
def change_row_fill(row = 0, rgb = 'ffffff')
|
107
|
+
validate_workbook
|
108
|
+
validate_nonnegative(row)
|
109
|
+
ensure_cell_exists(row)
|
110
|
+
Color.validate_color(rgb)
|
111
|
+
|
112
|
+
if @row_styles[(Integer(row)+1)].nil?
|
113
|
+
@row_styles[(Integer(row)+1)] = {}
|
114
|
+
@row_styles[(Integer(row)+1)][:style] = 0
|
115
|
+
end
|
116
|
+
|
117
|
+
@row_styles[(Integer(row)+1)][:style] = modify_fill(@workbook,Integer(@row_styles[(Integer(row)+1)][:style]),rgb)
|
118
|
+
|
119
|
+
@sheet_data[Integer(row)].each do |c|
|
120
|
+
unless c.nil?
|
121
|
+
c.change_fill(rgb)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
def change_row_font_name(row = 0, font_name = 'Verdana')
|
127
|
+
ensure_cell_exists(row)
|
128
|
+
font = row_font(row).dup
|
129
|
+
font.set_name(font_name)
|
130
|
+
change_row_font(row, Worksheet::NAME, font_name, font)
|
131
|
+
end
|
132
|
+
|
133
|
+
def change_row_font_size(row = 0, font_size=10)
|
134
|
+
ensure_cell_exists(row)
|
135
|
+
font = row_font(row).dup
|
136
|
+
font.set_size(font_size)
|
137
|
+
change_row_font(row, Worksheet::SIZE, font_size, font)
|
138
|
+
end
|
139
|
+
|
140
|
+
def change_row_font_color(row = 0, font_color='000000')
|
141
|
+
ensure_cell_exists(row)
|
142
|
+
Color.validate_color(font_color)
|
143
|
+
font = row_font(row).dup
|
144
|
+
font.set_rgb_color(font_color)
|
145
|
+
change_row_font(row, Worksheet::COLOR, font_color, font)
|
146
|
+
end
|
147
|
+
|
148
|
+
def change_row_italics(row = 0, italicized=false)
|
149
|
+
ensure_cell_exists(row)
|
150
|
+
font = row_font(row).dup
|
151
|
+
font.set_italic(italicized)
|
152
|
+
change_row_font(row, Worksheet::ITALICS, italicized, font)
|
153
|
+
end
|
154
|
+
|
155
|
+
def change_row_bold(row = 0, bolded=false)
|
156
|
+
ensure_cell_exists(row)
|
157
|
+
font = row_font(row).dup
|
158
|
+
font.set_bold(bolded)
|
159
|
+
change_row_font(row, Worksheet::BOLD, bolded, font)
|
160
|
+
end
|
161
|
+
|
162
|
+
def change_row_underline(row = 0, underlined=false)
|
163
|
+
ensure_cell_exists(row)
|
164
|
+
font = row_font(row).dup
|
165
|
+
font.set_underline(underlined)
|
166
|
+
change_row_font(row, Worksheet::UNDERLINE, underlined, font)
|
167
|
+
end
|
168
|
+
|
169
|
+
def change_row_strikethrough(row = 0, struckthrough=false)
|
170
|
+
ensure_cell_exists(row)
|
171
|
+
font = row_font(row).dup
|
172
|
+
font.set_strikethrough(struckthrough)
|
173
|
+
change_row_font(row, Worksheet::STRIKETHROUGH, struckthrough, font)
|
174
|
+
end
|
175
|
+
|
176
|
+
def change_row_height(row = 0, height=10)
|
177
|
+
validate_workbook
|
178
|
+
validate_nonnegative(row)
|
179
|
+
|
180
|
+
ensure_cell_exists(row)
|
181
|
+
|
182
|
+
if height.to_i.to_s == height.to_s
|
183
|
+
height = Integer(height)
|
184
|
+
elsif height.to_f.to_s == height.to_s
|
185
|
+
height = Float(height)
|
186
|
+
else
|
187
|
+
raise 'You must enter a number for the height'
|
188
|
+
end
|
189
|
+
|
190
|
+
if @row_styles[(row+1)].nil?
|
191
|
+
@row_styles[(row+1)] = {}
|
192
|
+
@row_styles[(row+1)][:style] = 0
|
193
|
+
end
|
194
|
+
@row_styles[(row+1)][:height] = height
|
195
|
+
@row_styles[(row+1)][:customHeight] = '1'
|
196
|
+
end
|
197
|
+
|
198
|
+
def change_row_horizontal_alignment(row = 0,alignment='center')
|
199
|
+
validate_workbook
|
200
|
+
validate_nonnegative(row)
|
201
|
+
validate_horizontal_alignment(alignment)
|
202
|
+
change_row_alignment(row,alignment,true)
|
203
|
+
end
|
204
|
+
|
205
|
+
def change_row_vertical_alignment(row = 0,alignment='center')
|
206
|
+
validate_workbook
|
207
|
+
validate_nonnegative(row)
|
208
|
+
validate_vertical_alignment(alignment)
|
209
|
+
change_row_alignment(row,alignment,false)
|
210
|
+
end
|
211
|
+
|
212
|
+
def change_row_border_top(row = 0, weight = 'thin')
|
213
|
+
change_row_border(row, :top, weight)
|
214
|
+
end
|
215
|
+
|
216
|
+
def change_row_border_left(row = 0, weight = 'thin')
|
217
|
+
change_row_border(row, :left, weight)
|
218
|
+
end
|
219
|
+
|
220
|
+
def change_row_border_right(row = 0, weight = 'thin')
|
221
|
+
change_row_border(row, :right, weight)
|
222
|
+
end
|
223
|
+
|
224
|
+
def change_row_border_bottom(row = 0, weight = 'thin')
|
225
|
+
change_row_border(row, :bottom, weight)
|
226
|
+
end
|
227
|
+
|
228
|
+
def change_row_border_diagonal(row = 0, weight = 'thin')
|
229
|
+
change_row_border(row, :diagonal, weight)
|
230
|
+
end
|
231
|
+
|
232
|
+
# Changes font name of column
|
233
|
+
def change_column_font_name(col = 0, font_name = 'Verdana')
|
234
|
+
xf = get_col_xf(col)
|
235
|
+
font = @workbook.fonts[xf.font_id].dup
|
236
|
+
font.set_name(font_name)
|
237
|
+
change_column_font(col, Worksheet::NAME, font_name, font, xf)
|
238
|
+
end
|
239
|
+
|
240
|
+
# Changes font size of column
|
241
|
+
def change_column_font_size(col=0, font_size=10)
|
242
|
+
xf = get_col_xf(col)
|
243
|
+
font = @workbook.fonts[xf.font_id].dup
|
244
|
+
font.set_size(font_size)
|
245
|
+
change_column_font(col, Worksheet::SIZE, font_size, font, xf)
|
246
|
+
end
|
247
|
+
|
248
|
+
# Changes font color of column
|
249
|
+
def change_column_font_color(col=0, font_color='000000')
|
250
|
+
Color.validate_color(font_color)
|
251
|
+
|
252
|
+
xf = get_col_xf(col)
|
253
|
+
font = @workbook.fonts[xf.font_id].dup
|
254
|
+
font.set_rgb_color(font_color)
|
255
|
+
change_column_font(col, Worksheet::COLOR, font_color, font, xf)
|
256
|
+
end
|
257
|
+
|
258
|
+
def change_column_italics(col = 0, italicized = false)
|
259
|
+
xf = get_col_xf(col)
|
260
|
+
font = @workbook.fonts[xf.font_id].dup
|
261
|
+
font.set_italic(italicized)
|
262
|
+
change_column_font(col, Worksheet::ITALICS, italicized, font, xf)
|
263
|
+
end
|
264
|
+
|
265
|
+
def change_column_bold(col = 0, bolded = false)
|
266
|
+
xf = get_col_xf(col)
|
267
|
+
font = @workbook.fonts[xf.font_id].dup
|
268
|
+
font.set_bold(bolded)
|
269
|
+
change_column_font(col, Worksheet::BOLD, bolded, font, xf)
|
270
|
+
end
|
271
|
+
|
272
|
+
def change_column_underline(col = 0, underlined = false)
|
273
|
+
xf = get_col_xf(col)
|
274
|
+
font = @workbook.fonts[xf.font_id].dup
|
275
|
+
font.set_underline(underlined)
|
276
|
+
change_column_font(col, Worksheet::UNDERLINE, underlined, font, xf)
|
277
|
+
end
|
278
|
+
|
279
|
+
def change_column_strikethrough(col=0, struckthrough=false)
|
280
|
+
xf = get_col_xf(col)
|
281
|
+
font = @workbook.fonts[xf.font_id].dup
|
282
|
+
font.set_strikethrough(struckthrough)
|
283
|
+
change_column_font(col, Worksheet::STRIKETHROUGH, struckthrough, font, xf)
|
284
|
+
end
|
285
|
+
|
286
|
+
def change_column_width(col = 0, width = 13)
|
287
|
+
validate_workbook
|
288
|
+
validate_nonnegative(col)
|
289
|
+
ensure_cell_exists(0, col)
|
290
|
+
|
291
|
+
RubyXL::ColumnRange.update(col, @column_ranges, { 'width' => width, 'customWidth' => 1 })
|
292
|
+
end
|
293
|
+
|
294
|
+
def get_column_style_index(col)
|
295
|
+
range = RubyXL::ColumnRange.find(col, @column_ranges)
|
296
|
+
(range && range.style_index) || 0
|
297
|
+
end
|
298
|
+
|
299
|
+
def change_column_fill(col=0, color_index='ffffff')
|
300
|
+
validate_workbook
|
301
|
+
validate_nonnegative(col)
|
302
|
+
Color.validate_color(color_index)
|
303
|
+
ensure_cell_exists(0, col)
|
304
|
+
|
305
|
+
new_style_index = modify_fill(@workbook, get_column_style_index(col), color_index)
|
306
|
+
RubyXL::ColumnRange.update(col, @column_ranges, { 'style' => new_style_index })
|
307
|
+
|
308
|
+
@sheet_data.each { |row|
|
309
|
+
c = row[col]
|
310
|
+
c.change_fill(color_index) if c
|
311
|
+
}
|
312
|
+
end
|
313
|
+
|
314
|
+
def change_column_horizontal_alignment(col=0,alignment='center')
|
315
|
+
validate_horizontal_alignment(alignment)
|
316
|
+
change_column_alignment(col,alignment,true)
|
317
|
+
end
|
318
|
+
|
319
|
+
def change_column_vertical_alignment(col=0,alignment='center')
|
320
|
+
validate_vertical_alignment(alignment)
|
321
|
+
change_column_alignment(col,alignment,false)
|
322
|
+
end
|
323
|
+
|
324
|
+
def change_column_border_top(col=0,weight = 'thin')
|
325
|
+
change_column_border(col, :top, weight)
|
326
|
+
end
|
327
|
+
|
328
|
+
def change_column_border_left(col=0,weight = 'thin')
|
329
|
+
change_column_border(col, :left, weight)
|
330
|
+
end
|
331
|
+
|
332
|
+
def change_column_border_right(col=0,weight = 'thin')
|
333
|
+
change_column_border(col, :right, weight)
|
334
|
+
end
|
335
|
+
|
336
|
+
def change_column_border_bottom(col=0,weight = 'thin')
|
337
|
+
change_column_border(col, :bottom, weight)
|
338
|
+
end
|
339
|
+
|
340
|
+
def change_column_border_diagonal(col=0,weight = 'thin')
|
341
|
+
change_column_border(col, :diagonal, weight)
|
342
|
+
end
|
343
|
+
|
344
|
+
# merges cells within a rectangular range
|
345
|
+
def merge_cells(row1 = 0, col1 = 0, row2 = 0, col2 = 0)
|
346
|
+
validate_workbook
|
347
|
+
@merged_cells << RubyXL::Reference.new(row1, row2, col1, col2)
|
348
|
+
end
|
349
|
+
|
350
|
+
def add_cell(row=0, column=0, data='', formula=nil,overwrite=true)
|
351
|
+
validate_workbook
|
352
|
+
validate_nonnegative(row)
|
353
|
+
validate_nonnegative(column)
|
354
|
+
ensure_cell_exists(row, column)
|
355
|
+
|
356
|
+
datatype = (formula.nil?) ? RubyXL::Cell::RAW_STRING : ''
|
357
|
+
|
358
|
+
if overwrite || @sheet_data[row][column].nil?
|
359
|
+
@sheet_data[row][column] = Cell.new(self,row,column,data,formula,datatype)
|
360
|
+
|
361
|
+
if (data.is_a?Integer) || (data.is_a?Float)
|
362
|
+
@sheet_data[row][column].datatype = ''
|
363
|
+
end
|
364
|
+
col = RubyXL::ColumnRange.find(column, @column_ranges)
|
365
|
+
|
366
|
+
if @row_styles[row+1] != nil
|
367
|
+
@sheet_data[row][column].style_index = @row_styles[row+1][:style]
|
368
|
+
elsif col != nil
|
369
|
+
@sheet_data[row][column].style_index = col.style_index
|
370
|
+
end
|
371
|
+
end
|
372
|
+
|
373
|
+
@sheet_data[row][column].style_index ||= 0
|
374
|
+
|
375
|
+
add_cell_style(row,column)
|
376
|
+
|
377
|
+
return @sheet_data[row][column]
|
378
|
+
end
|
379
|
+
|
380
|
+
def add_cell_obj(cell, overwrite=true)
|
381
|
+
validate_workbook
|
382
|
+
|
383
|
+
if cell.nil?
|
384
|
+
return cell
|
385
|
+
end
|
386
|
+
|
387
|
+
row = cell.row
|
388
|
+
column = cell.column
|
389
|
+
|
390
|
+
validate_nonnegative(row)
|
391
|
+
validate_nonnegative(column)
|
392
|
+
ensure_cell_exists(row, column)
|
393
|
+
|
394
|
+
if overwrite || @sheet_data[row][column].nil?
|
395
|
+
@sheet_data[row][column] = cell
|
396
|
+
end
|
397
|
+
|
398
|
+
add_cell_style(row,column)
|
399
|
+
|
400
|
+
return @sheet_data[row][column]
|
401
|
+
end
|
402
|
+
|
403
|
+
def delete_row(row_index=0)
|
404
|
+
validate_workbook
|
405
|
+
validate_nonnegative(row_index)
|
406
|
+
|
407
|
+
if row_index >= @sheet_data.size
|
408
|
+
return nil
|
409
|
+
end
|
410
|
+
|
411
|
+
deleted = @sheet_data.delete_at(row_index)
|
412
|
+
row_num = row_index+1
|
413
|
+
|
414
|
+
@row_styles.delete_at(row_index)
|
415
|
+
|
416
|
+
# Change cell row numbers
|
417
|
+
row_index.upto(@sheet_data.size - 1) { |index|
|
418
|
+
@sheet_data[index].each{ |c| c.row -= 1 unless c.nil? }
|
419
|
+
}
|
420
|
+
|
421
|
+
return deleted
|
422
|
+
end
|
423
|
+
|
424
|
+
#inserts row at row_index, pushes down, copies style from below (row previously at that index)
|
425
|
+
#USE OF THIS METHOD will break formulas which reference cells which are being "pushed down"
|
426
|
+
def insert_row(row_index=0)
|
427
|
+
validate_workbook
|
428
|
+
validate_nonnegative(row_index)
|
429
|
+
|
430
|
+
ensure_cell_exists(row_index)
|
431
|
+
|
432
|
+
@sheet_data.insert(row_index,Array.new(@sheet_data[row_index].size))
|
433
|
+
|
434
|
+
row_num = row_index+1
|
435
|
+
|
436
|
+
#copy cell styles from row above, (or below if first row)
|
437
|
+
@sheet_data[row_index].each_index do |i|
|
438
|
+
if row_index > 0
|
439
|
+
old_cell = @sheet_data[row_index-1][i]
|
440
|
+
else
|
441
|
+
old_cell = @sheet_data[row_index+1][i]
|
442
|
+
end
|
443
|
+
|
444
|
+
unless old_cell.nil?
|
445
|
+
#only add cell if style exists, not copying content
|
446
|
+
|
447
|
+
if @row_styles[(row_num+1)].nil?
|
448
|
+
@row_styles[(row_num+1)] = {:style=>0}
|
449
|
+
end
|
450
|
+
if old_cell.style_index != 0 && old_cell.style_index != @row_styles[(row_num+1)][:style]
|
451
|
+
c = Cell.new(self,row_index,i)
|
452
|
+
c.style_index = old_cell.style_index
|
453
|
+
@sheet_data[row_index][i] = c
|
454
|
+
end
|
455
|
+
end
|
456
|
+
end
|
457
|
+
|
458
|
+
#copy row styles from row above, (or below if first row)
|
459
|
+
(@row_styles.size+1).downto(row_num+1) do |i|
|
460
|
+
@row_styles[i] = @row_styles[(i-1)]
|
461
|
+
end
|
462
|
+
|
463
|
+
if row_index > 0
|
464
|
+
@row_styles[row_num] = @row_styles[(row_num-1)]
|
465
|
+
else
|
466
|
+
@row_styles[row_num] = nil #@row_styles[(row_num+1).to_s]
|
467
|
+
end
|
468
|
+
|
469
|
+
#update row value for all rows below
|
470
|
+
(row_index+1).upto(@sheet_data.size-1) do |i|
|
471
|
+
row = @sheet_data[i]
|
472
|
+
row.each do |c|
|
473
|
+
unless c.nil?
|
474
|
+
c.row += 1
|
475
|
+
end
|
476
|
+
end
|
477
|
+
end
|
478
|
+
|
479
|
+
return @sheet_data[row_index]
|
480
|
+
end
|
481
|
+
|
482
|
+
def delete_column(col_index=0)
|
483
|
+
validate_workbook
|
484
|
+
validate_nonnegative(col_index)
|
485
|
+
|
486
|
+
if col_index >= @sheet_data[0].size
|
487
|
+
return nil
|
488
|
+
end
|
489
|
+
|
490
|
+
#delete column
|
491
|
+
@sheet_data.map {|r| r.delete_at(col_index)}
|
492
|
+
|
493
|
+
#change column numbers for cells to right of deleted column
|
494
|
+
@sheet_data.each_with_index do |row,row_index|
|
495
|
+
(col_index...(row.size)).each do |index|
|
496
|
+
if @sheet_data[row_index][index].is_a?(Cell)
|
497
|
+
@sheet_data[row_index][index].column -= 1
|
498
|
+
end
|
499
|
+
end
|
500
|
+
end
|
501
|
+
|
502
|
+
@column_ranges.each { |range| range.delete_column(col_index) }
|
503
|
+
end
|
504
|
+
|
505
|
+
# inserts column at col_index, pushes everything right, takes styles from column to left
|
506
|
+
# USE OF THIS METHOD will break formulas which reference cells which are being "pushed down"
|
507
|
+
def insert_column(col_index = 0)
|
508
|
+
validate_workbook
|
509
|
+
validate_nonnegative(col_index)
|
510
|
+
ensure_cell_exists(0, col_index)
|
511
|
+
|
512
|
+
old_range = col_index > 0 ? RubyXL::ColumnRange.find(col_index, @column_ranges) : RubyXL::ColumnRange.new
|
513
|
+
|
514
|
+
#go through each cell in column
|
515
|
+
@sheet_data.each_with_index do |row, row_index|
|
516
|
+
old_cell = row[col_index]
|
517
|
+
new_cell = nil
|
518
|
+
|
519
|
+
if old_cell && old_cell.style_index != 0 &&
|
520
|
+
old_range && old_range.style_index != old_cell.style_index.to_i then
|
521
|
+
new_cell = Cell.new(self, row_index, col_index)
|
522
|
+
new_cell.style_index = old_cell.style_index
|
523
|
+
end
|
524
|
+
|
525
|
+
row.insert(col_index, new_cell)
|
526
|
+
end
|
527
|
+
|
528
|
+
ColumnRange.insert_column(col_index, @column_ranges)
|
529
|
+
|
530
|
+
#update column numbers
|
531
|
+
@sheet_data.each { |row|
|
532
|
+
(col_index + 1).upto(row.size) { |col|
|
533
|
+
row[col].column = col unless row[col].nil?
|
534
|
+
}
|
535
|
+
}
|
536
|
+
|
537
|
+
end
|
538
|
+
|
539
|
+
def insert_cell(row = 0, col = 0, data = nil, formula = nil, shift = nil)
|
540
|
+
validate_workbook
|
541
|
+
validate_nonnegative(row)
|
542
|
+
validate_nonnegative(col)
|
543
|
+
ensure_cell_exists(row, col)
|
544
|
+
|
545
|
+
case shift
|
546
|
+
when nil then # No shifting at all
|
547
|
+
when :right then
|
548
|
+
@sheet_data[row].insert(col,nil)
|
549
|
+
(row...(@sheet_data[row].size)).each { |index|
|
550
|
+
if @sheet_data[row][index].is_a?(Cell)
|
551
|
+
@sheet_data[row][index].column += 1
|
552
|
+
end
|
553
|
+
}
|
554
|
+
when :down then
|
555
|
+
@sheet_data << Array.new(@sheet_data[row].size)
|
556
|
+
(@sheet_data.size-1).downto(row+1) { |index|
|
557
|
+
@sheet_data[index][col] = @sheet_data[index-1][col]
|
558
|
+
}
|
559
|
+
else
|
560
|
+
raise 'invalid shift option'
|
561
|
+
end
|
562
|
+
|
563
|
+
return add_cell(row,col,data,formula)
|
564
|
+
end
|
565
|
+
|
566
|
+
# by default, only sets cell to nil
|
567
|
+
# if :left is specified, method will shift row contents to the right of the deleted cell to the left
|
568
|
+
# if :up is specified, method will shift column contents below the deleted cell upward
|
569
|
+
def delete_cell(row = 0, col=0, shift=nil)
|
570
|
+
validate_workbook
|
571
|
+
validate_nonnegative(row)
|
572
|
+
validate_nonnegative(col)
|
573
|
+
|
574
|
+
return nil if @sheet_data.size <= row || @sheet_data[row].size <= col
|
575
|
+
|
576
|
+
cell = @sheet_data[row][col]
|
577
|
+
|
578
|
+
case shift
|
579
|
+
when nil then
|
580
|
+
@sheet_data[row][col] = nil
|
581
|
+
when :left then
|
582
|
+
@sheet_data[row].delete_at(col)
|
583
|
+
@sheet_data[row] << nil
|
584
|
+
(col...(@sheet_data[row].size)).each { |index|
|
585
|
+
if @sheet_data[row][index].is_a?(Cell)
|
586
|
+
@sheet_data[row][index].column -= 1
|
587
|
+
end
|
588
|
+
}
|
589
|
+
when :up then
|
590
|
+
(row...(@sheet_data.size-1)).each { |index|
|
591
|
+
@sheet_data[index][col] = @sheet_data[index+1][col]
|
592
|
+
if @sheet_data[index][col].is_a?(Cell)
|
593
|
+
@sheet_data[index][col].row -= 1
|
594
|
+
end
|
595
|
+
}
|
596
|
+
|
597
|
+
@sheet_data.last[col].row -= 1 if @sheet_data.last[col].is_a?(Cell)
|
598
|
+
else
|
599
|
+
raise 'invalid shift option'
|
600
|
+
end
|
601
|
+
|
602
|
+
return cell
|
603
|
+
end
|
604
|
+
|
605
|
+
def get_row_fill(row = 0)
|
606
|
+
validate_workbook
|
607
|
+
validate_nonnegative(row)
|
608
|
+
|
609
|
+
if @sheet_data.size <= row
|
610
|
+
return nil
|
611
|
+
end
|
612
|
+
|
613
|
+
if @row_styles[(row+1)].nil?
|
614
|
+
return "ffffff" #default, white
|
615
|
+
end
|
616
|
+
|
617
|
+
xf = get_row_xf(row)
|
618
|
+
|
619
|
+
return @workbook.get_fill_color(xf)
|
620
|
+
end
|
621
|
+
|
622
|
+
def get_row_font_name(row = 0)
|
623
|
+
font = row_font(row)
|
624
|
+
font && font.get_name
|
625
|
+
end
|
626
|
+
|
627
|
+
def get_row_font_size(row = 0)
|
628
|
+
font = row_font(row)
|
629
|
+
font && font.get_size
|
630
|
+
end
|
631
|
+
|
632
|
+
def get_row_font_color(row = 0)
|
633
|
+
font = row_font(row)
|
634
|
+
color = font && font.color
|
635
|
+
color && (color.rgb || '000000')
|
636
|
+
end
|
637
|
+
|
638
|
+
def is_row_italicized(row = 0)
|
639
|
+
font = row_font(row)
|
640
|
+
font && font.is_italic
|
641
|
+
end
|
642
|
+
|
643
|
+
def is_row_bolded(row = 0)
|
644
|
+
font = row_font(row)
|
645
|
+
font && font.is_bold
|
646
|
+
end
|
647
|
+
|
648
|
+
def is_row_underlined(row = 0)
|
649
|
+
font = row_font(row)
|
650
|
+
font && font.is_underlined
|
651
|
+
end
|
652
|
+
|
653
|
+
def is_row_struckthrough(row = 0)
|
654
|
+
font = row_font(row)
|
655
|
+
font && font.is_strikethrough
|
656
|
+
end
|
657
|
+
|
658
|
+
def get_row_height(row = 0)
|
659
|
+
validate_workbook
|
660
|
+
validate_nonnegative(row)
|
661
|
+
|
662
|
+
if @sheet_data.size <= row
|
663
|
+
return nil
|
664
|
+
end
|
665
|
+
|
666
|
+
if @row_styles[(row+1)].nil?
|
667
|
+
return 13
|
668
|
+
else
|
669
|
+
@row_styles[(row+1)][:height]
|
670
|
+
end
|
671
|
+
end
|
672
|
+
|
673
|
+
def get_row_horizontal_alignment(row = 0)
|
674
|
+
return get_row_alignment(row,true)
|
675
|
+
end
|
676
|
+
|
677
|
+
def get_row_vertical_alignment(row = 0)
|
678
|
+
return get_row_alignment(row,false)
|
679
|
+
end
|
680
|
+
|
681
|
+
def get_row_border_top(row = 0)
|
682
|
+
return get_row_border(row, :top)
|
683
|
+
end
|
684
|
+
|
685
|
+
def get_row_border_left(row = 0)
|
686
|
+
return get_row_border(row, :left)
|
687
|
+
end
|
688
|
+
|
689
|
+
def get_row_border_right(row = 0)
|
690
|
+
return get_row_border(row, :right)
|
691
|
+
end
|
692
|
+
|
693
|
+
def get_row_border_bottom(row = 0)
|
694
|
+
return get_row_border(row, :bottom)
|
695
|
+
end
|
696
|
+
|
697
|
+
def get_row_border_diagonal(row = 0)
|
698
|
+
return get_row_border(row, :diagonal)
|
699
|
+
end
|
700
|
+
|
701
|
+
def get_column_font_name(col = 0)
|
702
|
+
font = column_font(col)
|
703
|
+
font && font.get_name
|
704
|
+
end
|
705
|
+
|
706
|
+
def get_column_font_size(col = 0)
|
707
|
+
font = column_font(col)
|
708
|
+
font && font.get_size
|
709
|
+
end
|
710
|
+
|
711
|
+
def get_column_font_color(col = 0)
|
712
|
+
font = column_font(col)
|
713
|
+
font && (font.get_rgb_color || '000000')
|
714
|
+
end
|
715
|
+
|
716
|
+
def is_column_italicized(col = 0)
|
717
|
+
font = column_font(col)
|
718
|
+
font && font.is_italic
|
719
|
+
end
|
720
|
+
|
721
|
+
def is_column_bolded(col = 0)
|
722
|
+
font = column_font(col)
|
723
|
+
font && font.is_bold
|
724
|
+
end
|
725
|
+
|
726
|
+
def is_column_underlined(col = 0)
|
727
|
+
font = column_font(col)
|
728
|
+
font && font.is_underlined
|
729
|
+
end
|
730
|
+
|
731
|
+
def is_column_struckthrough(col = 0)
|
732
|
+
font = column_font(col)
|
733
|
+
font && font.is_strikethrough
|
734
|
+
end
|
735
|
+
|
736
|
+
def get_column_width(col=0)
|
737
|
+
validate_workbook
|
738
|
+
validate_nonnegative(col)
|
739
|
+
|
740
|
+
if @sheet_data[0].size <= col
|
741
|
+
return nil
|
742
|
+
end
|
743
|
+
|
744
|
+
range = RubyXL::ColumnRange.find(col, @column_ranges)
|
745
|
+
|
746
|
+
(range && range.width) || 10
|
747
|
+
end
|
748
|
+
|
749
|
+
def get_column_fill(col=0)
|
750
|
+
validate_workbook
|
751
|
+
validate_nonnegative(col)
|
752
|
+
return nil if @sheet_data[0].size <= col
|
753
|
+
@workbook.get_fill_color(get_col_xf(col))
|
754
|
+
end
|
755
|
+
|
756
|
+
def get_column_horizontal_alignment(col=0)
|
757
|
+
get_column_alignment(col, :horizontal)
|
758
|
+
end
|
759
|
+
|
760
|
+
def get_column_vertical_alignment(col=0)
|
761
|
+
get_column_alignment(col, :vertical)
|
762
|
+
end
|
763
|
+
|
764
|
+
def get_column_border_top(col=0)
|
765
|
+
get_column_border(col, :top)
|
766
|
+
end
|
767
|
+
|
768
|
+
def get_column_border_left(col=0)
|
769
|
+
get_column_border(col, :left)
|
770
|
+
end
|
771
|
+
|
772
|
+
def get_column_border_right(col=0)
|
773
|
+
get_column_border(col, :right)
|
774
|
+
end
|
775
|
+
|
776
|
+
def get_column_border_bottom(col=0)
|
777
|
+
get_column_border(col, :bottom)
|
778
|
+
end
|
779
|
+
|
780
|
+
def get_column_border_diagonal(col=0)
|
781
|
+
get_column_border(col, :diagonal)
|
782
|
+
end
|
783
|
+
|
784
|
+
|
785
|
+
private
|
786
|
+
|
787
|
+
Worksheet::NAME = 0
|
788
|
+
Worksheet::SIZE = 1
|
789
|
+
Worksheet::COLOR = 2
|
790
|
+
Worksheet::ITALICS = 3
|
791
|
+
Worksheet::BOLD = 4
|
792
|
+
Worksheet::UNDERLINE = 5
|
793
|
+
Worksheet::STRIKETHROUGH = 6
|
794
|
+
|
795
|
+
#row_styles is assumed to not be nil at specified row
|
796
|
+
def get_row_xf(row)
|
797
|
+
@row_styles[(row+1)] ||= { :style => 0 }
|
798
|
+
@workbook.cell_xfs[@row_styles[(row+1)][:style]]
|
799
|
+
end
|
800
|
+
|
801
|
+
def row_font(row)
|
802
|
+
validate_workbook
|
803
|
+
validate_nonnegative(row)
|
804
|
+
xf = get_row_xf(row)
|
805
|
+
return nil if @sheet_data.size <= row
|
806
|
+
@workbook.fonts[xf.font_id]
|
807
|
+
end
|
808
|
+
|
809
|
+
def get_row_alignment(row, is_horizontal)
|
810
|
+
validate_workbook
|
811
|
+
validate_nonnegative(row)
|
812
|
+
|
813
|
+
if @sheet_data.size <= row || @row_styles[(row+1)].nil?
|
814
|
+
return nil
|
815
|
+
end
|
816
|
+
|
817
|
+
xf_obj = @workbook.cell_xfs[@row_styles[(row+1)][:style]]
|
818
|
+
|
819
|
+
return nil if xf_obj.alignment.nil?
|
820
|
+
|
821
|
+
if is_horizontal then
|
822
|
+
return xf_obj.alignment.horizontal
|
823
|
+
else
|
824
|
+
return xf_obj.alignment.vertical
|
825
|
+
end
|
826
|
+
end
|
827
|
+
|
828
|
+
def get_row_border(row, border_direction)
|
829
|
+
validate_workbook
|
830
|
+
validate_nonnegative(row)
|
831
|
+
|
832
|
+
return nil if @sheet_data.size <= row || @row_styles[(row+1)].nil?
|
833
|
+
|
834
|
+
border = @workbook.borders[get_row_xf(row).border_id]
|
835
|
+
border && border.get_edge_style(border_direction)
|
836
|
+
end
|
837
|
+
|
838
|
+
def column_font(col)
|
839
|
+
validate_workbook
|
840
|
+
validate_nonnegative(col)
|
841
|
+
|
842
|
+
return nil if @sheet_data[0].size <= col
|
843
|
+
style_index = get_cols_style_index(col)
|
844
|
+
@workbook.fonts[@workbook.cell_xfs[style_index].font_id]
|
845
|
+
end
|
846
|
+
|
847
|
+
def get_column_alignment(col, type)
|
848
|
+
validate_workbook
|
849
|
+
validate_nonnegative(col)
|
850
|
+
|
851
|
+
return nil if @sheet_data[0].size <= col
|
852
|
+
xf = @workbook.cell_xfs[get_cols_style_index(col)]
|
853
|
+
xf.alignment && xf.alignment.send(type)
|
854
|
+
end
|
855
|
+
|
856
|
+
def get_column_border(col, border_direction)
|
857
|
+
validate_workbook
|
858
|
+
validate_nonnegative(col)
|
859
|
+
|
860
|
+
return nil if @sheet_data[0].size <= col
|
861
|
+
|
862
|
+
xf = @workbook.cell_xfs[get_cols_style_index(col)]
|
863
|
+
|
864
|
+
border = @workbook.borders[xf.border_id]
|
865
|
+
border && border.get_edge_style(border_direction)
|
866
|
+
end
|
867
|
+
|
868
|
+
#validates Workbook, ensures that this worksheet is in @workbook
|
869
|
+
def validate_workbook()
|
870
|
+
unless @workbook.nil? || @workbook.worksheets.nil?
|
871
|
+
return if @workbook.worksheets.include?(self)
|
872
|
+
end
|
873
|
+
|
874
|
+
raise "This worksheet #{self} is not in workbook #{@workbook}"
|
875
|
+
end
|
876
|
+
|
877
|
+
def get_cols_style_index(col)
|
878
|
+
range = RubyXL::ColumnRange.find(col, @column_ranges)
|
879
|
+
(range && range.style_index) || 0
|
880
|
+
end
|
881
|
+
|
882
|
+
# Helper method to update the row styles array
|
883
|
+
# change_type - NAME or SIZE or COLOR etc
|
884
|
+
# main method to change font, called from each separate font mutator method
|
885
|
+
def change_row_font(row, change_type, arg, font)
|
886
|
+
validate_workbook
|
887
|
+
validate_nonnegative(row)
|
888
|
+
ensure_cell_exists(row)
|
889
|
+
|
890
|
+
xf = workbook.register_new_font(font, get_row_xf(row))
|
891
|
+
@row_styles[(row+1)][:style] = workbook.register_new_xf(xf, @row_styles[(row+1)][:style])
|
892
|
+
|
893
|
+
@sheet_data[row] ||= []
|
894
|
+
@sheet_data[Integer(row)].each { |c|
|
895
|
+
font_switch(c, change_type, arg) unless c.nil?
|
896
|
+
}
|
897
|
+
end
|
898
|
+
|
899
|
+
# Helper method to update the fonts and cell styles array
|
900
|
+
# main method to change font, called from each separate font mutator method
|
901
|
+
def change_column_font(col, change_type, arg, font, xf)
|
902
|
+
validate_workbook
|
903
|
+
validate_nonnegative(col)
|
904
|
+
ensure_cell_exists(0, col)
|
905
|
+
|
906
|
+
xf = workbook.register_new_font(font, xf)
|
907
|
+
new_style_index = workbook.register_new_xf(xf, get_col_style(col))
|
908
|
+
RubyXL::ColumnRange.update(col, @column_ranges, { 'style' => new_style_index })
|
909
|
+
|
910
|
+
@sheet_data.each { |row|
|
911
|
+
c = row[col]
|
912
|
+
font_switch(c, change_type, arg) unless c.nil?
|
913
|
+
}
|
914
|
+
end
|
915
|
+
|
916
|
+
#performs correct modification based on what type of change_type is specified
|
917
|
+
def font_switch(c,change_type,arg)
|
918
|
+
case change_type
|
919
|
+
when Worksheet::NAME
|
920
|
+
unless arg.is_a?String
|
921
|
+
raise 'Not a String'
|
922
|
+
end
|
923
|
+
c.change_font_name(arg)
|
924
|
+
when Worksheet::SIZE
|
925
|
+
unless arg.is_a?(Integer) || arg.is_a?(Float)
|
926
|
+
raise 'Not a Number'
|
927
|
+
end
|
928
|
+
c.change_font_size(arg)
|
929
|
+
when Worksheet::COLOR
|
930
|
+
Color.validate_color(arg)
|
931
|
+
c.change_font_color(arg)
|
932
|
+
when Worksheet::ITALICS
|
933
|
+
unless arg == !!arg
|
934
|
+
raise 'Not a boolean'
|
935
|
+
end
|
936
|
+
c.change_font_italics(arg)
|
937
|
+
when Worksheet::BOLD
|
938
|
+
unless arg == !!arg
|
939
|
+
raise 'Not a boolean'
|
940
|
+
end
|
941
|
+
c.change_font_bold(arg)
|
942
|
+
when Worksheet::UNDERLINE
|
943
|
+
unless arg == !!arg
|
944
|
+
raise 'Not a boolean'
|
945
|
+
end
|
946
|
+
c.change_font_underline(arg)
|
947
|
+
when Worksheet::STRIKETHROUGH
|
948
|
+
unless arg == !!arg
|
949
|
+
raise 'Not a boolean'
|
950
|
+
end
|
951
|
+
c.change_font_strikethrough(arg)
|
952
|
+
else
|
953
|
+
raise 'Invalid change_type'
|
954
|
+
end
|
955
|
+
end
|
956
|
+
|
957
|
+
# Ensures that cell with +row_index+ and +col_index+ exists in
|
958
|
+
# +sheet_data+ arrays, growing them up if necessary.
|
959
|
+
def ensure_cell_exists(row_index, col_index = 0)
|
960
|
+
# Writing anything to a cell in the array automatically creates all the members
|
961
|
+
# with lower indices, filling them with +nil+s. But, we can't just write +nil+
|
962
|
+
# to +col_index+ because it may be less than +size+! So we read from that index
|
963
|
+
# (if it didn't exist, we will get nil) and write right back.
|
964
|
+
@sheet_data.each { |r| r[col_index] = r[col_index] }
|
965
|
+
|
966
|
+
col_size = @sheet_data[0].size
|
967
|
+
|
968
|
+
# Doing +.downto()+ here so the reallocation of row array has to only happen once,
|
969
|
+
# when it is extended to max size; after that, we will be writing into existing
|
970
|
+
# (but empty) members. Additional checks are not necessary, because if +row_index+
|
971
|
+
# is less than +size+, then +.downto()+ will not execute, and if it equals +size+,
|
972
|
+
# then the block will be invoked exactly once, which takes care of the case when
|
973
|
+
# +row_index+ is greater than the current max index by exactly 1.
|
974
|
+
row_index.downto(@sheet_data.size) { |r| @sheet_data[r] = Array.new(col_size) }
|
975
|
+
end
|
976
|
+
|
977
|
+
# Helper method to get the style index for a row
|
978
|
+
def get_row_style(row)
|
979
|
+
if @row_styles[(row+1)].nil?
|
980
|
+
@row_styles[(row+1)] = {}
|
981
|
+
@row_styles[(row+1)][:style] = 0
|
982
|
+
@workbook.fonts[0].count += 1
|
983
|
+
end
|
984
|
+
return @row_styles[(row+1)][:style]
|
985
|
+
end
|
986
|
+
|
987
|
+
# Helper method to get the style index for a column
|
988
|
+
def get_col_style(col)
|
989
|
+
range = RubyXL::ColumnRange.find(col, @column_ranges)
|
990
|
+
(range && range.style_index) || 0
|
991
|
+
end
|
992
|
+
|
993
|
+
def get_col_xf(col)
|
994
|
+
@workbook.cell_xfs[get_col_style(col)]
|
995
|
+
end
|
996
|
+
|
997
|
+
def change_row_alignment(row,alignment,is_horizontal)
|
998
|
+
validate_workbook
|
999
|
+
validate_nonnegative(row)
|
1000
|
+
ensure_cell_exists(row)
|
1001
|
+
|
1002
|
+
if @row_styles[(row+1)].nil?
|
1003
|
+
@row_styles[(row+1)] = {}
|
1004
|
+
@row_styles[(row+1)][:style] = 0
|
1005
|
+
end
|
1006
|
+
|
1007
|
+
@row_styles[(row+1)][:style] =
|
1008
|
+
modify_alignment(@workbook,@row_styles[(row+1)][:style],is_horizontal,alignment)
|
1009
|
+
|
1010
|
+
@sheet_data[row].each do |c|
|
1011
|
+
unless c.nil?
|
1012
|
+
if is_horizontal
|
1013
|
+
c.change_horizontal_alignment(alignment)
|
1014
|
+
else
|
1015
|
+
c.change_vertical_alignment(alignment)
|
1016
|
+
end
|
1017
|
+
end
|
1018
|
+
end
|
1019
|
+
end
|
1020
|
+
|
1021
|
+
def change_column_alignment(col,alignment,is_horizontal)
|
1022
|
+
validate_workbook
|
1023
|
+
validate_nonnegative(col)
|
1024
|
+
ensure_cell_exists(0, col)
|
1025
|
+
|
1026
|
+
new_style_index = modify_alignment(@workbook, get_column_style_index(col), is_horizontal, alignment)
|
1027
|
+
RubyXL::ColumnRange.update(col, @column_ranges, { 'style' => new_style_index })
|
1028
|
+
|
1029
|
+
@sheet_data.each { |row|
|
1030
|
+
c = row[col]
|
1031
|
+
next if c.nil?
|
1032
|
+
if is_horizontal
|
1033
|
+
c.change_horizontal_alignment(alignment)
|
1034
|
+
else
|
1035
|
+
c.change_vertical_alignment(alignment)
|
1036
|
+
end
|
1037
|
+
}
|
1038
|
+
end
|
1039
|
+
|
1040
|
+
def change_row_border(row, direction, weight)
|
1041
|
+
validate_workbook
|
1042
|
+
validate_nonnegative(row)
|
1043
|
+
validate_border(weight)
|
1044
|
+
ensure_cell_exists(row)
|
1045
|
+
|
1046
|
+
xf = get_row_xf(row)
|
1047
|
+
border = @workbook.borders[xf.border_id].dup
|
1048
|
+
border.set_edge_style(direction, weight)
|
1049
|
+
|
1050
|
+
xf = workbook.register_new_border(border, xf)
|
1051
|
+
@row_styles[(row+1)][:style] = workbook.register_new_xf(xf, @row_styles[(row+1)][:style])
|
1052
|
+
|
1053
|
+
@sheet_data[row].each { |c|
|
1054
|
+
next if c.nil?
|
1055
|
+
case direction
|
1056
|
+
when :top then c.change_border_top(weight)
|
1057
|
+
when :left then c.change_border_left(weight)
|
1058
|
+
when :right then c.change_border_right(weight)
|
1059
|
+
when :bottom then c.change_border_bottom(weight)
|
1060
|
+
when :diagonal then c.change_border_diagonal(weight)
|
1061
|
+
else raise 'invalid direction'
|
1062
|
+
end
|
1063
|
+
}
|
1064
|
+
end
|
1065
|
+
|
1066
|
+
def change_column_border(col, direction, weight)
|
1067
|
+
col = Integer(col)
|
1068
|
+
validate_workbook
|
1069
|
+
validate_nonnegative(col)
|
1070
|
+
validate_border(weight)
|
1071
|
+
ensure_cell_exists(0, col)
|
1072
|
+
|
1073
|
+
xf = get_col_xf(col)
|
1074
|
+
border = @workbook.borders[xf.border_id].dup
|
1075
|
+
border.set_edge_style(direction, weight)
|
1076
|
+
|
1077
|
+
xf = workbook.register_new_border(border, get_col_xf(col))
|
1078
|
+
new_style_index = workbook.register_new_xf(xf, get_col_style(col))
|
1079
|
+
RubyXL::ColumnRange.update(col, @column_ranges, { 'style' => new_style_index })
|
1080
|
+
|
1081
|
+
@sheet_data.each { |row|
|
1082
|
+
c = row[col]
|
1083
|
+
next if c.nil?
|
1084
|
+
case direction
|
1085
|
+
when :top then c.change_border_top(weight)
|
1086
|
+
when :left then c.change_border_left(weight)
|
1087
|
+
when :right then c.change_border_right(weight)
|
1088
|
+
when :bottom then c.change_border_bottom(weight)
|
1089
|
+
when :diagonal then c.change_border_diagonal(weight)
|
1090
|
+
else raise 'invalid direction'
|
1091
|
+
end
|
1092
|
+
}
|
1093
|
+
end
|
1094
|
+
|
1095
|
+
def add_cell_style(row,column)
|
1096
|
+
xf = @workbook.cell_xfs[@sheet_data[row][column].style_index]
|
1097
|
+
@workbook.fonts[xf.font_id].count += 1
|
1098
|
+
@workbook.fills[xf.fill_id].count += 1
|
1099
|
+
@workbook.borders[xf.border_id].count += 1
|
1100
|
+
end
|
1101
|
+
|
1102
|
+
# finds first row which contains at least all strings in cells_content
|
1103
|
+
def find_first_row_with_content(cells_content)
|
1104
|
+
validate_workbook
|
1105
|
+
index = nil
|
1106
|
+
|
1107
|
+
@sheet_data.each_with_index do |row, index|
|
1108
|
+
cells_content = cells_content.map { |header| header.to_s.downcase.strip }
|
1109
|
+
original_cells_content = row.map { |cell| cell.nil? ? '' : cell.value.to_s.downcase.strip }
|
1110
|
+
if (cells_content & original_cells_content).size == cells_content.size
|
1111
|
+
return index
|
1112
|
+
end
|
1113
|
+
end
|
1114
|
+
return nil
|
1115
|
+
end
|
1116
|
+
|
1117
|
+
end #end class
|
1118
|
+
end
|