ru_excel 0.0.6
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.
- data/README +21 -0
- data/Rakefile +30 -0
- data/VERSION +1 -0
- data/examples/big-16Mb_test.rb +35 -0
- data/examples/test_multiline.rb +13 -0
- data/examples/test_utf8.rb +12 -0
- data/lib/ru_excel/biff_records.rb +1930 -0
- data/lib/ru_excel/bitmap.rb +222 -0
- data/lib/ru_excel/cell.rb +57 -0
- data/lib/ru_excel/column.rb +31 -0
- data/lib/ru_excel/compound_doc.rb +268 -0
- data/lib/ru_excel/deco.rb +156 -0
- data/lib/ru_excel/excel_magic.rb +1019 -0
- data/lib/ru_excel/formatting.rb +231 -0
- data/lib/ru_excel/row.rb +170 -0
- data/lib/ru_excel/style.rb +135 -0
- data/lib/ru_excel/unicode_utils.rb +73 -0
- data/lib/ru_excel/workbook.rb +365 -0
- data/lib/ru_excel/worksheet.rb +466 -0
- data/lib/ru_excel.rb +16 -0
- metadata +73 -0
@@ -0,0 +1,365 @@
|
|
1
|
+
=begin
|
2
|
+
Record Order in BIFF8
|
3
|
+
Workbook Globals Substream
|
4
|
+
BOF Type = workbook globals
|
5
|
+
Interface Header
|
6
|
+
MMS
|
7
|
+
Interface End
|
8
|
+
WRITEACCESS
|
9
|
+
CODEPAGE
|
10
|
+
DSF
|
11
|
+
TABID
|
12
|
+
FNGROUPCOUNT
|
13
|
+
Workbook Protection Block
|
14
|
+
WINDOWPROTECT
|
15
|
+
PROTECT
|
16
|
+
PASSWORD
|
17
|
+
PROT4REV
|
18
|
+
PROT4REVPASS
|
19
|
+
BACKUP
|
20
|
+
HIDEOBJ
|
21
|
+
WINDOW1
|
22
|
+
DATEMODE
|
23
|
+
PRECISION
|
24
|
+
REFRESHALL
|
25
|
+
BOOKBOOL
|
26
|
+
FONT +
|
27
|
+
FORMAT *
|
28
|
+
XF +
|
29
|
+
STYLE +
|
30
|
+
? PALETTE
|
31
|
+
USESELFS
|
32
|
+
|
33
|
+
BOUNDSHEET +
|
34
|
+
|
35
|
+
COUNTRY
|
36
|
+
? Link Table
|
37
|
+
SST
|
38
|
+
ExtSST
|
39
|
+
EOF
|
40
|
+
=end
|
41
|
+
dir = File.dirname(__FILE__)
|
42
|
+
require dir + '/style'
|
43
|
+
require dir + '/deco'
|
44
|
+
require dir + '/worksheet'
|
45
|
+
require dir + '/compound_doc'
|
46
|
+
|
47
|
+
module Excel
|
48
|
+
class Workbook
|
49
|
+
extend Deco
|
50
|
+
#################################################################
|
51
|
+
## Constructor
|
52
|
+
#################################################################
|
53
|
+
def initialize
|
54
|
+
@owner = 'None'
|
55
|
+
@country_code = 0x07
|
56
|
+
@wnd_protect = 0
|
57
|
+
@obj_protect = 0
|
58
|
+
@protect = 0
|
59
|
+
@backup_on_save = 0
|
60
|
+
# for WINDOW1 record
|
61
|
+
@hpos_twips = 0x01E0
|
62
|
+
@vpos_twips = 0x005A
|
63
|
+
@width_twips = 0x3FCF
|
64
|
+
@height_twips = 0x2A4E
|
65
|
+
|
66
|
+
@active_sheet = 0
|
67
|
+
@first_tab_index = 0
|
68
|
+
@selected_tabs = 0x01
|
69
|
+
@tab_width_twips = 0x0258
|
70
|
+
|
71
|
+
@wnd_hidden = 0
|
72
|
+
@wnd_mini = 0
|
73
|
+
@hscroll_visible = 1
|
74
|
+
@vscroll_visible = 1
|
75
|
+
@tabs_visible = 1
|
76
|
+
|
77
|
+
@styles = StyleCollection.new()
|
78
|
+
|
79
|
+
@dates_1904 = 0
|
80
|
+
@use_cell_values = 1
|
81
|
+
|
82
|
+
@sst = SharedStringTable.new()
|
83
|
+
|
84
|
+
@worksheets = []
|
85
|
+
end
|
86
|
+
#################################################################
|
87
|
+
## Properties, "getters", "setters"
|
88
|
+
#################################################################
|
89
|
+
|
90
|
+
string_accessor :owner
|
91
|
+
int_accessor :country_code
|
92
|
+
bool_accessor :wnd_protect, :protect, :backup_on_save
|
93
|
+
|
94
|
+
short_accessor :hpos, :vpos, :width, :height, :tab_width
|
95
|
+
|
96
|
+
def active_sheet=(value)
|
97
|
+
@first_tab_index = @active_sheet = value.to_i & 0xFFFF
|
98
|
+
end
|
99
|
+
attr_reader :active_sheet
|
100
|
+
|
101
|
+
def wnd_visible=(value)
|
102
|
+
@wnd_hidden = !value
|
103
|
+
end
|
104
|
+
def wnd_visible
|
105
|
+
!@wnd_hidden
|
106
|
+
end
|
107
|
+
bool_accessor :wnd_visible
|
108
|
+
|
109
|
+
bool_int_accessor :wnd_mini, :hscroll_visible, :vscroll_visible, :obj_protect
|
110
|
+
bool_int_accessor :tabs_visible, :dates_1904, :use_cell_values
|
111
|
+
|
112
|
+
def default_style
|
113
|
+
@styles.default_style
|
114
|
+
end
|
115
|
+
|
116
|
+
##################################################################
|
117
|
+
## Methods
|
118
|
+
##################################################################
|
119
|
+
|
120
|
+
def add_style(style)
|
121
|
+
@styles.add(style)
|
122
|
+
end
|
123
|
+
|
124
|
+
def add_str(s)
|
125
|
+
@sst.add_str(s)
|
126
|
+
end
|
127
|
+
|
128
|
+
def str_index(s)
|
129
|
+
@sst.str_index(s)
|
130
|
+
end
|
131
|
+
|
132
|
+
def add_sheet(sheetname)
|
133
|
+
@worksheets << Worksheet.new(sheetname, self)
|
134
|
+
@worksheets[-1]
|
135
|
+
end
|
136
|
+
|
137
|
+
def get_sheet(sheetnum)
|
138
|
+
@worksheets[sheetnum]
|
139
|
+
end
|
140
|
+
|
141
|
+
##################################################################
|
142
|
+
## BIFF records generation
|
143
|
+
##################################################################
|
144
|
+
|
145
|
+
def _bof_rec
|
146
|
+
BiffRecord.biff8BOFRecord(BiffRecord::BOOK_GLOBAL)
|
147
|
+
end
|
148
|
+
|
149
|
+
def _eof_rec
|
150
|
+
BiffRecord.eofRecord()
|
151
|
+
end
|
152
|
+
|
153
|
+
def _intf_hdr_rec
|
154
|
+
BiffRecord.interaceHdrRecord()
|
155
|
+
end
|
156
|
+
|
157
|
+
def _intf_end_rec
|
158
|
+
BiffRecord.interaceEndRecord()
|
159
|
+
end
|
160
|
+
|
161
|
+
def _intf_mms_rec
|
162
|
+
BiffRecord.mmsRecord()
|
163
|
+
end
|
164
|
+
|
165
|
+
def _write_access_rec
|
166
|
+
BiffRecord.writeAccessRecord(@owner)
|
167
|
+
end
|
168
|
+
|
169
|
+
def _wnd_protect_rec
|
170
|
+
BiffRecord.windowProtectRecord(@wnd_protect)
|
171
|
+
end
|
172
|
+
|
173
|
+
def _obj_protect_rec
|
174
|
+
BiffRecord.objectProtectRecord(@obj_protect)
|
175
|
+
end
|
176
|
+
|
177
|
+
def _protect_rec
|
178
|
+
BiffRecord.protectRecord(@protect)
|
179
|
+
end
|
180
|
+
|
181
|
+
def _password_rec
|
182
|
+
BiffRecord.passwordRecord()
|
183
|
+
end
|
184
|
+
|
185
|
+
def _prot4rev_rec
|
186
|
+
BiffRecord.prot4RevRecord()
|
187
|
+
end
|
188
|
+
|
189
|
+
def _prot4rev_pass_rec
|
190
|
+
BiffRecord.prot4RevPassRecord()
|
191
|
+
end
|
192
|
+
|
193
|
+
def _backup_rec
|
194
|
+
BiffRecord.backupRecord(@backup_on_save)
|
195
|
+
end
|
196
|
+
|
197
|
+
def _hide_obj_rec
|
198
|
+
BiffRecord.hideObjRecord()
|
199
|
+
end
|
200
|
+
|
201
|
+
def _window1_rec
|
202
|
+
flags = 0
|
203
|
+
flags |= (@wnd_hidden) << 0
|
204
|
+
flags |= (@wnd_mini) << 1
|
205
|
+
flags |= (@hscroll_visible) << 3
|
206
|
+
flags |= (@vscroll_visible) << 4
|
207
|
+
flags |= (@tabs_visible) << 5
|
208
|
+
|
209
|
+
BiffRecord.window1Record(@hpos_twips, @vpos_twips,
|
210
|
+
@width_twips, @height_twips,
|
211
|
+
flags,
|
212
|
+
@active_sheet, @first_tab_index,
|
213
|
+
@selected_tabs, @tab_width_twips)
|
214
|
+
end
|
215
|
+
|
216
|
+
def _codepage_rec
|
217
|
+
BiffRecord.codepageBiff8Record()
|
218
|
+
end
|
219
|
+
|
220
|
+
def _country_rec
|
221
|
+
BiffRecord.countryRecord(@country_code, @country_code)
|
222
|
+
end
|
223
|
+
|
224
|
+
def _dsf_rec
|
225
|
+
BiffRecord.dsfRecord()
|
226
|
+
end
|
227
|
+
|
228
|
+
def _tabid_rec
|
229
|
+
BiffRecord.tabIDRecord(@worksheets.length)
|
230
|
+
end
|
231
|
+
def _fngroupcount_rec
|
232
|
+
BiffRecord.fnGroupCountRecord()
|
233
|
+
end
|
234
|
+
def _datemode_rec
|
235
|
+
BiffRecord.dateModeRecord(@dates_1904)
|
236
|
+
end
|
237
|
+
def _precision_rec
|
238
|
+
BiffRecord.precisionRecord(@use_cell_values)
|
239
|
+
end
|
240
|
+
def _refresh_all_rec
|
241
|
+
BiffRecord.refreshAllRecord()
|
242
|
+
end
|
243
|
+
def _bookbool_rec
|
244
|
+
BiffRecord.bookBoolRecord()
|
245
|
+
end
|
246
|
+
def _all_fonts_num_formats_xf_styles_rec
|
247
|
+
@styles.get_biff_data()
|
248
|
+
end
|
249
|
+
def _palette_rec
|
250
|
+
''
|
251
|
+
end
|
252
|
+
def _useselfs_rec
|
253
|
+
BiffRecord.useSelfsRecord()
|
254
|
+
end
|
255
|
+
def _boundsheets_rec(data_len_before, data_len_after, sheet_biff_lens)
|
256
|
+
# .................................
|
257
|
+
# BOUNDSEHEET0
|
258
|
+
# BOUNDSEHEET1
|
259
|
+
# BOUNDSEHEET2
|
260
|
+
# ..................................
|
261
|
+
# WORKSHEET0
|
262
|
+
# WORKSHEET1
|
263
|
+
# WORKSHEET2
|
264
|
+
boundsheets_len = 0
|
265
|
+
for sheet in @worksheets
|
266
|
+
boundsheets_len += BiffRecord.boundSheetRecord(0x00, sheet.hidden, sheet.name).length
|
267
|
+
end
|
268
|
+
|
269
|
+
start = data_len_before + boundsheets_len + data_len_after
|
270
|
+
|
271
|
+
result = ''
|
272
|
+
for sheet_biff_len, sheet in sheet_biff_lens.zip(@worksheets)
|
273
|
+
result << BiffRecord.boundSheetRecord(start, sheet.hidden, sheet.name)
|
274
|
+
start += sheet_biff_len
|
275
|
+
end
|
276
|
+
result
|
277
|
+
end
|
278
|
+
|
279
|
+
def _all_links_rec
|
280
|
+
''
|
281
|
+
end
|
282
|
+
|
283
|
+
def _sst_rec
|
284
|
+
@sst.get_biff_record()
|
285
|
+
end
|
286
|
+
|
287
|
+
def _ext_sst_rec(abs_stream_pos)
|
288
|
+
''
|
289
|
+
#BiffRecord.ExtSSTRecord(abs_stream_pos, @sst_record.str_placement,
|
290
|
+
#@sst_record.portions_len)
|
291
|
+
end
|
292
|
+
|
293
|
+
def get_biff_data
|
294
|
+
before = ''
|
295
|
+
before << _bof_rec()
|
296
|
+
before << _intf_hdr_rec()
|
297
|
+
before << _intf_mms_rec()
|
298
|
+
before << _intf_end_rec()
|
299
|
+
before << _write_access_rec()
|
300
|
+
before << _codepage_rec()
|
301
|
+
before << _dsf_rec()
|
302
|
+
before << _tabid_rec()
|
303
|
+
before << _fngroupcount_rec()
|
304
|
+
before << _wnd_protect_rec()
|
305
|
+
before << _protect_rec()
|
306
|
+
before << _obj_protect_rec()
|
307
|
+
before << _password_rec()
|
308
|
+
before << _prot4rev_rec()
|
309
|
+
before << _prot4rev_pass_rec()
|
310
|
+
before << _backup_rec()
|
311
|
+
before << _hide_obj_rec()
|
312
|
+
before << _window1_rec()
|
313
|
+
before << _datemode_rec()
|
314
|
+
before << _precision_rec()
|
315
|
+
before << _refresh_all_rec()
|
316
|
+
before << _bookbool_rec()
|
317
|
+
before << _all_fonts_num_formats_xf_styles_rec()
|
318
|
+
before << _palette_rec()
|
319
|
+
before << _useselfs_rec()
|
320
|
+
|
321
|
+
country = _country_rec()
|
322
|
+
all_links = _all_links_rec()
|
323
|
+
|
324
|
+
shared_str_table = _sst_rec()
|
325
|
+
after = country + all_links + shared_str_table
|
326
|
+
|
327
|
+
ext_sst = _ext_sst_rec(0) # need fake cause we need calc stream pos
|
328
|
+
eof = _eof_rec()
|
329
|
+
@worksheets[@active_sheet].selected = true if @worksheets.length > 0
|
330
|
+
sheets = ''
|
331
|
+
sheet_biff_lens = []
|
332
|
+
for sheet in @worksheets
|
333
|
+
data = sheet.get_biff_data()
|
334
|
+
sheets << data
|
335
|
+
sheet_biff_lens << data.length
|
336
|
+
end
|
337
|
+
|
338
|
+
bundlesheets = _boundsheets_rec(before.length, after.length+ext_sst.length+eof.length, sheet_biff_lens)
|
339
|
+
|
340
|
+
sst_stream_pos = before.length + bundlesheets.length + country.length + all_links.length
|
341
|
+
ext_sst = _ext_sst_rec(sst_stream_pos)
|
342
|
+
|
343
|
+
before + bundlesheets + after + ext_sst + eof + sheets
|
344
|
+
end
|
345
|
+
|
346
|
+
def save(file)
|
347
|
+
doc = XlsDoc.new()
|
348
|
+
doc.save(file, get_biff_data())
|
349
|
+
end
|
350
|
+
|
351
|
+
def binary
|
352
|
+
doc = XlsDoc.new()
|
353
|
+
doc.binary(get_biff_data())
|
354
|
+
end
|
355
|
+
end
|
356
|
+
end
|
357
|
+
|
358
|
+
if $0 == __FILE__
|
359
|
+
wb = Excel::Workbook.new()
|
360
|
+
wb.add_str('s')
|
361
|
+
wb.add_str('sssssss')
|
362
|
+
f = File.open('workbook1.bin', 'wb')
|
363
|
+
f.write(wb.get_biff_data())
|
364
|
+
f.close()
|
365
|
+
end
|