ld 0.1.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/.gitignore +9 -0
- data/.idea/.rakeTasks +7 -0
- data/.idea/encodings.xml +4 -0
- data/.idea/ld.iml +17 -0
- data/.idea/misc.xml +4 -0
- data/.idea/modules.xml +8 -0
- data/.idea/scopes/scope_settings.xml +5 -0
- data/.idea/vcs.xml +6 -0
- data/.idea/workspace.xml +49 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +41 -0
- data/Rakefile +2 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/ld.gemspec +35 -0
- data/lib/ld/dir.rb +123 -0
- data/lib/ld/excel.rb +623 -0
- data/lib/ld/file.rb +82 -0
- data/lib/ld/node.rb +13 -0
- data/lib/ld/nodes.rb +33 -0
- data/lib/ld/tree.rb +39 -0
- data/lib/ld/version.rb +3 -0
- data/lib/ld.rb +32 -0
- metadata +98 -0
data/lib/ld/excel.rb
ADDED
@@ -0,0 +1,623 @@
|
|
1
|
+
require 'spreadsheet'
|
2
|
+
Spreadsheet.client_encoding = 'UTF-8'
|
3
|
+
|
4
|
+
class Ld::Excel
|
5
|
+
attr_accessor :excel,:path,:basename,:sheets,:sheet,:scope_arrs,:mappings,:bean,:beans
|
6
|
+
attr_accessor :format
|
7
|
+
|
8
|
+
@@hz ||= ".xls"
|
9
|
+
ZIMU ||= {}
|
10
|
+
|
11
|
+
if ZIMU.empty?
|
12
|
+
flag = 'A'
|
13
|
+
0.upto(9999) do |i|
|
14
|
+
ZIMU.store(flag,i)
|
15
|
+
flag = flag.succ
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# 构造函数,如果未传path则是创建一个新的excel, 如果传了path,则打开这个excel,不过打开前会验证后缀与是否存在
|
20
|
+
def initialize(path = nil)
|
21
|
+
if path!=nil
|
22
|
+
if path.match(/.xls$/)!=nil
|
23
|
+
if File::exist? path
|
24
|
+
@excel = Spreadsheet.open path
|
25
|
+
@path = path
|
26
|
+
puts "打开文件: #{path}"
|
27
|
+
else
|
28
|
+
raise "文件不存在: #{path}"
|
29
|
+
end
|
30
|
+
else
|
31
|
+
raise "只能打开.xls结尾的文件"
|
32
|
+
end
|
33
|
+
else
|
34
|
+
@excel = Spreadsheet::Workbook.new
|
35
|
+
puts "创建新的Excel实例"
|
36
|
+
end
|
37
|
+
@sheets = {}
|
38
|
+
@sheet = nil
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.open(path)
|
42
|
+
self.new(path)
|
43
|
+
end
|
44
|
+
|
45
|
+
# 获取一页
|
46
|
+
def open_sheet sheet_name
|
47
|
+
@sheet = @excel.worksheet sheet_name
|
48
|
+
if @sheet == nil
|
49
|
+
raise "未找到 sheet #{sheet_name}"
|
50
|
+
else
|
51
|
+
# puts "sheet #{sheet_name}"
|
52
|
+
end
|
53
|
+
self
|
54
|
+
end
|
55
|
+
|
56
|
+
# 获取所有页
|
57
|
+
def get_sheets
|
58
|
+
@sheets = @excel.worksheets
|
59
|
+
puts "返回 #{@sheets.size} 页"
|
60
|
+
self
|
61
|
+
end
|
62
|
+
|
63
|
+
# 创建新页(先查有没有该页)
|
64
|
+
def new_sheet(sheet_name)
|
65
|
+
@sheet = @excel.create_worksheet(:name => sheet_name)
|
66
|
+
# puts "创建了一页 #{sheet_name}"
|
67
|
+
self
|
68
|
+
end
|
69
|
+
|
70
|
+
# 读一个单元格
|
71
|
+
def read_location(location,parse = true)
|
72
|
+
l = parse_location(location)
|
73
|
+
unit = read_unit_by_xy(l[:r],l[:c],parse)
|
74
|
+
# puts ""
|
75
|
+
end
|
76
|
+
|
77
|
+
# 读一个单元格2
|
78
|
+
def read_sheet_location(location,parse = true)
|
79
|
+
open_sheet location.split('?')[0]
|
80
|
+
read_location location.split('?')[1]
|
81
|
+
end
|
82
|
+
|
83
|
+
|
84
|
+
# 刷新excel中的sheet
|
85
|
+
def open_new
|
86
|
+
excel_new = Excel.open @path
|
87
|
+
end
|
88
|
+
|
89
|
+
# 读很多个location链,返回二维数组
|
90
|
+
def read_location_list_arr(location_list_arr_str)
|
91
|
+
units_arr = []
|
92
|
+
location_list_arr_str.split(',').each do |location_list|
|
93
|
+
units = read_location_list(location_list)
|
94
|
+
units_arr << units
|
95
|
+
end
|
96
|
+
units_arr
|
97
|
+
end
|
98
|
+
|
99
|
+
# 读取一个location链 ,返回一维数组
|
100
|
+
def read_sheet_locations(locations_config,parse = true)
|
101
|
+
unit_list = []
|
102
|
+
open_sheet locations_config.split('?')[0]
|
103
|
+
locations_config.split('?')[1].split('.').each do |location|
|
104
|
+
l = parse_location(location)
|
105
|
+
unit = read_unit_by_xy(l[:r],l[:c],parse)
|
106
|
+
unit_list << unit
|
107
|
+
end
|
108
|
+
unit_list
|
109
|
+
end
|
110
|
+
|
111
|
+
# 通过xy坐标往unit写内容
|
112
|
+
def write_unit_by_xy x, y, unit
|
113
|
+
unit = unit.to_s if unit.class == Array
|
114
|
+
@sheet.row(x)[y] = unit
|
115
|
+
end
|
116
|
+
|
117
|
+
# 通过x,y坐标获取unit内容
|
118
|
+
def read_unit_by_xy x, y, parse
|
119
|
+
# puts "x: #{x}\ty: #{y}"
|
120
|
+
unit = @sheet.row(y)[x]
|
121
|
+
if unit.instance_of? Spreadsheet::Formula
|
122
|
+
if parse
|
123
|
+
return unit.value
|
124
|
+
end
|
125
|
+
end
|
126
|
+
return unit
|
127
|
+
end
|
128
|
+
|
129
|
+
def flush
|
130
|
+
Excel.new self.path
|
131
|
+
end
|
132
|
+
|
133
|
+
def parse_del_to_hash address, scope
|
134
|
+
arr = address.split '-'
|
135
|
+
arr = arr[1..arr.size-1]
|
136
|
+
start_row_num = scope.scan(/\d/).join[0..1]# 首行行号
|
137
|
+
location = parse_location(scope.split(':')[0])
|
138
|
+
hash = {}
|
139
|
+
del_rows = []
|
140
|
+
address.each do |del_row_num|# 去除行行号
|
141
|
+
rows << del_row_num.to_i - start_row_num.to_i# 去除行行号 - 首行行号 = 数组角标位置
|
142
|
+
end
|
143
|
+
hash.store(:rows,jiang(rows))
|
144
|
+
hash
|
145
|
+
end
|
146
|
+
|
147
|
+
# 解析一个excel location
|
148
|
+
def parse_location location
|
149
|
+
if location and location.class == String
|
150
|
+
location.upcase!
|
151
|
+
{
|
152
|
+
:x => ZIMU[location.scan(/[A-Z]+/).join].to_i,
|
153
|
+
:y => (location.scan(/[0-9]+/).join.to_i - 1)
|
154
|
+
}
|
155
|
+
else
|
156
|
+
ms.puts_fail "location为空或不是String类型,无法解析"
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
def ab_to a, b
|
161
|
+
type = nil
|
162
|
+
if is_number?(a) == true and is_number?(b) == true
|
163
|
+
type = 'y'
|
164
|
+
case a.to_i <=> b.to_i
|
165
|
+
when 1
|
166
|
+
return [type, (b..a).to_a]
|
167
|
+
when -1
|
168
|
+
return [type, (a..b).to_a]
|
169
|
+
when 0
|
170
|
+
return [type, [a]]
|
171
|
+
end
|
172
|
+
elsif is_number?(a) == false and is_number?(b) == false
|
173
|
+
type = 'x'
|
174
|
+
case a <=> b
|
175
|
+
when 1
|
176
|
+
return [type, (b..a).to_a]
|
177
|
+
when -1
|
178
|
+
return [type, (a..b).to_a]
|
179
|
+
when 0
|
180
|
+
return [type, [a]]
|
181
|
+
end
|
182
|
+
else
|
183
|
+
raise "解析excel配置范围时,':'两边必须要么都是字母,要么都是数字!"
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
def map_adds map, adds
|
188
|
+
case adds[0]
|
189
|
+
when 'x'
|
190
|
+
adds[1].each do |add|
|
191
|
+
map[:x] << add
|
192
|
+
end
|
193
|
+
when 'y'
|
194
|
+
adds[1].each do |add|
|
195
|
+
map[:y] << add
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
def map_add map, add
|
201
|
+
if is_number? add
|
202
|
+
map[:y] << add
|
203
|
+
else
|
204
|
+
map[:x] << add
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
def map_mins map, mins
|
209
|
+
case mins[0]
|
210
|
+
when 'x'
|
211
|
+
mins[1].each do |min|
|
212
|
+
map[:x].delete min
|
213
|
+
end
|
214
|
+
when 'y'
|
215
|
+
mins[1].each do |min|
|
216
|
+
map[:y].delete min
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
def map_min map, min
|
222
|
+
if is_number? min
|
223
|
+
map[:y].delete min
|
224
|
+
else
|
225
|
+
map[:x].delete min
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
def is_number? str
|
230
|
+
if str.to_i.to_s == str.to_s
|
231
|
+
return true
|
232
|
+
end
|
233
|
+
false
|
234
|
+
end
|
235
|
+
|
236
|
+
# 用坐标解析一个excel scope
|
237
|
+
def generate_map address_str
|
238
|
+
map = {:x => [], :y => []}
|
239
|
+
config = parse_address address_str
|
240
|
+
if config[:scope]
|
241
|
+
if config[:scope].include? ':'
|
242
|
+
# map初始化
|
243
|
+
arr = config[:scope].split(':')
|
244
|
+
if config[:scope].scan(/[0-9]+/).join == ''
|
245
|
+
map_adds(map, ab_to(arr[0].scan(/[A-Z]+/).join, arr[1].scan(/[A-Z]+/).join))
|
246
|
+
elsif config[:scope].scan(/[A-Z]+/).join == ''
|
247
|
+
map_adds(map, ab_to(arr[0].scan(/[0-9]+/).join, arr[1].scan(/[0-9]+/).join))
|
248
|
+
else
|
249
|
+
map_adds(map, ab_to(arr[0].scan(/[0-9]+/).join, arr[1].scan(/[0-9]+/).join))
|
250
|
+
map_adds(map, ab_to(arr[0].scan(/[A-Z]+/).join, arr[1].scan(/[A-Z]+/).join))
|
251
|
+
end
|
252
|
+
# map 添加
|
253
|
+
if config[:add_str]
|
254
|
+
config[:add_str].split(',').each do |add|
|
255
|
+
if add.include? ":"
|
256
|
+
map_adds(map, ab_to(add.split(':')[0], add.split(':')[1]))
|
257
|
+
else
|
258
|
+
map_add map, add
|
259
|
+
end
|
260
|
+
end
|
261
|
+
end
|
262
|
+
# map 减小
|
263
|
+
if config[:min_str]
|
264
|
+
config[:min_str].split(',').each do |min|
|
265
|
+
if min.include? ":"
|
266
|
+
map_mins(map, ab_to(min.split(':')[0], min.split(':')[1]))
|
267
|
+
else
|
268
|
+
map_min map, min
|
269
|
+
end
|
270
|
+
end
|
271
|
+
end
|
272
|
+
else
|
273
|
+
raise "scope 没有 ':' 无法解析"
|
274
|
+
end
|
275
|
+
else
|
276
|
+
raise "scope == nil"
|
277
|
+
end
|
278
|
+
map[:x].uniq!
|
279
|
+
map[:y].uniq!
|
280
|
+
arrs = []
|
281
|
+
map[:y].each do |y|
|
282
|
+
rows = []
|
283
|
+
map[:x].each do |x|
|
284
|
+
rows << ["#{x}_#{y}", ZIMU[x], y.to_i - 1]
|
285
|
+
end
|
286
|
+
arrs << rows
|
287
|
+
end
|
288
|
+
return arrs
|
289
|
+
rescue
|
290
|
+
puts "生成map时发生错误: #{$!}"
|
291
|
+
puts $@
|
292
|
+
end
|
293
|
+
|
294
|
+
|
295
|
+
# 解析范围配置
|
296
|
+
def parse_address address
|
297
|
+
hash = {}
|
298
|
+
if address
|
299
|
+
address.upcase!
|
300
|
+
else
|
301
|
+
raise "address 为 nil"
|
302
|
+
end
|
303
|
+
if address.split('+').size > 2
|
304
|
+
raise "'+'号只能有1个"
|
305
|
+
end
|
306
|
+
if address.split('-').size > 2
|
307
|
+
raise "'-'号只能有1个"
|
308
|
+
end
|
309
|
+
if address.include?('+')
|
310
|
+
a = address.split('+')[0]
|
311
|
+
b = address.split('+')[1]
|
312
|
+
if a.include?('-')
|
313
|
+
hash.store :scope, a.split('-')[0]
|
314
|
+
hash.store :min_str, a.split('-')[1]
|
315
|
+
hash.store :add_str, b
|
316
|
+
else
|
317
|
+
hash.store :scope, a
|
318
|
+
if b.include?('-')
|
319
|
+
hash.store :min_str, b.split('-')[1]
|
320
|
+
hash.store :add_str, b.split('-')[0]
|
321
|
+
else
|
322
|
+
hash.store :add_str, b
|
323
|
+
end
|
324
|
+
end
|
325
|
+
else
|
326
|
+
if address.include?('-')
|
327
|
+
hash.store :scope, address.split('-')[0]
|
328
|
+
hash.store :min_str, address.split('-')[1]
|
329
|
+
else
|
330
|
+
hash.store :scope, address
|
331
|
+
end
|
332
|
+
end
|
333
|
+
hash
|
334
|
+
end
|
335
|
+
|
336
|
+
# 先打开一个sheet页,再读scope范围数据
|
337
|
+
# params?b13:m27-g.j.k.(14:18)
|
338
|
+
def read_sheet_scope full_scope, simple = true, filter_nil = false
|
339
|
+
if full_scope.include?('?')
|
340
|
+
sheet_name = full_scope.split('?')[0]
|
341
|
+
if sheet_name
|
342
|
+
open_sheet sheet_name
|
343
|
+
else
|
344
|
+
raise "sheetname为nil"
|
345
|
+
end
|
346
|
+
address_str = full_scope.split('?')[1]
|
347
|
+
map = generate_map address_str
|
348
|
+
data_arrs = read_map map, simple
|
349
|
+
if data_arrs.size == 0
|
350
|
+
puts "没有任何内容的区域! #{full_scope}"
|
351
|
+
else
|
352
|
+
puts "#{full_scope}"
|
353
|
+
end
|
354
|
+
# 除去不完整数据
|
355
|
+
if filter_nil == true
|
356
|
+
(data_arrs.size - 1).downto(0) do |i|
|
357
|
+
arr = data_arrs[i]
|
358
|
+
if arr[0] == nil or arr[1] == nil
|
359
|
+
data_arrs.delete_at i
|
360
|
+
end
|
361
|
+
end
|
362
|
+
end
|
363
|
+
return data_arrs
|
364
|
+
else
|
365
|
+
raise "缺少?,需要在'?'左边指定sheet的名称"
|
366
|
+
end
|
367
|
+
end
|
368
|
+
|
369
|
+
def read_map arrs, simple = true
|
370
|
+
@scope_arrs = []
|
371
|
+
arrs.each do |arr|
|
372
|
+
rows = []
|
373
|
+
arr.each do |a|
|
374
|
+
if simple
|
375
|
+
rows << read_unit_by_xy(a[1], a[2], true)
|
376
|
+
else
|
377
|
+
rows << {:index => a[0], :value => read_unit_by_xy(a[1], a[2], true)}
|
378
|
+
end
|
379
|
+
end
|
380
|
+
@scope_arrs << rows
|
381
|
+
end
|
382
|
+
@scope_arrs
|
383
|
+
end
|
384
|
+
|
385
|
+
# 排序
|
386
|
+
def jiang arr
|
387
|
+
0.upto(arr.size - 2) do |i|
|
388
|
+
(i+1).upto(arr.size - 1) do |j|
|
389
|
+
if arr[i] < arr[j]
|
390
|
+
arr[i] = arr[i] + arr[j]
|
391
|
+
arr[j] = arr[i] - arr[j]
|
392
|
+
arr[i] = arr[i] - arr[j]
|
393
|
+
end
|
394
|
+
end
|
395
|
+
end
|
396
|
+
arr
|
397
|
+
end
|
398
|
+
|
399
|
+
def sheng arr
|
400
|
+
0.upto(arr.size - 2) do |i|
|
401
|
+
(i+1).upto(arr.size - 1) do |j|
|
402
|
+
if arr[i] > arr[j]
|
403
|
+
arr[i] = arr[i] + arr[j]
|
404
|
+
arr[j] = arr[i] - arr[j]
|
405
|
+
arr[i] = arr[i] - arr[j]
|
406
|
+
end
|
407
|
+
end
|
408
|
+
end
|
409
|
+
arr
|
410
|
+
end
|
411
|
+
|
412
|
+
# 将二维数组写到表中
|
413
|
+
def write_arrs_to_point(arrs,point = "a1")
|
414
|
+
l = parse_location(point)
|
415
|
+
arrs.each_with_index do |arr,r|
|
416
|
+
arr.each_with_index do |data,c|
|
417
|
+
write_unit_by_xy(r+l[:x],c+l[:y],data)
|
418
|
+
end
|
419
|
+
end
|
420
|
+
self
|
421
|
+
end
|
422
|
+
|
423
|
+
# 将一维数组写到表中,可写成列,也可以写成行
|
424
|
+
def write_arr_to_point(arr, rank = '|', point = "a1")
|
425
|
+
l = parse_location(point)
|
426
|
+
if rank == '|' or rank == 'col'
|
427
|
+
arr.each_with_index do |data,r|
|
428
|
+
# 坚写,行动列不动
|
429
|
+
write_unit_by_xy(l[:r]+r,l[:c],data)
|
430
|
+
end
|
431
|
+
elsif rank == '-' or rank == 'row'
|
432
|
+
arr.each_with_index do |data,c|
|
433
|
+
# 横写,列动行不动
|
434
|
+
write_unit_by_xy(l[:r],l[:c]+c,data)
|
435
|
+
end
|
436
|
+
else
|
437
|
+
raise "横写rank | 竖写rank - 无法识别#{rank}"
|
438
|
+
end
|
439
|
+
self
|
440
|
+
end
|
441
|
+
|
442
|
+
# 保存文件
|
443
|
+
def save(path = nil)
|
444
|
+
flag = 1
|
445
|
+
if path==nil
|
446
|
+
if File.exist? @path
|
447
|
+
@excel.write @path
|
448
|
+
puts "保存覆盖了一个同名文件 #{@path}"
|
449
|
+
else
|
450
|
+
@excel.write @path
|
451
|
+
puts "保存到: #{@path}"
|
452
|
+
end
|
453
|
+
else
|
454
|
+
@excel.write path
|
455
|
+
if File.exist? path
|
456
|
+
puts "保存到: #{path}"
|
457
|
+
else
|
458
|
+
raise "保存失败!"
|
459
|
+
end
|
460
|
+
end
|
461
|
+
self
|
462
|
+
end
|
463
|
+
|
464
|
+
def save_to_source(basename)
|
465
|
+
if basename.match(/.xls$/)!=nil
|
466
|
+
save(@@base_path + "source/" + basename)
|
467
|
+
else
|
468
|
+
raise "要以.xls结尾"
|
469
|
+
end
|
470
|
+
self
|
471
|
+
end
|
472
|
+
|
473
|
+
def save_to_complete(basename)
|
474
|
+
if basename.match(/.xls$/)!=nil
|
475
|
+
save(@@base_path + "complete/" + basename)
|
476
|
+
else
|
477
|
+
raise "要以.xls结尾"
|
478
|
+
end
|
479
|
+
self
|
480
|
+
end
|
481
|
+
|
482
|
+
def save_to(path_name)
|
483
|
+
if path_name.match(/.xls$/)!=nil
|
484
|
+
save(path_name)
|
485
|
+
else
|
486
|
+
raise "要以.xls结尾"
|
487
|
+
end
|
488
|
+
self
|
489
|
+
end
|
490
|
+
|
491
|
+
# 打印信息
|
492
|
+
def info
|
493
|
+
if File.exist?(@path)
|
494
|
+
@sheets ||= @excel.worksheets
|
495
|
+
@sheets.each_with_index do |sheet,i|
|
496
|
+
puts "第#{i}个sheet,name:#{sheet.name}"
|
497
|
+
end
|
498
|
+
puts "Excel文件size:#{File.size @path},sheet数:#{@sheets.size},文件path:#{@path}"
|
499
|
+
else
|
500
|
+
puts "不存在的文件,#{@path}"
|
501
|
+
end
|
502
|
+
self
|
503
|
+
end
|
504
|
+
|
505
|
+
# 获取第一列的所有单元格格式颜色arr
|
506
|
+
def get_examples
|
507
|
+
@sheet.row(4).formats[0].pattern_fg_color == :red
|
508
|
+
cols = excel.sheet.column(0)
|
509
|
+
cols.each do |col|
|
510
|
+
puts col
|
511
|
+
end
|
512
|
+
end
|
513
|
+
|
514
|
+
# 重新加载文件数据
|
515
|
+
def reload
|
516
|
+
if @path!=nil
|
517
|
+
if File.exist? @path
|
518
|
+
@excel = Spreadsheet.open @path
|
519
|
+
@sheets = @excel.worksheets
|
520
|
+
@sheet = nil
|
521
|
+
@basename = nil
|
522
|
+
puts "reload成功 #{@path}"
|
523
|
+
else
|
524
|
+
raise "#{path},这个文件不存在,无法reload"
|
525
|
+
end
|
526
|
+
|
527
|
+
else
|
528
|
+
raise "@path==nil,无法reload"
|
529
|
+
end
|
530
|
+
self
|
531
|
+
end
|
532
|
+
|
533
|
+
def set_default_format(font_color = :black)
|
534
|
+
if @sheet!=nil
|
535
|
+
@format = Spreadsheet::Format.new(
|
536
|
+
:color => :blue,
|
537
|
+
:weight => :bold,
|
538
|
+
:size => 11
|
539
|
+
)
|
540
|
+
@format.font.color = font_color
|
541
|
+
@format.font.name = "微软雅黑"
|
542
|
+
@format.font.size = 11
|
543
|
+
@sheet.default_format = @format
|
544
|
+
# puts "设置默认格式成功 #{@sheet.name}"
|
545
|
+
else
|
546
|
+
raise "@sheet==nil,无法获取默认格式,无法设置默认格式"
|
547
|
+
end
|
548
|
+
@format
|
549
|
+
end
|
550
|
+
|
551
|
+
def write_sheet(sheet)
|
552
|
+
new_sheet sheet[:name]
|
553
|
+
set_default_format(sheet[:color].nil? ? 'black' : sheet[:color])
|
554
|
+
write_arrs_to_point(sheet[:arrs], sheet[:point].nil? ? "a1" : sheet[:point])
|
555
|
+
sheet
|
556
|
+
end
|
557
|
+
|
558
|
+
def self.write_excel(arrs_list,excel_name)
|
559
|
+
new_excel = Excel.new
|
560
|
+
arrs_list.each_with_index do |arrs,i|
|
561
|
+
new_excel.write_sheet arrs,'sheet'+(i+1).to_s,:red
|
562
|
+
end
|
563
|
+
new_excel.save_to_complete excel_name
|
564
|
+
end
|
565
|
+
|
566
|
+
def self.create(path, sheets)
|
567
|
+
e = Excel.new
|
568
|
+
sheets.each do |sheet|
|
569
|
+
e.write_sheet sheet
|
570
|
+
end
|
571
|
+
e.save path
|
572
|
+
end
|
573
|
+
|
574
|
+
def self.write_excel2(arrs,excel_name)
|
575
|
+
new_excel = Excel.new
|
576
|
+
new_excel.write_sheet arrs,'sheet1',:red
|
577
|
+
new_excel.save_to excel_name
|
578
|
+
rescue
|
579
|
+
puts $!
|
580
|
+
puts $@
|
581
|
+
end
|
582
|
+
|
583
|
+
end
|
584
|
+
|
585
|
+
=begin
|
586
|
+
|
587
|
+
# <Spreadsheet::Format:0x007fe8297dba40
|
588
|
+
@bottom=:none,
|
589
|
+
@bottom_color=:builtin_black,
|
590
|
+
@cross_down=false,
|
591
|
+
@cross_up=false,
|
592
|
+
@diagonal_color=:builtin_black,
|
593
|
+
@font=
|
594
|
+
# <Spreadsheet::Font:0x007fe8285948a0
|
595
|
+
@color=:black,
|
596
|
+
@encoding=:iso_latin1,
|
597
|
+
@escapement=:normal,
|
598
|
+
@family=:none,
|
599
|
+
@italic=false,
|
600
|
+
@name="仿宋",
|
601
|
+
@outline=false,
|
602
|
+
@previous_fast_key=nil,
|
603
|
+
@shadow=false,
|
604
|
+
@size=11,
|
605
|
+
@strikeout=false,
|
606
|
+
@underline=:none,
|
607
|
+
@weight=400>,
|
608
|
+
@horizontal_align=:center,
|
609
|
+
@indent_level=0,
|
610
|
+
@left=:none,
|
611
|
+
@left_color=:builtin_black,
|
612
|
+
@number_format="GENERAL",
|
613
|
+
@pattern=1,
|
614
|
+
@pattern_bg_color=:border,
|
615
|
+
@pattern_fg_color=:red,
|
616
|
+
@regexes=
|
617
|
+
{:date=>/[YMD]/,
|
618
|
+
:date_or_time=>/[hmsYMD]/,
|
619
|
+
:datetime=>/([YMD].*[HS])|([HS].*[YMD])/,
|
620
|
+
:time=>/[hms]/,
|
621
|
+
:number=>/([# ]|0+)/,
|
622
|
+
:locale=>/(?-mix:\A\[\$\-\d+\])/},
|
623
|
+
=end
|
data/lib/ld/file.rb
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
class Ld::File
|
2
|
+
|
3
|
+
attr_accessor :path, :name, :type
|
4
|
+
|
5
|
+
def initialize path
|
6
|
+
@path = path
|
7
|
+
@name = File.basename @path
|
8
|
+
@type = File.directory?(@path) ? 1 : 0
|
9
|
+
end
|
10
|
+
|
11
|
+
def brothers
|
12
|
+
father.children
|
13
|
+
end
|
14
|
+
|
15
|
+
def children
|
16
|
+
arr = []
|
17
|
+
Dir.foreach(@path)do |p|
|
18
|
+
if !['.','..','.DS_Store'].include?(p)
|
19
|
+
arr << Ld::File.new("#{@path}/#{p}")
|
20
|
+
end
|
21
|
+
end
|
22
|
+
arr.sort!{|a,b| b.type-a.type}
|
23
|
+
arr
|
24
|
+
end
|
25
|
+
|
26
|
+
def father
|
27
|
+
arr = @path.split('/')
|
28
|
+
arr.pop
|
29
|
+
Ld::File.new(arr.join('/'))
|
30
|
+
end
|
31
|
+
|
32
|
+
def find name
|
33
|
+
name = name.to_s
|
34
|
+
children.each do |f|
|
35
|
+
if f.name == name
|
36
|
+
return f
|
37
|
+
end
|
38
|
+
end
|
39
|
+
return nil
|
40
|
+
end
|
41
|
+
|
42
|
+
def read
|
43
|
+
File.open(@path).read
|
44
|
+
end
|
45
|
+
|
46
|
+
def readlines
|
47
|
+
File.open(@path).readlines
|
48
|
+
end
|
49
|
+
|
50
|
+
def where regexp
|
51
|
+
arr = []
|
52
|
+
iter_search regexp, arr
|
53
|
+
arr
|
54
|
+
end
|
55
|
+
|
56
|
+
def iter_search regexp, arr
|
57
|
+
children.each do |f|
|
58
|
+
if f.type == 1
|
59
|
+
f.iter_search regexp, arr
|
60
|
+
end
|
61
|
+
if f.name.match(regexp)
|
62
|
+
arr << f
|
63
|
+
end
|
64
|
+
end
|
65
|
+
self
|
66
|
+
end
|
67
|
+
|
68
|
+
def iter arr
|
69
|
+
children.each do |f|
|
70
|
+
if f.type == 1
|
71
|
+
f.iter arr
|
72
|
+
end
|
73
|
+
arr << f
|
74
|
+
end
|
75
|
+
self
|
76
|
+
end
|
77
|
+
|
78
|
+
def method_missing name
|
79
|
+
find name
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
data/lib/ld/node.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
class Ld::Node
|
2
|
+
attr_accessor :id, :depth, :name, :path ,:type, :suffix
|
3
|
+
|
4
|
+
def initialize id, depth, path
|
5
|
+
@id = id
|
6
|
+
@depth = depth
|
7
|
+
@path = path
|
8
|
+
@type = File.directory?(path) ? 1 : 0
|
9
|
+
@name = File.basename path
|
10
|
+
@suffix = @type == 1 ? nil : @name.split('.').last
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|