spreadsheet-excel 0.3.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. data/CHANGES +124 -0
  2. data/CVS/Entries +10 -0
  3. data/CVS/Repository +1 -0
  4. data/CVS/Root +1 -0
  5. data/README +69 -0
  6. data/doc/CVS/Entries +3 -0
  7. data/doc/CVS/Repository +1 -0
  8. data/doc/CVS/Root +1 -0
  9. data/doc/format.txt +330 -0
  10. data/doc/spreadsheet.txt +178 -0
  11. data/examples/CVS/Entries +3 -0
  12. data/examples/CVS/Repository +1 -0
  13. data/examples/CVS/Root +1 -0
  14. data/examples/example_basic.rb +27 -0
  15. data/examples/example_format.rb +69 -0
  16. data/lib/CVS/Entries +1 -0
  17. data/lib/CVS/Repository +1 -0
  18. data/lib/CVS/Root +1 -0
  19. data/lib/spreadsheet/CVS/Entries +7 -0
  20. data/lib/spreadsheet/CVS/Repository +1 -0
  21. data/lib/spreadsheet/CVS/Root +1 -0
  22. data/lib/spreadsheet/biffwriter.rb +46 -0
  23. data/lib/spreadsheet/excel.rb +13 -0
  24. data/lib/spreadsheet/format.rb +359 -0
  25. data/lib/spreadsheet/olewriter.rb +178 -0
  26. data/lib/spreadsheet/workbook.rb +279 -0
  27. data/lib/spreadsheet/worksheet.rb +449 -0
  28. data/test/CVS/Entries +9 -0
  29. data/test/CVS/Repository +1 -0
  30. data/test/CVS/Root +1 -0
  31. data/test/perl_output/CVS/Entries +10 -0
  32. data/test/perl_output/CVS/Repository +1 -0
  33. data/test/perl_output/CVS/Root +1 -0
  34. data/test/perl_output/README +31 -0
  35. data/test/perl_output/f_font_biff +0 -0
  36. data/test/perl_output/f_font_key +1 -0
  37. data/test/perl_output/f_xf_biff +0 -0
  38. data/test/perl_output/ole_write_header +0 -0
  39. data/test/perl_output/ws_colinfo +1 -0
  40. data/test/perl_output/ws_store_dimensions +1 -0
  41. data/test/perl_output/ws_store_selection +1 -0
  42. data/test/perl_output/ws_store_window2 +1 -0
  43. data/test/tc_all.rb +6 -0
  44. data/test/tc_biff.rb +62 -0
  45. data/test/tc_excel.rb +26 -0
  46. data/test/tc_format.rb +133 -0
  47. data/test/tc_ole.rb +125 -0
  48. data/test/tc_workbook.rb +71 -0
  49. data/test/tc_worksheet.rb +142 -0
  50. data/test/ts_all.rb +9 -0
  51. metadata +103 -0
@@ -0,0 +1,449 @@
1
+ class MaxSizeError < StandardError; end
2
+
3
+ class Worksheet < BIFFWriter
4
+
5
+ RowMax = 65536
6
+ ColMax = 256
7
+ StrMax = 255
8
+ Buffer = 4096
9
+
10
+ attr_reader :name, :xf_index
11
+ attr_accessor :index, :colinfo, :selection, :offset
12
+
13
+ def initialize(name, index=0, active_sheet=0, first_sheet=0, url_format=nil)
14
+ super(name,index)
15
+
16
+ @name = name
17
+ @index = index
18
+ @active_sheet = active_sheet
19
+ @first_sheet = first_sheet
20
+ @url_format = url_format
21
+
22
+ @offset = 0
23
+
24
+ @dim_rowmin = RowMax + 1
25
+ @dim_rowmax = 0
26
+ @dim_colmin = ColMax + 1
27
+ @dim_colmax = 0
28
+
29
+ @colinfo = []
30
+ @selection = [0,0]
31
+ @row_formats = {}
32
+ @column_formats = {}
33
+ @outline_row_level = 0
34
+ end
35
+
36
+ def close
37
+ store_dimensions
38
+
39
+ unless @colinfo.empty?
40
+ while @colinfo.length > 0
41
+ store_colinfo(*@colinfo.pop)
42
+ end
43
+ store_defcol
44
+ end
45
+
46
+ store_guts
47
+ store_bof(0x0010)
48
+
49
+ store_window2
50
+ store_selection(*@selection)
51
+ store_eof
52
+ end
53
+
54
+ def data
55
+ if @data && @data.length > 0
56
+ tmp = @data
57
+ @data = ""
58
+ return tmp
59
+ end
60
+ end
61
+
62
+ def activate
63
+ @active_sheet = @index
64
+ end
65
+
66
+ def set_first_sheet
67
+ @first_sheet = @index
68
+ end
69
+
70
+ def column(*range)
71
+ @colinfo = *range
72
+ end
73
+
74
+ def store_dimensions
75
+ record = 0x0000
76
+ length = 0x000A
77
+ reserved = 0x0000
78
+
79
+ header = [record, length].pack("vv")
80
+ fields = [@dim_rowmin, @dim_rowmax, @dim_colmin, @dim_colmax, reserved]
81
+ data = fields.pack("vvvvv")
82
+
83
+ prepend(header, data)
84
+ end
85
+
86
+ def store_guts
87
+ record = 0x0080 # record identifier
88
+ length = 0x0008 # bytes to follow
89
+
90
+ dxRwGut = 0x0000 # size of row gutter
91
+ dxColGut = 0x0000 # size of col gutter
92
+
93
+ row_level = @outline_row_level
94
+ col_level = 0
95
+
96
+ @colinfo.each do |colinfo|
97
+ next if colinfo.length < 6
98
+ col_level = colinfo[5] if colinfo[5] > col_level
99
+ end
100
+
101
+ col_level = 0 if col_level < 0
102
+ col_level = 7 if col_level > 7
103
+
104
+ row_level += 1 if row_level > 0
105
+ col_level += 1 if col_level > 0
106
+
107
+ header = [record, length].pack("vv")
108
+ fields = [dxRwGut, dxColGut, row_level, col_level]
109
+ data = fields.pack("vvvv")
110
+
111
+ prepend(header, data)
112
+ end
113
+
114
+ def store_window2
115
+ record = 0x023E
116
+ length = 0x000A
117
+
118
+ grbit = 0x00B6
119
+ rwTop = 0x0000
120
+ colLeft = 0x0000
121
+ rgbHdr = 0x00000000
122
+
123
+ if @active_sheet == @index
124
+ grbit = 0x06B6
125
+ end
126
+
127
+ header = [record, length].pack("vv")
128
+ data = [grbit, rwTop, colLeft, rgbHdr].pack("vvvV")
129
+
130
+ append(header, data)
131
+ end
132
+
133
+ def store_defcol
134
+ record = 0x0055
135
+ length = 0x0002
136
+
137
+ colwidth = 0x0008
138
+
139
+ header = [record, length].pack("vv")
140
+ data = [colwidth].pack("v")
141
+
142
+ prepend(header, data)
143
+ end
144
+
145
+ def store_colinfo(first=0, last=0, coldx=8.43, ixfe=0x0F, grbit=0)
146
+ record = 0x007D
147
+ length = 0x000B
148
+
149
+ coldx += 0.72
150
+ coldx *= 256
151
+ reserved = 0x00
152
+
153
+ if ixfe.kind_of?(Format)
154
+ ixfe = ixfe.xf_index
155
+ end
156
+
157
+ header = [record, length].pack("vv")
158
+ data = [first, last, coldx, ixfe, grbit, reserved].pack("vvvvvC")
159
+
160
+ prepend(header,data)
161
+ end
162
+
163
+ # I think this may have problems
164
+ def store_selection(row=0, col=0, row_last=0, col_last=0)
165
+ record = 0x001D
166
+ length = 0x000F
167
+
168
+ pnn = 3
169
+ rwAct = row
170
+ colAct = col
171
+ irefAct = 0
172
+ cref = 1
173
+
174
+ rwFirst = row
175
+ colFirst = col
176
+
177
+ if row_last != 0
178
+ rwLast = row_last
179
+ else
180
+ rwLast = rwFirst
181
+ end
182
+
183
+ if col_last != 0
184
+ colLast = col_last
185
+ else
186
+ colLast = colFirst
187
+ end
188
+
189
+ if rwFirst > rwLast
190
+ rwFirst,rwLast = rwLast,rwFirst
191
+ end
192
+
193
+ if colFirst > colLast
194
+ colFirst,colLast = colLast,colFirst
195
+ end
196
+
197
+ header = [record, length].pack("vv")
198
+ fields = [pnn,rwAct,colAct,irefAct,cref,rwFirst,rwLast,colFirst,colLast]
199
+ data = fields.pack("CvvvvvvCC")
200
+
201
+ append(header, data)
202
+ end
203
+
204
+ def write(row, col, data=nil, format=nil)
205
+ if data.nil?
206
+ write_blank(row, col, format)
207
+ elsif data.kind_of?(Array)
208
+ write_row(row, col, data, format)
209
+ elsif data.kind_of?(Numeric)
210
+ write_number(row, col, data, format)
211
+ else
212
+ write_string(row, col, data, format)
213
+ end
214
+ end
215
+
216
+ def write_row(row, col, tokens=nil, format=nil)
217
+ if tokens.nil?
218
+ write(row,col,tokens,format)
219
+ return
220
+ end
221
+
222
+ tokens.each{ |token|
223
+ if token.kind_of?(Array)
224
+ write_column(row,col,token,format)
225
+ else
226
+ write(row,col,token,format)
227
+ end
228
+ col += 1
229
+ }
230
+ end
231
+
232
+ def write_column(row, col, tokens=nil, format=nil)
233
+ if tokens.nil?
234
+ write(row,col,tokens,format)
235
+ return
236
+ end
237
+
238
+ tokens.each{ |token|
239
+ if token.kind_of?(Array)
240
+ write_row(row, col, token, format)
241
+ else
242
+ write(row, col, token, format)
243
+ end
244
+ row += 1
245
+ }
246
+ end
247
+
248
+ def write_number(row, col, num, format=nil)
249
+ record = 0x0203
250
+ length = 0x000E
251
+
252
+ xf_index = XF(row,col,format)
253
+
254
+ raise MaxSizeError if row >= RowMax
255
+ raise MaxSizeError if col >= ColMax
256
+
257
+ @dim_rowmin = row if row < @dim_rowmin
258
+ @dim_rowmax = row if row > @dim_rowmax
259
+ @dim_colmin = col if col < @dim_colmin
260
+ @dim_colmax = col if col > @dim_colmax
261
+
262
+ header = [record,length].pack("vv")
263
+ data = [row,col,xf_index].pack("vvv")
264
+ xl_double = [num].pack("d")
265
+
266
+ if BigEndian
267
+ xl_double.reverse!
268
+ end
269
+
270
+ append(header,data,xl_double)
271
+ end
272
+
273
+ def write_string(row, col, str, format)
274
+ record = 0x0204
275
+ length = 0x0008 + str.length
276
+
277
+ xf_index = XF(row, col, format)
278
+
279
+ strlen = str.length
280
+
281
+ raise MaxSizeError if row >= RowMax
282
+ raise MaxSizeError if col >= ColMax
283
+
284
+ @dim_rowmin = row if row < @dim_rowmin
285
+ @dim_rowmax = row if row > @dim_rowmax
286
+ @dim_colmin = col if col < @dim_colmin
287
+ @dim_colmax = col if col > @dim_colmax
288
+
289
+ # Truncate strings over 255 characters
290
+ if strlen > StrMax
291
+ str = str[0..StrMax-1]
292
+ length = 0x0008 + StrMax
293
+ strlen = StrMax
294
+ end
295
+
296
+ header = [record, length].pack("vv")
297
+ data = [row, col, xf_index, strlen].pack("vvvv")
298
+
299
+ append(header, data, str)
300
+ end
301
+
302
+ # Write a blank cell to the specified row and column (zero indexed).
303
+ # A blank cell is used to specify formatting without adding data.
304
+ def write_blank(row, col, format)
305
+ record = 0x0201
306
+ length = 0x0006
307
+
308
+ xf_index = XF(row, col, format)
309
+
310
+ raise MaxSizeError if row >= RowMax
311
+ raise MaxSizeError if col >= ColMax
312
+
313
+ @dim_rowmin = row if row < @dim_rowmin
314
+ @dim_rowmax = row if row > @dim_rowmax
315
+ @dim_colmin = col if col < @dim_colmin
316
+ @dim_colmax = col if col > @dim_colmax
317
+
318
+ header = [record, length].pack("vv")
319
+ data = [row, col, xf_index].pack("vvv")
320
+
321
+ append(header, data)
322
+ end
323
+
324
+ # Format a rectangular section of cells. Note that you should call this
325
+ # method only after you have written data to it, or the formatting will
326
+ # be lost.
327
+ def format_rectangle(x1, y1, x2, y2, format)
328
+ raise TypeError, "invalid format" unless format.kind_of?(Format)
329
+
330
+ x1.upto(x2){ |row|
331
+ y1.upto(y2){ |col|
332
+ write_blank(row, col, format)
333
+ }
334
+ }
335
+ end
336
+
337
+ def write_url(row, col, url, string=url, format=nil)
338
+ record = 0x01B8
339
+ length = 0x0034 + 2 * (1+url.length)
340
+
341
+ write_string(row,col,string,format)
342
+
343
+ header = [record, length].pack("vv")
344
+ data = [row, row, col, col].pack("vvvv")
345
+
346
+ unknown = "D0C9EA79F9BACE118C8200AA004BA90B02000000"
347
+ unknown += "03000000E0C9EA79F9BACE118C8200AA004BA90B"
348
+
349
+ stream = [unknown].pack("H*")
350
+
351
+ url = url.split('').join("\0")
352
+ url += "\0\0\0"
353
+
354
+ len = url.length
355
+ url_len = [len].pack("V")
356
+
357
+ append(header + data)
358
+ append(stream)
359
+ append(url_len)
360
+ append(url)
361
+ end
362
+
363
+ def format_row(row, height=nil, format=nil, hidden=false, level=0)
364
+ unless row.kind_of?(Range) || row.kind_of?(Integer)
365
+ raise TypeError, 'row must be an Integer or Range'
366
+ end
367
+
368
+ if hidden.nil? || hidden == false
369
+ hidden = 0
370
+ end
371
+
372
+ record = 0x0208 # record identifier
373
+ length = 0x0010 # number of bytes to follow
374
+
375
+ col_first = 0x0000 # first defined column
376
+ col_last = 0x0000 # last defined column
377
+ irwmac = 0x0000 # used by Excel to optimize loading
378
+ reserved = 0x0000 # reservered
379
+ grbit = 0x0000 # option flags
380
+ xf_index = nil
381
+
382
+ grbit |= level
383
+ if hidden > 0
384
+ grbit |= 0x0020
385
+ end
386
+ grbit |= 0x0040 #unsynched
387
+ grbit |= 0x0100
388
+
389
+ @outline_row_level = level if level > @outline_row_level
390
+
391
+ if format.nil?
392
+ xf_index = 0x0F
393
+ else
394
+ xf_index = format.xf_index
395
+ grbit |= 0x80
396
+ end
397
+
398
+ if height.nil?
399
+ height = 0xff
400
+ else
401
+ height = height * 20
402
+ end
403
+
404
+ row = row..row if row.kind_of?(Fixnum) # Avoid an if..else clause :)
405
+ row.each{ |r|
406
+ header = [record, length].pack("vv")
407
+ fields = [r,col_first,col_last,height,irwmac,reserved,grbit,xf_index]
408
+ data = fields.pack("vvvvvvvv")
409
+
410
+ @row_formats[r] = format if format
411
+ append(header + data)
412
+ }
413
+ end
414
+
415
+ # private - adapted from .37 of Spreadsheet::WriteExcel
416
+ def XF(row, col, xf=nil)
417
+ if xf.kind_of?(Format)
418
+ return xf.xf_index
419
+ elsif @row_formats.has_key?(row)
420
+ return @row_formats[row].xf_index
421
+ elsif @column_formats.has_key?(col)
422
+ return @column_formats[col].xf_index
423
+ else
424
+ return 0x0F
425
+ end
426
+ end
427
+
428
+ def format_column(column, width=nil, format=nil)
429
+ unless column.kind_of?(Range) || column.kind_of?(Fixnum)
430
+ raise TypeError
431
+ end
432
+
433
+ width = 8.43 if width.nil?
434
+ column = column..column if column.kind_of?(Fixnum)
435
+
436
+ column.each{ |e|
437
+ @column_formats[e] = format unless format.nil?
438
+ }
439
+ @colinfo.push([column.begin, column.end, width, format])
440
+ end
441
+
442
+ end
443
+ =begin
444
+ = Differences between Worksheet.pm and worksheet.rb
445
+ ---write_url
446
+ I made this a public method to be called directly by the user if they want
447
+ to write a url string. A variable number of arguments made it a pain to
448
+ integrate into the 'write' method.
449
+ =end
data/test/CVS/Entries ADDED
@@ -0,0 +1,9 @@
1
+ /tc_all.rb/1.1/Sun Nov 23 03:46:55 2003//
2
+ /tc_biff.rb/1.3/Wed Oct 12 21:33:36 2005//
3
+ /tc_excel.rb/1.7/Fri Feb 17 03:36:41 2006//
4
+ /tc_format.rb/1.4/Wed Oct 12 21:34:22 2005//
5
+ /tc_ole.rb/1.4/Wed Oct 12 21:33:05 2005//
6
+ /tc_workbook.rb/1.2/Wed Oct 12 21:34:46 2005//
7
+ /tc_worksheet.rb/1.3/Wed Oct 12 21:35:11 2005//
8
+ /ts_all.rb/1.2/Wed Oct 12 21:35:30 2005//
9
+ D/perl_output////