workbook 0.4.6.0 → 0.4.7
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 +4 -4
- data/.gitignore +1 -0
- data/README.md +14 -15
- data/lib/workbook.rb +22 -11
- data/lib/workbook/book.rb +47 -25
- data/lib/workbook/cell.rb +20 -26
- data/lib/workbook/generatetypes.rb +14 -0
- data/lib/workbook/modules/cache.rb +52 -0
- data/lib/workbook/modules/{table_diff_sort.rb → diff_sort.rb} +64 -16
- data/lib/workbook/modules/raw_objects_storage.rb +7 -2
- data/lib/workbook/readers/ods_reader.rb +1 -1
- data/lib/workbook/readers/xls_reader.rb +55 -55
- data/lib/workbook/readers/xls_shared.rb +47 -0
- data/lib/workbook/readers/xlsx_reader.rb +34 -153
- data/lib/workbook/row.rb +47 -4
- data/lib/workbook/sheet.rb +4 -0
- data/lib/workbook/table.rb +36 -16
- data/lib/workbook/types/Date.rb +9 -0
- data/lib/workbook/types/False.rb +0 -0
- data/lib/workbook/types/FalseClass.rb +9 -0
- data/lib/workbook/types/Nil.rb +0 -0
- data/lib/workbook/types/NilClass.rb +9 -0
- data/lib/workbook/types/Numeric.rb +9 -0
- data/lib/workbook/types/String.rb +9 -0
- data/lib/workbook/types/Time.rb +9 -0
- data/lib/workbook/types/True.rb +0 -0
- data/lib/workbook/types/TrueClass.rb +9 -0
- data/lib/workbook/version.rb +1 -1
- data/lib/workbook/writers/html_writer.rb +40 -18
- data/lib/workbook/writers/xls_writer.rb +47 -5
- data/lib/workbook/writers/xlsx_writer.rb +123 -0
- data/test/artifacts/bigtable.xls +0 -0
- data/test/artifacts/bigtable.xlsx +0 -0
- data/test/artifacts/simple_sheet.xlsx +0 -0
- data/test/artifacts/simple_sheet_many_sheets.xls +0 -0
- data/test/test_book.rb +50 -2
- data/test/test_cell.rb +1 -1
- data/test/test_format.rb +8 -0
- data/test/test_modules_cache.rb +68 -0
- data/test/test_modules_table_diff_sort.rb +12 -1
- data/test/test_readers_xls_reader.rb +6 -0
- data/test/test_readers_xlsx_reader.rb +10 -9
- data/test/test_row.rb +65 -8
- data/test/test_sheet.rb +8 -0
- data/test/test_table.rb +48 -0
- data/test/test_writers_html_writer.rb +18 -8
- data/test/test_writers_xls_writer.rb +90 -0
- data/test/test_writers_xlsx_writer.rb +153 -0
- data/workbook.gemspec +9 -7
- metadata +71 -31
@@ -11,8 +11,7 @@ module Workbook
|
|
11
11
|
|
12
12
|
# Returns true if there is a template for a certain class, otherwise false
|
13
13
|
def has_raw_for? raw_object_class
|
14
|
-
|
15
|
-
return false
|
14
|
+
available_raws.include? raw_object_class
|
16
15
|
end
|
17
16
|
|
18
17
|
# Returns raw data stored for a type of raw object (if available)
|
@@ -27,6 +26,12 @@ module Workbook
|
|
27
26
|
@raws = {}
|
28
27
|
end
|
29
28
|
|
29
|
+
# Lists the classes for which raws are available
|
30
|
+
# @return Array<Object> array with the classes available
|
31
|
+
def available_raws
|
32
|
+
raws.keys
|
33
|
+
end
|
34
|
+
|
30
35
|
# Return all raw data references
|
31
36
|
def raws
|
32
37
|
@raws = {} unless defined? @raws
|
@@ -10,7 +10,7 @@ module Workbook
|
|
10
10
|
file_obj = file_obj.path if file_obj.is_a? File
|
11
11
|
content = ""
|
12
12
|
styles = ""
|
13
|
-
Zip::
|
13
|
+
Zip::File.open(file_obj) do |zipfile|
|
14
14
|
zipfile.entries.each do |file|
|
15
15
|
styles = zipfile.read(file.name) if file.name == "styles.xml"
|
16
16
|
content = zipfile.read(file.name) if file.name == "content.xml"
|
@@ -1,9 +1,12 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
2
|
require 'spreadsheet'
|
3
|
+
require 'workbook/readers/xls_shared'
|
4
|
+
|
3
5
|
|
4
6
|
module Workbook
|
5
7
|
module Readers
|
6
8
|
module XlsReader
|
9
|
+
include Workbook::Readers::XlsShared
|
7
10
|
|
8
11
|
def load_xls file_obj
|
9
12
|
begin
|
@@ -27,63 +30,66 @@ module Workbook
|
|
27
30
|
number_of_worksheets = xls_spreadsheet.worksheets.count
|
28
31
|
(0..number_of_worksheets-1).each do |si|
|
29
32
|
xls_sheet = xls_spreadsheet.worksheets[si]
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
33
|
+
if [:visible, :hidden, nil].include? xls_sheet.visibility # don't read :strong_hidden sheets, symmetrical to the writer
|
34
|
+
begin
|
35
|
+
number_of_rows = xls_sheet.count
|
36
|
+
s = create_or_open_sheet_at(si)
|
37
|
+
s.name = xls_sheet.name
|
38
|
+
(0..number_of_rows-1).each do |ri|
|
39
|
+
xls_row = xls_sheet.row(ri)
|
40
|
+
r = s.table.create_or_open_row_at(ri)
|
41
|
+
col_widths = xls_sheet.columns.collect{|c| c.width if c}
|
42
|
+
xls_row.each_with_index do |xls_cell,ci|
|
38
43
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
44
|
+
begin
|
45
|
+
r[ci] = Workbook::Cell.new xls_cell
|
46
|
+
r[ci].parse!
|
47
|
+
rescue ArgumentError => e
|
48
|
+
if e.message.match('not a Spreadsheet::Formula')
|
49
|
+
v = xls_cell.value
|
50
|
+
if v.class == Float and xls_row.format(ci).date?
|
51
|
+
xls_row[ci] = v
|
52
|
+
v = xls_row.datetime(ci)
|
53
|
+
end
|
54
|
+
if v.is_a? Spreadsheet::Excel::Error
|
55
|
+
v = "----!"
|
56
|
+
end
|
57
|
+
r[ci] = Workbook::Cell.new v
|
58
|
+
elsif e.message.match('not a Spreadsheet::Link')
|
59
|
+
r[ci] = Workbook::Cell.new xls_cell.to_s
|
60
|
+
elsif e.message.match('not a Spreadsheet::Link')
|
61
|
+
r[ci] = Workbook::Cell.new xls_cell.to_s
|
62
|
+
elsif e.message.match('not a Spreadsheet::Excel::Error')
|
63
|
+
r[ci] = "._."
|
64
|
+
else
|
65
|
+
r[ci] = "._." # raise e (we're going to be silent for now)
|
51
66
|
end
|
52
|
-
r[ci] = Workbook::Cell.new v
|
53
|
-
elsif e.message.match('not a Spreadsheet::Link')
|
54
|
-
r[ci] = Workbook::Cell.new xls_cell.to_s
|
55
|
-
elsif e.message.match('not a Spreadsheet::Link')
|
56
|
-
r[ci] = Workbook::Cell.new xls_cell.to_s
|
57
|
-
elsif e.message.match('not a Spreadsheet::Excel::Error')
|
58
|
-
r[ci] = "._."
|
59
|
-
else
|
60
|
-
r[ci] = "._." # raise e (we're going to be silent for now)
|
61
67
|
end
|
62
|
-
|
63
|
-
|
64
|
-
col_width = nil
|
68
|
+
xls_format = xls_row.format(ci)
|
69
|
+
col_width = nil
|
65
70
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
71
|
+
if ri == 0
|
72
|
+
col_width = col_widths[ci]
|
73
|
+
end
|
74
|
+
f = template.create_or_find_format_by "object_id_#{xls_format.object_id}",col_width
|
75
|
+
f[:width]= col_width
|
76
|
+
f[:rotation] = xls_format.rotation if xls_format.rotation
|
77
|
+
f[:background_color] = xls_color_to_html_hex(xls_format.pattern_fg_color)
|
78
|
+
f[:number_format] = ms_formatting_to_strftime(xls_format.number_format)
|
79
|
+
f[:text_direction] = xls_format.text_direction
|
80
|
+
f[:font_family] = "#{xls_format.font.name}, #{xls_format.font.family}"
|
81
|
+
f[:font_weight] = xls_format.font.weight
|
82
|
+
f[:color] = xls_color_to_html_hex(xls_format.font.color)
|
78
83
|
|
79
|
-
|
84
|
+
f.add_raw xls_format
|
80
85
|
|
81
|
-
|
86
|
+
r[ci].format = f
|
87
|
+
end
|
82
88
|
end
|
89
|
+
rescue TypeError
|
90
|
+
puts "WARNING: Failed at worksheet (#{si})... ignored"
|
91
|
+
#ignore SpreadsheetGem can be buggy...
|
83
92
|
end
|
84
|
-
rescue TypeError
|
85
|
-
puts "WARNING: Failed at worksheet (#{si})... ignored"
|
86
|
-
#ignore SpreadsheetGem can be buggy...
|
87
93
|
end
|
88
94
|
end
|
89
95
|
end
|
@@ -92,12 +98,6 @@ module Workbook
|
|
92
98
|
def xls_color_to_html_hex color_sym
|
93
99
|
Workbook::Book::XLS_COLORS[color_sym] ? Workbook::Book::XLS_COLORS[color_sym] : "#000000"
|
94
100
|
end
|
95
|
-
|
96
|
-
def ms_formatting_to_strftime ms_nr_format
|
97
|
-
ms_nr_format = ms_nr_format.downcase
|
98
|
-
return nil if ms_nr_format == 'general'
|
99
|
-
ms_nr_format.gsub('yyyy','%Y').gsub('dddd','%A').gsub('mmmm','%B').gsub('ddd','%a').gsub('mmm','%b').gsub('yy','%y').gsub('dd','%d').gsub('mm','%m').gsub('y','%y').gsub('%%y','%y').gsub('d','%e').gsub('%%e','%d').gsub('m','%m').gsub('%%m','%m').gsub(';@','').gsub('\\','')
|
100
|
-
end
|
101
101
|
end
|
102
102
|
end
|
103
103
|
end
|
@@ -2,6 +2,53 @@
|
|
2
2
|
module Workbook
|
3
3
|
module Readers
|
4
4
|
module XlsShared
|
5
|
+
def ms_formatting_to_strftime ms_nr_format
|
6
|
+
if ms_nr_format
|
7
|
+
ms_nr_format = ms_nr_format.to_s.downcase
|
8
|
+
return nil if ms_nr_format == 'general' or ms_nr_format == ""
|
9
|
+
translation_table = {
|
10
|
+
'yyyy'=>'%Y',
|
11
|
+
'dddd'=>'%A',
|
12
|
+
'mmmm'=>'%B',
|
13
|
+
'ddd'=>'%a',
|
14
|
+
'mmm'=>'%b',
|
15
|
+
'yy'=>'%y',
|
16
|
+
'dd'=>'%d',
|
17
|
+
'mm'=>'%m',
|
18
|
+
'y'=>'%y',
|
19
|
+
'%%y'=>'%y',
|
20
|
+
'd'=>'%e',
|
21
|
+
'%%e'=>'%d',
|
22
|
+
'm'=>'%m',
|
23
|
+
'%%m'=>'%m',
|
24
|
+
';@'=>'',
|
25
|
+
'\\'=>''
|
26
|
+
}
|
27
|
+
translation_table.each{|k,v| ms_nr_format.gsub!(k,v) }
|
28
|
+
ms_nr_format
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Attempt to convert html-hex color value to xls color number
|
33
|
+
#
|
34
|
+
# @param [String] hex color
|
35
|
+
# @return [String] xls color
|
36
|
+
def html_color_to_xls_color hex
|
37
|
+
Workbook::Readers::XlsShared::XLS_COLORS.each do |k,v|
|
38
|
+
return k if (v == hex or (hex and hex != "" and k == hex.to_sym))
|
39
|
+
end
|
40
|
+
return nil
|
41
|
+
end
|
42
|
+
|
43
|
+
# Converts standard (ruby/C++/unix/...) strftime formatting to MS's formatting
|
44
|
+
#
|
45
|
+
# @param [String, nil] numberformat (nil returns nil)
|
46
|
+
# @return [String, nil]
|
47
|
+
def strftime_to_ms_format numberformat
|
48
|
+
return nil if numberformat.nil?
|
49
|
+
return numberformat.gsub('%Y','yyyy').gsub('%A','dddd').gsub('%B','mmmm').gsub('%a','ddd').gsub('%b','mmm').gsub('%y','yy').gsub('%d','dd').gsub('%m','mm').gsub('%y','y').gsub('%y','%%y').gsub('%e','d')
|
50
|
+
end
|
51
|
+
|
5
52
|
XLS_COLORS = {:xls_color_1=>'#000000',
|
6
53
|
:xls_color_2=>'#FFFFFF',
|
7
54
|
:xls_color_3=>'#FF0000',
|
@@ -1,136 +1,19 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
2
|
require 'rubyXL'
|
3
|
+
require 'workbook/readers/xls_shared'
|
3
4
|
|
4
|
-
# Monkeypatching rubyXL, pull request submitted: https://github.com/gilt/rubyXL/pull/47
|
5
|
-
module RubyXL
|
6
|
-
class Workbook
|
7
|
-
|
8
|
-
# Improves upon date format detection
|
9
|
-
def is_date_format?(num_fmt)
|
10
|
-
num_fmt = num_fmt.to_s
|
11
|
-
num_fmt.downcase!
|
12
|
-
skip_chars = ['$', '-', '+', '/', '(', ')', ':', ' ']
|
13
|
-
num_chars = ['0', '#', '?']
|
14
|
-
non_date_formats = ['0.00e+00', '##0.0e+0', 'general', '@']
|
15
|
-
date_chars = ['y','m','d','h','s']
|
16
|
-
|
17
|
-
state = 0
|
18
|
-
s = ''
|
19
|
-
num_fmt.split(//).each do |c|
|
20
|
-
if state == 0
|
21
|
-
if c == '"'
|
22
|
-
state = 1
|
23
|
-
elsif ['\\', '_', '*'].include?(c)
|
24
|
-
state = 2
|
25
|
-
elsif skip_chars.include?(c)
|
26
|
-
next
|
27
|
-
else
|
28
|
-
s << c
|
29
|
-
end
|
30
|
-
elsif state == 1
|
31
|
-
if c == '"'
|
32
|
-
state = 0
|
33
|
-
end
|
34
|
-
elsif state == 2
|
35
|
-
state = 0
|
36
|
-
end
|
37
|
-
end
|
38
|
-
s.gsub!(/\[[^\]]*\]/, '')
|
39
|
-
if non_date_formats.include?(s)
|
40
|
-
return false
|
41
|
-
end
|
42
|
-
separator = ';'
|
43
|
-
got_sep = 0
|
44
|
-
date_count = 0
|
45
|
-
num_count = 0
|
46
|
-
s.split(//).each do |c|
|
47
|
-
if date_chars.include?(c)
|
48
|
-
date_count += 1
|
49
|
-
elsif num_chars.include?(c)
|
50
|
-
num_count += 1
|
51
|
-
elsif c == separator
|
52
|
-
got_sep = 1
|
53
|
-
end
|
54
|
-
end
|
55
|
-
if date_count > 0 && num_count == 0
|
56
|
-
return true
|
57
|
-
elsif num_count > 0 && date_count == 0
|
58
|
-
return false
|
59
|
-
elsif date_count
|
60
|
-
# ambiguous result
|
61
|
-
elsif got_sep == 0
|
62
|
-
# constant result
|
63
|
-
end
|
64
|
-
return date_count > num_count
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
68
|
-
# end monkey patch submitted
|
69
|
-
|
70
|
-
module RubyXL
|
71
|
-
class Workbook
|
72
|
-
def num_fmts_by_id
|
73
|
-
return @num_fmts_hash unless @num_fmts_hash.nil?
|
74
|
-
@num_fmts_hash={1=>{:attributes=>{:formatCode=>'0'}},
|
75
|
-
2=>{:attributes=>{:formatCode=>'0.00'}},
|
76
|
-
3=>{:attributes=>{:formatCode=>'#, ##0'}},
|
77
|
-
4=>{:attributes=>{:formatCode=>'#, ##0.00'}},
|
78
|
-
5=>{:attributes=>{:formatCode=>'$#, ##0_);($#, ##0)'}},
|
79
|
-
6=>{:attributes=>{:formatCode=>'$#, ##0_);[Red]($#, ##0)'}},
|
80
|
-
7=>{:attributes=>{:formatCode=>'$#, ##0.00_);($#, ##0.00)'}},
|
81
|
-
8=>{:attributes=>{:formatCode=>'$#, ##0.00_);[Red]($#, ##0.00)'}},
|
82
|
-
9=>{:attributes=>{:formatCode=>'0%'}},
|
83
|
-
10=>{:attributes=>{:formatCode=>'0.00%'}},
|
84
|
-
11=>{:attributes=>{:formatCode=>'0.00E+00'}},
|
85
|
-
12=>{:attributes=>{:formatCode=>'# ?/?'}},
|
86
|
-
13=>{:attributes=>{:formatCode=>'# ??/??'}},
|
87
|
-
14=>{:attributes=>{:formatCode=>'m/d/yyyy'}},
|
88
|
-
15=>{:attributes=>{:formatCode=>'d-mmm-yy'}},
|
89
|
-
16=>{:attributes=>{:formatCode=>'d-mmm'}},
|
90
|
-
17=>{:attributes=>{:formatCode=>'mmm-yy'}},
|
91
|
-
18=>{:attributes=>{:formatCode=>'h:mm AM/PM'}},
|
92
|
-
19=>{:attributes=>{:formatCode=>'h:mm:ss AM/PM'}},
|
93
|
-
20=>{:attributes=>{:formatCode=>'h:mm'}},
|
94
|
-
21=>{:attributes=>{:formatCode=>'h:mm:ss'}},
|
95
|
-
22=>{:attributes=>{:formatCode=>'m/d/yyyy h:mm'}},
|
96
|
-
37=>{:attributes=>{:formatCode=>'#, ##0_);(#, ##0)'}},
|
97
|
-
38=>{:attributes=>{:formatCode=>'#, ##0_);[Red](#, ##0)'}},
|
98
|
-
39=>{:attributes=>{:formatCode=>'#, ##0.00_);(#, ##0.00)'}},
|
99
|
-
40=>{:attributes=>{:formatCode=>'#, ##0.00_);[Red](#, ##0.00)'}},
|
100
|
-
45=>{:attributes=>{:formatCode=>'mm:ss'}},
|
101
|
-
46=>{:attributes=>{:formatCode=>'[h]:mm:ss'}},
|
102
|
-
47=>{:attributes=>{:formatCode=>'mm:ss.0'}},
|
103
|
-
48=>{:attributes=>{:formatCode=>'##0.0E+0'}},
|
104
|
-
49=>{:attributes=>{:formatCode=>'@'}}}
|
105
|
-
if num_fmts and num_fmts[:numFmt]
|
106
|
-
num_fmts[:numFmt].each do |num_fmt|
|
107
|
-
@num_fmts_hash[num_fmt[:attributes][:numFmtId]]=num_fmt
|
108
|
-
end
|
109
|
-
end
|
110
|
-
return @num_fmts_hash
|
111
|
-
end
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
115
|
-
# other monkey patch
|
116
|
-
module RubyXL
|
117
|
-
class Cell
|
118
|
-
def number_format
|
119
|
-
if !@value.is_a?(String)
|
120
|
-
if @workbook.num_fmts_by_id
|
121
|
-
num_fmt_id = xf_id()[:numFmtId]
|
122
|
-
tmp_num_fmt = @workbook.num_fmts_by_id[num_fmt_id]
|
123
|
-
return (tmp_num_fmt &&tmp_num_fmt[:attributes] && tmp_num_fmt[:attributes][:formatCode]) ? tmp_num_fmt[:attributes][:formatCode] : nil
|
124
|
-
end
|
125
|
-
end
|
126
|
-
end
|
127
|
-
end
|
128
|
-
end
|
129
|
-
# end of monkey patch
|
130
5
|
|
131
6
|
module Workbook
|
132
7
|
module Readers
|
133
8
|
module XlsxReader
|
9
|
+
include Workbook::Readers::XlsShared
|
10
|
+
|
11
|
+
# Load method for .xlsm files, an office open file format, hence compatible with .xlsx (it emphasizes that it contains macros)
|
12
|
+
#
|
13
|
+
# @param [String, File] file_obj a string with a reference to the file to be written to
|
14
|
+
def load_xlsm file_obj
|
15
|
+
self.load_xlsx file_obj
|
16
|
+
end
|
134
17
|
def load_xlsx file_obj
|
135
18
|
file_obj = file_obj.path if file_obj.is_a? File
|
136
19
|
sp = RubyXL::Parser.parse(file_obj)
|
@@ -149,43 +32,41 @@ module Workbook
|
|
149
32
|
rescue
|
150
33
|
# Column widths couldn't be read, no big deal...
|
151
34
|
end
|
35
|
+
|
152
36
|
worksheet.each_with_index do |row, ri|
|
153
|
-
|
37
|
+
if row
|
38
|
+
r = s.table.create_or_open_row_at(ri)
|
39
|
+
row.cells.each_with_index do |cell,ci|
|
40
|
+
if cell.nil?
|
41
|
+
r[ci] = Workbook::Cell.new nil
|
42
|
+
else
|
43
|
+
r[ci] = Workbook::Cell.new cell.value
|
44
|
+
r[ci].parse!
|
45
|
+
xls_format = cell.style_index
|
46
|
+
col_width = nil
|
154
47
|
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
48
|
+
if ri == 0
|
49
|
+
col_width = col_widths[ci]
|
50
|
+
end
|
51
|
+
f = template.create_or_find_format_by "style_index_#{cell.style_index}", col_width
|
52
|
+
f[:width]= col_width
|
53
|
+
background_color = cell.fill_color
|
54
|
+
background_color = (background_color.length == 8) ? background_color[2..8] : background_color #ignoring alpha for now.
|
55
|
+
f[:background_color] = "##{background_color}"
|
163
56
|
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
f = template.create_or_find_format_by "style_index_#{cell.style_index}", col_width
|
168
|
-
f[:width]= col_width
|
169
|
-
f[:background_color] = "##{cell.fill_color}"
|
170
|
-
f[:number_format] = ms_formatting_to_strftime(cell.number_format)
|
171
|
-
f[:font_family] = cell.font_name
|
172
|
-
f[:color] = "##{cell.font_color}"
|
57
|
+
f[:number_format] = ms_formatting_to_strftime(cell.number_format)
|
58
|
+
# f[:font_family] = cell.font_name
|
59
|
+
# f[:color] = "##{cell.font_color}"
|
173
60
|
|
174
|
-
|
61
|
+
f.add_raw xls_format
|
175
62
|
|
176
|
-
|
63
|
+
r[ci].format = f
|
64
|
+
end
|
177
65
|
end
|
178
66
|
end
|
179
67
|
end
|
180
68
|
end
|
181
69
|
end
|
182
|
-
def ms_formatting_to_strftime ms_nr_format
|
183
|
-
if ms_nr_format
|
184
|
-
ms_nr_format = ms_nr_format.to_s.downcase
|
185
|
-
return nil if ms_nr_format == 'general' or ms_nr_format == ""
|
186
|
-
ms_nr_format.gsub('yyyy','%Y').gsub('dddd','%A').gsub('mmmm','%B').gsub('ddd','%a').gsub('mmm','%b').gsub('yy','%y').gsub('dd','%d').gsub('mm','%m').gsub('y','%y').gsub('%%y','%y').gsub('d','%e').gsub('%%e','%d').gsub('m','%m').gsub('%%m','%m').gsub(';@','').gsub('\\','')
|
187
|
-
end
|
188
|
-
end
|
189
70
|
end
|
190
71
|
end
|
191
72
|
end
|
data/lib/workbook/row.rb
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
|
+
|
2
3
|
module Workbook
|
3
4
|
class Row < Array
|
5
|
+
include Workbook::Modules::Cache
|
6
|
+
|
4
7
|
alias_method :compare_without_header, :<=>
|
5
8
|
attr_accessor :placeholder # The placeholder attribute is used in compares (corresponds to newly created or removed lines (depending which side you're on)
|
6
9
|
attr_accessor :format
|
@@ -57,13 +60,45 @@ module Workbook
|
|
57
60
|
end
|
58
61
|
end
|
59
62
|
|
63
|
+
# Add cell
|
64
|
+
# @param [Workbook::Cell, Numeric,String,Time,Date,TrueClass,FalseClass,NilClass] cell or value to add
|
65
|
+
def push(cell)
|
66
|
+
cell = Workbook::Cell.new(cell) unless cell.class == Workbook::Cell
|
67
|
+
super(cell)
|
68
|
+
end
|
69
|
+
|
70
|
+
# Add cell
|
71
|
+
# @param [Workbook::Cell, Numeric,String,Time,Date,TrueClass,FalseClass,NilClass] cell or value to add
|
72
|
+
def <<(cell)
|
73
|
+
cell = Workbook::Cell.new(cell) unless cell.class == Workbook::Cell
|
74
|
+
super(cell)
|
75
|
+
end
|
76
|
+
|
77
|
+
# plus
|
78
|
+
# @param [Workbook::Row, Array] row to add
|
79
|
+
# @return [Workbook::Row] a new row, not linked to the table
|
80
|
+
def +(row)
|
81
|
+
rv = super(row)
|
82
|
+
rv = Workbook::Row.new(rv) unless rv.class == Workbook::Row
|
83
|
+
return rv
|
84
|
+
end
|
85
|
+
|
86
|
+
# concat
|
87
|
+
# @param [Workbook::Row, Array] row to add
|
88
|
+
# @return [self] self
|
89
|
+
def concat(row)
|
90
|
+
row = Workbook::Row.new(row) unless row.class == Workbook::Row
|
91
|
+
super(row)
|
92
|
+
end
|
93
|
+
|
94
|
+
|
60
95
|
# Overrides normal Array's []-function with support for symbols that identify a column based on the header-values
|
61
96
|
#
|
62
97
|
# @example Lookup using fixnum or header value encoded as symbol
|
63
98
|
# row[1] #=> <Cell value="a">
|
64
99
|
# row[:a] #=> <Cell value="a">
|
65
100
|
#
|
66
|
-
# @param [Fixnum, Symbol] index_or_hash
|
101
|
+
# @param [Fixnum, Symbol, String] index_or_hash that identifies the column (strings are converted to symbols)
|
67
102
|
# @return [Workbook::Cell, nil]
|
68
103
|
def [](index_or_hash)
|
69
104
|
if index_or_hash.is_a? Symbol
|
@@ -73,6 +108,9 @@ module Workbook
|
|
73
108
|
rescue NoMethodError
|
74
109
|
end
|
75
110
|
return rv
|
111
|
+
elsif index_or_hash.is_a? String
|
112
|
+
symbolized = Workbook::Cell.new(index_or_hash).to_sym
|
113
|
+
self[symbolized]
|
76
114
|
else
|
77
115
|
if index_or_hash
|
78
116
|
return to_a[index_or_hash]
|
@@ -82,17 +120,20 @@ module Workbook
|
|
82
120
|
|
83
121
|
# Overrides normal Array's []=-function with support for symbols that identify a column based on the header-values
|
84
122
|
#
|
85
|
-
# @example Lookup using fixnum or header value encoded as symbol
|
123
|
+
# @example Lookup using fixnum or header value encoded as symbol (strings are converted to symbols)
|
86
124
|
# row[1] #=> <Cell value="a">
|
87
125
|
# row[:a] #=> <Cell value="a">
|
88
126
|
#
|
89
|
-
# @param [Fixnum, Symbol] index_or_hash
|
127
|
+
# @param [Fixnum, Symbol, String] index_or_hash that identifies the column
|
90
128
|
# @param [String, Fixnum, NilClass, Date, DateTime, Time, Float] value
|
91
129
|
# @return [Workbook::Cell, nil]
|
92
130
|
def []= (index_or_hash, value)
|
93
131
|
index = index_or_hash
|
94
132
|
if index_or_hash.is_a? Symbol
|
95
133
|
index = table_header_keys.index(index_or_hash)
|
134
|
+
elsif index_or_hash.is_a? String
|
135
|
+
symbolized = Workbook::Cell.new(index_or_hash).to_sym
|
136
|
+
index = table_header_keys.index(symbolized)
|
96
137
|
end
|
97
138
|
|
98
139
|
value_celled = Workbook::Cell.new
|
@@ -144,7 +185,9 @@ module Workbook
|
|
144
185
|
# Converts a row to an array of symbol representations of the row content, see also: Workbook::Cell#to_sym
|
145
186
|
# @return [Array<Symbol>] returns row as an array of symbols
|
146
187
|
def to_symbols
|
147
|
-
|
188
|
+
fetch_cache(:to_symbols){
|
189
|
+
collect{|c| c.to_sym}
|
190
|
+
}
|
148
191
|
end
|
149
192
|
|
150
193
|
# Converts the row to an array of Workbook::Cell's
|