roo 1.11.2 → 1.12.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,27 +1,24 @@
1
1
  require 'csv'
2
2
  require 'time'
3
3
 
4
- # The Csv class can read csv files (must be separated with commas) which then
4
+ # The CSV class can read csv files (must be separated with commas) which then
5
5
  # can be handled like spreadsheets. This means you can access cells like A5
6
6
  # within these files.
7
- # The Csv class provides only string objects. If you want conversions to other
7
+ # The CSV class provides only string objects. If you want conversions to other
8
8
  # types you have to do it yourself.
9
+ #
10
+ # You can pass options to the underlying CSV parse operation, via the
11
+ # :csv_options option.
12
+ #
9
13
 
10
- class Roo::Csv < Roo::GenericSpreadsheet
11
- def initialize(filename, packed=nil, file_warning=:error, tmpdir=nil)
12
- @filename = filename
13
- @cell = Hash.new
14
- @cell_type = Hash.new
15
- @cells_read = Hash.new
16
- @first_row = Hash.new
17
- @last_row = Hash.new
18
- @first_column = Hash.new
19
- @last_column = Hash.new
14
+ class Roo::CSV < Roo::Base
15
+ def initialize(filename, options = {})
16
+ super
20
17
  end
21
18
 
22
19
  attr_reader :filename
23
20
 
24
- # Returns an array with the names of the sheets. In Csv class there is only
21
+ # Returns an array with the names of the sheets. In CSV class there is only
25
22
  # one dummy sheet, because a csv file cannot have more than one sheet.
26
23
  def sheets
27
24
  ['default']
@@ -29,22 +26,24 @@ class Roo::Csv < Roo::GenericSpreadsheet
29
26
 
30
27
  def cell(row, col, sheet=nil)
31
28
  sheet ||= @default_sheet
32
- read_cells(sheet) unless @cells_read[sheet]
33
- row,col = normalize(row,col)
34
- @cell[[row,col]]
29
+ read_cells(sheet)
30
+ @cell[normalize(row,col)]
35
31
  end
36
32
 
37
33
  def celltype(row, col, sheet=nil)
38
34
  sheet ||= @default_sheet
39
- read_cells(sheet) unless @cells_read[sheet]
40
- row,col = normalize(row,col)
41
- @cell_type[[row,col]]
35
+ read_cells(sheet)
36
+ @cell_type[normalize(row,col)]
42
37
  end
43
38
 
44
39
  def cell_postprocessing(row,col,value)
45
40
  value
46
41
  end
47
42
 
43
+ def csv_options
44
+ @options[:csv_options] || {}
45
+ end
46
+
48
47
  private
49
48
 
50
49
  TYPE_MAP = {
@@ -58,27 +57,26 @@ class Roo::Csv < Roo::GenericSpreadsheet
58
57
  TYPE_MAP[value.class]
59
58
  end
60
59
 
61
- def data
62
- @data ||=
60
+ def each_row(options, &block)
61
+ if uri?(filename)
63
62
  make_tmpdir do |tmpdir|
64
- File.open(
65
- uri?(filename) ?
66
- open_from_uri(filename, tmpdir) :
67
- filename
68
- ) { |f| f.read }
63
+ filename = download_uri(filename, tmpdir)
64
+ CSV.foreach(filename, options, &block)
69
65
  end
66
+ else
67
+ CSV.foreach(filename, options, &block)
68
+ end
70
69
  end
71
70
 
72
71
  def read_cells(sheet=nil)
73
72
  sheet ||= @default_sheet
74
- @cell_type = {} unless @cell_type
75
- @cell = {} unless @cell
73
+ return if @cells_read[sheet]
76
74
  @first_row[sheet] = 1
77
75
  @last_row[sheet] = 0
78
76
  @first_column[sheet] = 1
79
77
  @last_column[sheet] = 1
80
78
  rownum = 1
81
- CSV.parse data do |row|
79
+ each_row csv_options do |row|
82
80
  row.each_with_index do |elem,i|
83
81
  @cell[[rownum,i+1]] = cell_postprocessing rownum,i+1, elem
84
82
  @cell_type[[rownum,i+1]] = celltype_class @cell[[rownum,i+1]]
@@ -112,4 +110,4 @@ class Roo::Csv < Roo::GenericSpreadsheet
112
110
  @last_column[sheet] -= 1
113
111
  end
114
112
  end
115
- end # class Csv
113
+ end
@@ -1,23 +1,33 @@
1
1
  require 'spreadsheet'
2
- #require 'lib/roo/generic_spreadsheet'
3
- #require 'parseexcel'
4
- CHARGUESS =
5
- begin
6
- require 'charguess'
7
- true
8
- rescue LoadError
9
- false
10
- end
11
2
 
12
3
  # Class for handling Excel-Spreadsheets
13
- class Roo::Excel < Roo::GenericSpreadsheet
4
+ class Roo::Excel < Roo::Base
5
+ FORMULAS_MESSAGE = 'the spreadsheet gem does not support forumulas, so roo can not.'
6
+ CHARGUESS =
7
+ begin
8
+ require 'charguess'
9
+ true
10
+ rescue LoadError
11
+ false
12
+ end
13
+
14
+ attr_reader :workbook
14
15
 
15
16
  # Creates a new Excel spreadsheet object.
16
17
  # Parameter packed: :zip - File is a zip-file
17
- def initialize(filename, packed = nil, file_warning = :error)
18
+ def initialize(filename, options = {}, deprecated_file_warning = :error)
19
+ if Hash === options
20
+ packed = options[:packed]
21
+ file_warning = options[:file_warning] || :error
22
+ else
23
+ warn 'Supplying `packed` or `file_warning` as separate arguments to `Roo::Excel.new` is deprected. Use an options hash instead.'
24
+ packed = options
25
+ file_warning = deprecated_file_warning
26
+ end
27
+
18
28
  file_type_check(filename,'.xls','an Excel', file_warning, packed)
19
29
  make_tmpdir do |tmpdir|
20
- filename = open_from_uri(filename, tmpdir) if uri?(filename)
30
+ filename = download_uri(filename, tmpdir) if uri?(filename)
21
31
  filename = open_from_stream(filename[7..-1], tmpdir) if filename[0,7] == "stream:"
22
32
  filename = unzip(filename, tmpdir) if packed == :zip
23
33
 
@@ -27,16 +37,8 @@ class Roo::Excel < Roo::GenericSpreadsheet
27
37
  end
28
38
  @workbook = Spreadsheet.open(filename)
29
39
  end
30
- @default_sheet = self.sheets.first
31
- @cell = Hash.new
32
- @cell_type = Hash.new
40
+ super(filename, options)
33
41
  @formula = Hash.new
34
- @first_row = Hash.new
35
- @last_row = Hash.new
36
- @first_column = Hash.new
37
- @last_column = Hash.new
38
- @header_line = 1
39
- @cells_read = Hash.new
40
42
  @fonts = Hash.new
41
43
  end
42
44
 
@@ -49,12 +51,19 @@ class Roo::Excel < Roo::GenericSpreadsheet
49
51
  @workbook.worksheets.collect {|worksheet| normalize_string(worksheet.name)}
50
52
  end
51
53
 
54
+ # this method lets you find the worksheet with the most data
55
+ def longest_sheet
56
+ sheet(@workbook.worksheets.inject {|m,o|
57
+ o.row_count > m.row_count ? o : m
58
+ }.name)
59
+ end
60
+
52
61
  # returns the content of a cell. The upper left corner is (1,1) or ('A',1)
53
62
  def cell(row,col,sheet=nil)
54
63
  sheet ||= @default_sheet
55
64
  validate_sheet!(sheet)
56
65
 
57
- read_cells(sheet) unless @cells_read[sheet]
66
+ read_cells(sheet)
58
67
  raise "should be read" unless @cells_read[sheet]
59
68
  row,col = normalize(row,col)
60
69
  if celltype(row,col,sheet) == :date
@@ -82,7 +91,7 @@ class Roo::Excel < Roo::GenericSpreadsheet
82
91
  # * :datetime
83
92
  def celltype(row,col,sheet=nil)
84
93
  sheet ||= @default_sheet
85
- read_cells(sheet) unless @cells_read[sheet]
94
+ read_cells(sheet)
86
95
  row,col = normalize(row,col)
87
96
  begin
88
97
  if @formula[sheet] and @formula[sheet][[row,col]]
@@ -98,23 +107,19 @@ class Roo::Excel < Roo::GenericSpreadsheet
98
107
 
99
108
  # returns NO formula in excel spreadsheets
100
109
  def formula(row,col,sheet=nil)
101
- wait_for_version_080
102
- end
103
-
104
- # raises an exception because formulas are not supported for excel files
105
- def formula?(row,col,sheet=nil)
106
- wait_for_version_080
110
+ raise NotImplementedError, FORMULAS_MESSAGE
107
111
  end
112
+ alias_method :formula?, :formula
108
113
 
109
114
  # returns NO formulas in excel spreadsheets
110
115
  def formulas(sheet=nil)
111
- wait_for_version_080
116
+ raise NotImplementedError, FORMULAS_MESSAGE
112
117
  end
113
118
 
114
119
  # Given a cell, return the cell's font
115
120
  def font(row, col, sheet=nil)
116
121
  sheet ||= @default_sheet
117
- read_cells(sheet) unless @cells_read[sheet]
122
+ read_cells(sheet)
118
123
  row,col = normalize(row,col)
119
124
  @fonts[sheet][[row,col]]
120
125
  end
@@ -123,7 +128,7 @@ class Roo::Excel < Roo::GenericSpreadsheet
123
128
  # mainly for debugging purposes
124
129
  def to_s(sheet=nil)
125
130
  sheet ||= @default_sheet
126
- read_cells(sheet) unless @cells_read[sheet]
131
+ read_cells(sheet)
127
132
  @cell[sheet].inspect
128
133
  end
129
134
 
@@ -239,10 +244,7 @@ class Roo::Excel < Roo::GenericSpreadsheet
239
244
  def read_cells(sheet=nil)
240
245
  sheet ||= @default_sheet
241
246
  validate_sheet!(sheet)
242
-
243
- if @cells_read[sheet]
244
- raise "sheet #{sheet} already read"
245
- end
247
+ return if @cells_read[sheet]
246
248
 
247
249
  worksheet = @workbook.worksheet(sheet_no(sheet))
248
250
  row_index=1
@@ -286,7 +288,6 @@ class Roo::Excel < Roo::GenericSpreadsheet
286
288
  false
287
289
  end
288
290
  end
289
- private :date_or_time?
290
291
 
291
292
  # Read the date-time cell and convert to,
292
293
  # the date-time values for Roo
@@ -326,7 +327,6 @@ class Roo::Excel < Roo::GenericSpreadsheet
326
327
  end
327
328
  return value_type, value
328
329
  end
329
- private :read_cell_date_or_time
330
330
 
331
331
  # Read the cell and based on the class,
332
332
  # return the values for Roo
@@ -345,15 +345,5 @@ class Roo::Excel < Roo::GenericSpreadsheet
345
345
  end # case
346
346
  return value_type, value
347
347
  end
348
- private :read_cell
349
-
350
- def wait_for_version_080
351
- if Spreadsheet::VERSION<='0.8.0'
352
- raise 'Formulas are not supported for excel spreadsheets.' +
353
- " We have to wait for the 0.8.0 version of the Spreadsheet gem (currently used version is #{Spreadsheet::VERSION})"
354
- else
355
- raise 'Thomas should implement formulas from Spreadsheet gem'
356
- end
357
- end
358
348
 
359
349
  end
@@ -1,35 +1,34 @@
1
- require 'fileutils'
2
1
  require 'date'
3
2
  require 'base64'
4
- require 'cgi'
5
3
  require 'nokogiri'
6
4
 
7
- class Roo::Excel2003XML < Roo::GenericSpreadsheet
5
+ class Roo::Excel2003XML < Roo::Base
8
6
 
9
7
  # initialization and opening of a spreadsheet file
10
8
  # values for packed: :zip
11
- def initialize(filename, packed=nil, file_warning=:error)
9
+ def initialize(filename, options={}, deprecated_file_warning=:error)
10
+ if Hash === options
11
+ packed = options[:packed]
12
+ file_warning = options[:file_warning] || :error
13
+ else
14
+ warn 'Supplying `packed` or `file_warning` as separate arguments to `Roo::Excel2003XML.new` is deprected. Use an options hash instead.'
15
+ packed = options
16
+ file_warning = deprecated_file_warning
17
+ end
18
+
12
19
  make_tmpdir do |tmpdir|
13
- filename = open_from_uri(filename, tmpdir) if uri?(filename)
20
+ filename = download_uri(filename, tmpdir) if uri?(filename)
14
21
  filename = unzip(filename, tmpdir) if packed == :zip
15
22
 
16
23
  file_type_check(filename,'.xml','an Excel 2003 XML', file_warning)
17
- @cells_read = Hash.new
18
24
  @filename = filename
19
25
  unless File.file?(@filename)
20
26
  raise IOError, "file #{@filename} does not exist"
21
27
  end
22
- @doc = Nokogiri::XML(open(@filename))
28
+ @doc = load_xml(@filename)
23
29
  end
24
- @default_sheet = self.sheets.first
25
- @cell = Hash.new
26
- @cell_type = Hash.new
30
+ super(filename, options)
27
31
  @formula = Hash.new
28
- @first_row = Hash.new
29
- @last_row = Hash.new
30
- @first_column = Hash.new
31
- @last_column = Hash.new
32
- @header_line = 1
33
32
  @style = Hash.new
34
33
  @style_defaults = Hash.new { |h,k| h[k] = [] }
35
34
  @style_definitions = Hash.new
@@ -42,7 +41,7 @@ class Roo::Excel2003XML < Roo::GenericSpreadsheet
42
41
  # cell at the first line and first row.
43
42
  def cell(row, col, sheet=nil)
44
43
  sheet ||= @default_sheet
45
- read_cells(sheet) unless @cells_read[sheet]
44
+ read_cells(sheet)
46
45
  row,col = normalize(row,col)
47
46
  if celltype(row,col,sheet) == :date
48
47
  yyyy,mm,dd = @cell[sheet][[row,col]].split('-')
@@ -56,22 +55,11 @@ class Roo::Excel2003XML < Roo::GenericSpreadsheet
56
55
  # The method #formula? checks if there is a formula.
57
56
  def formula(row,col,sheet=nil)
58
57
  sheet ||= @default_sheet
59
- read_cells(sheet) unless @cells_read[sheet]
60
- row,col = normalize(row,col)
61
- if @formula[sheet][[row,col]] == nil
62
- return nil
63
- else
64
- return @formula[sheet][[row,col]]["oooc:".length..-1]
65
- end
66
- end
67
-
68
- # true, if there is a formula
69
- def formula?(row,col,sheet=nil)
70
- sheet ||= @default_sheet
71
- read_cells(sheet) unless @cells_read[sheet]
58
+ read_cells(sheet)
72
59
  row,col = normalize(row,col)
73
- formula(row,col) != nil
60
+ @formula[sheet][[row,col]] && @formula[sheet][[row,col]]["oooc:".length..-1]
74
61
  end
62
+ alias_method :formula?, :formula
75
63
 
76
64
  class Font
77
65
  attr_accessor :bold, :italic, :underline
@@ -92,7 +80,7 @@ class Roo::Excel2003XML < Roo::GenericSpreadsheet
92
80
  # Given a cell, return the cell's style
93
81
  def font(row, col, sheet=nil)
94
82
  sheet ||= @default_sheet
95
- read_cells(sheet) unless @cells_read[sheet]
83
+ read_cells(sheet)
96
84
  row,col = normalize(row,col)
97
85
  style_name = @style[sheet][[row,col]] || @style_defaults[sheet][col - 1] || 'Default'
98
86
  @style_definitions[style_name]
@@ -108,7 +96,7 @@ class Roo::Excel2003XML < Roo::GenericSpreadsheet
108
96
  # * :datetime
109
97
  def celltype(row,col,sheet=nil)
110
98
  sheet ||= @default_sheet
111
- read_cells(sheet) unless @cells_read[sheet]
99
+ read_cells(sheet)
112
100
  row,col = normalize(row,col)
113
101
  if @formula[sheet][[row,col]]
114
102
  return :formula
@@ -134,7 +122,7 @@ class Roo::Excel2003XML < Roo::GenericSpreadsheet
134
122
  # mainly for debugging purposes
135
123
  def to_s(sheet=nil)
136
124
  sheet ||= @default_sheet
137
- read_cells(sheet) unless @cells_read[sheet]
125
+ read_cells(sheet)
138
126
  @cell[sheet].inspect
139
127
  end
140
128
 
@@ -148,7 +136,7 @@ class Roo::Excel2003XML < Roo::GenericSpreadsheet
148
136
  def formulas(sheet=nil)
149
137
  theformulas = Array.new
150
138
  sheet ||= @default_sheet
151
- read_cells(sheet) unless @cells_read[sheet]
139
+ read_cells(sheet)
152
140
  first_row(sheet).upto(last_row(sheet)) {|row|
153
141
  first_column(sheet).upto(last_column(sheet)) {|col|
154
142
  if formula?(row,col,sheet)
@@ -204,9 +192,9 @@ class Roo::Excel2003XML < Roo::GenericSpreadsheet
204
192
  #++
205
193
  def read_cells(sheet=nil)
206
194
  sheet ||= @default_sheet
195
+ validate_sheet!(sheet)
196
+ return if @cells_read[sheet]
207
197
  sheet_found = false
208
- raise ArgumentError, "Error: sheet '#{sheet||'nil'}' not valid" if @default_sheet == nil and sheet==nil
209
- raise RangeError unless self.sheets.include? sheet
210
198
  @doc.xpath("/ss:Workbook/ss:Worksheet[@ss:Name='#{sheet}']").each do |ws|
211
199
  sheet_found = true
212
200
  row = 1
@@ -1,8 +1,7 @@
1
- require 'fileutils'
2
1
  require 'date'
3
2
  require 'nokogiri'
4
3
 
5
- class Roo::Excelx < Roo::GenericSpreadsheet
4
+ class Roo::Excelx < Roo::Base
6
5
  module Format
7
6
  EXCEPTIONAL_FORMATS = {
8
7
  'h:mm am/pm' => :date,
@@ -66,56 +65,47 @@ class Roo::Excelx < Roo::GenericSpreadsheet
66
65
 
67
66
  # initialization and opening of a spreadsheet file
68
67
  # values for packed: :zip
69
- def initialize(filename, packed=nil, file_warning = :error) #, create = false)
68
+ def initialize(filename, options = {}, deprecated_file_warning = :error)
69
+ if Hash === options
70
+ packed = options[:packed]
71
+ file_warning = options[:file_warning] || :error
72
+ else
73
+ warn 'Supplying `packed` or `file_warning` as separate arguments to `Roo::Excelx.new` is deprected. Use an options hash instead.'
74
+ packed = options
75
+ file_warning = deprecated_file_warning
76
+ end
77
+
70
78
  file_type_check(filename,'.xlsx','an Excel-xlsx', file_warning, packed)
71
79
  make_tmpdir do |tmpdir|
72
- filename = open_from_uri(filename, tmpdir) if uri?(filename)
80
+ filename = download_uri(filename, tmpdir) if uri?(filename)
73
81
  filename = unzip(filename, tmpdir) if packed == :zip
74
- @cells_read = Hash.new
75
82
  @filename = filename
76
83
  unless File.file?(@filename)
77
84
  raise IOError, "file #{@filename} does not exist"
78
85
  end
79
86
  @comments_files = Array.new
80
87
  extract_content(tmpdir, @filename)
81
- @workbook_doc = File.open(File.join(tmpdir, "roo_workbook.xml")) do |file|
82
- Nokogiri::XML(file)
83
- end
88
+ @workbook_doc = load_xml(File.join(tmpdir, "roo_workbook.xml"))
84
89
  @shared_table = []
85
90
  if File.exist?(File.join(tmpdir, 'roo_sharedStrings.xml'))
86
- @sharedstring_doc = File.open(File.join(tmpdir, 'roo_sharedStrings.xml')) do |file|
87
- Nokogiri::XML(file)
88
- end
91
+ @sharedstring_doc = load_xml(File.join(tmpdir, 'roo_sharedStrings.xml'))
89
92
  read_shared_strings(@sharedstring_doc)
90
93
  end
91
94
  @styles_table = []
92
95
  @style_definitions = Array.new # TODO: ??? { |h,k| h[k] = {} }
93
96
  if File.exist?(File.join(tmpdir, 'roo_styles.xml'))
94
- @styles_doc = File.open(File.join(tmpdir, 'roo_styles.xml')) do |file|
95
- Nokogiri::XML(file)
96
- end
97
+ @styles_doc = load_xml(File.join(tmpdir, 'roo_styles.xml'))
97
98
  read_styles(@styles_doc)
98
99
  end
99
100
  @sheet_doc = @sheet_files.map do |item|
100
- File.open(item) do |file|
101
- Nokogiri::XML(file)
102
- end
101
+ load_xml(item)
103
102
  end
104
103
  @comments_doc = @comments_files.map do |item|
105
- File.open(item) do |file|
106
- Nokogiri::XML(file)
107
- end
104
+ load_xml(item)
108
105
  end
109
106
  end
110
- @default_sheet = self.sheets.first
111
- @cell = Hash.new
112
- @cell_type = Hash.new
107
+ super(filename, options)
113
108
  @formula = Hash.new
114
- @first_row = Hash.new
115
- @last_row = Hash.new
116
- @first_column = Hash.new
117
- @last_column = Hash.new
118
- @header_line = 1
119
109
  @excelx_type = Hash.new
120
110
  @excelx_value = Hash.new
121
111
  @s_attribute = Hash.new # TODO: ggf. wieder entfernen nur lokal benoetigt
@@ -128,7 +118,7 @@ class Roo::Excelx < Roo::GenericSpreadsheet
128
118
  read_labels
129
119
  if @label.has_key?(m.to_s)
130
120
  sheet ||= @default_sheet
131
- read_cells(sheet) unless @cells_read[sheet]
121
+ read_cells(sheet)
132
122
  row,col = label(m.to_s)
133
123
  cell(row,col)
134
124
  else
@@ -143,7 +133,7 @@ class Roo::Excelx < Roo::GenericSpreadsheet
143
133
  # cell at the first line and first row.
144
134
  def cell(row, col, sheet=nil)
145
135
  sheet ||= @default_sheet
146
- read_cells(sheet) unless @cells_read[sheet]
136
+ read_cells(sheet)
147
137
  row,col = normalize(row,col)
148
138
  if celltype(row,col,sheet) == :date
149
139
  yyyy,mm,dd = @cell[sheet][[row,col]].split('-')
@@ -162,28 +152,17 @@ class Roo::Excelx < Roo::GenericSpreadsheet
162
152
  # The method #formula? checks if there is a formula.
163
153
  def formula(row,col,sheet=nil)
164
154
  sheet ||= @default_sheet
165
- read_cells(sheet) unless @cells_read[sheet]
155
+ read_cells(sheet)
166
156
  row,col = normalize(row,col)
167
- if @formula[sheet][[row,col]] == nil
168
- return nil
169
- else
170
- return @formula[sheet][[row,col]]
171
- end
172
- end
173
-
174
- # true, if there is a formula
175
- def formula?(row,col,sheet=nil)
176
- sheet ||= @default_sheet
177
- read_cells(sheet) unless @cells_read[sheet]
178
- row,col = normalize(row,col)
179
- formula(row,col) != nil
157
+ @formula[sheet][[row,col]] && @formula[sheet][[row,col]]
180
158
  end
159
+ alias_method :formula?, :formula
181
160
 
182
161
  # returns each formula in the selected sheet as an array of elements
183
162
  # [row, col, formula]
184
163
  def formulas(sheet=nil)
185
164
  sheet ||= @default_sheet
186
- read_cells(sheet) unless @cells_read[sheet]
165
+ read_cells(sheet)
187
166
  if @formula[sheet]
188
167
  @formula[sheet].each.collect do |elem|
189
168
  [elem[0][0], elem[0][1], elem[1]]
@@ -212,7 +191,7 @@ class Roo::Excelx < Roo::GenericSpreadsheet
212
191
  # Given a cell, return the cell's style
213
192
  def font(row, col, sheet=nil)
214
193
  sheet ||= @default_sheet
215
- read_cells(sheet) unless @cells_read[sheet]
194
+ read_cells(sheet)
216
195
  row,col = normalize(row,col)
217
196
  s_attribute = @s_attribute[sheet][[row,col]]
218
197
  s_attribute ||= 0
@@ -230,7 +209,7 @@ class Roo::Excelx < Roo::GenericSpreadsheet
230
209
  # * :datetime
231
210
  def celltype(row,col,sheet=nil)
232
211
  sheet ||= @default_sheet
233
- read_cells(sheet) unless @cells_read[sheet]
212
+ read_cells(sheet)
234
213
  row,col = normalize(row,col)
235
214
  if @formula[sheet][[row,col]]
236
215
  return :formula
@@ -245,7 +224,7 @@ class Roo::Excelx < Roo::GenericSpreadsheet
245
224
  # Note: this is only available within the Excelx class
246
225
  def excelx_type(row,col,sheet=nil)
247
226
  sheet ||= @default_sheet
248
- read_cells(sheet) unless @cells_read[sheet]
227
+ read_cells(sheet)
249
228
  row,col = normalize(row,col)
250
229
  return @excelx_type[sheet][[row,col]]
251
230
  end
@@ -254,7 +233,7 @@ class Roo::Excelx < Roo::GenericSpreadsheet
254
233
  # Note: this is only available within the Excelx class
255
234
  def excelx_value(row,col,sheet=nil)
256
235
  sheet ||= @default_sheet
257
- read_cells(sheet) unless @cells_read[sheet]
236
+ read_cells(sheet)
258
237
  row,col = normalize(row,col)
259
238
  return @excelx_value[sheet][[row,col]]
260
239
  end
@@ -262,7 +241,7 @@ class Roo::Excelx < Roo::GenericSpreadsheet
262
241
  # returns the internal format of an excel cell
263
242
  def excelx_format(row,col,sheet=nil)
264
243
  sheet ||= @default_sheet
265
- read_cells(sheet) unless @cells_read[sheet]
244
+ read_cells(sheet)
266
245
  row,col = normalize(row,col)
267
246
  s = @s_attribute[sheet][[row,col]]
268
247
  attribute2format(s).to_s
@@ -279,7 +258,7 @@ class Roo::Excelx < Roo::GenericSpreadsheet
279
258
  # for debugging purposes
280
259
  def to_s(sheet=nil)
281
260
  sheet ||= @default_sheet
282
- read_cells(sheet) unless @cells_read[sheet]
261
+ read_cells(sheet)
283
262
  @cell[sheet].inspect
284
263
  end
285
264
 
@@ -291,7 +270,7 @@ class Roo::Excelx < Roo::GenericSpreadsheet
291
270
  return nil,nil,nil
292
271
  else
293
272
  return @label[labelname][1].to_i,
294
- Roo::GenericSpreadsheet.letter_to_number(@label[labelname][2]),
273
+ Roo::Base.letter_to_number(@label[labelname][2]),
295
274
  @label[labelname][0]
296
275
  end
297
276
  end
@@ -300,12 +279,12 @@ class Roo::Excelx < Roo::GenericSpreadsheet
300
279
  # [labelname, [row,col,sheetname]]
301
280
  def labels
302
281
  # sheet ||= @default_sheet
303
- # read_cells(sheet) unless @cells_read[sheet]
282
+ # read_cells(sheet)
304
283
  read_labels
305
284
  @label.map do |label|
306
285
  [ label[0], # name
307
286
  [ label[1][1].to_i, # row
308
- Roo::GenericSpreadsheet.letter_to_number(label[1][2]), # column
287
+ Roo::Base.letter_to_number(label[1][2]), # column
309
288
  label[1][0], # sheet
310
289
  ] ]
311
290
  end
@@ -315,7 +294,7 @@ class Roo::Excelx < Roo::GenericSpreadsheet
315
294
  # nil if there is no comment
316
295
  def comment(row,col,sheet=nil)
317
296
  sheet ||= @default_sheet
318
- #read_cells(sheet) unless @cells_read[sheet]
297
+ #read_cells(sheet)
319
298
  read_comments(sheet) unless @comments_read[sheet]
320
299
  row,col = normalize(row,col)
321
300
  return nil unless @comment[sheet]
@@ -325,7 +304,7 @@ class Roo::Excelx < Roo::GenericSpreadsheet
325
304
  # true, if there is a comment
326
305
  def comment?(row,col,sheet=nil)
327
306
  sheet ||= @default_sheet
328
- # read_cells(sheet) unless @cells_read[sheet]
307
+ # read_cells(sheet)
329
308
  read_comments(sheet) unless @comments_read[sheet]
330
309
  row,col = normalize(row,col)
331
310
  comment(row,col) != nil
@@ -365,9 +344,9 @@ class Roo::Excelx < Roo::GenericSpreadsheet
365
344
  when :string
366
345
  v
367
346
  when :date
368
- (Date.new(1899,12,30)+v.to_i).strftime("%Y-%m-%d")
347
+ (base_date+v.to_i).strftime("%Y-%m-%d")
369
348
  when :datetime
370
- (DateTime.new(1899,12,30)+v.to_f).strftime("%Y-%m-%d %H:%M:%S")
349
+ (base_date+v.to_f).strftime("%Y-%m-%d %H:%M:%S")
371
350
  when :percentage
372
351
  v.to_f
373
352
  when :time
@@ -387,6 +366,8 @@ class Roo::Excelx < Roo::GenericSpreadsheet
387
366
  def read_cells(sheet=nil)
388
367
  sheet ||= @default_sheet
389
368
  validate_sheet!(sheet)
369
+ return if @cells_read[sheet]
370
+
390
371
  @sheet_doc[sheets.index(sheet)].xpath("/xmlns:worksheet/xmlns:sheetData/xmlns:row/xmlns:c").each do |c|
391
372
  s_attribute = c['s'].to_i # should be here
392
373
  # c: <c r="A5" s="2">
@@ -420,7 +401,7 @@ class Roo::Excelx < Roo::GenericSpreadsheet
420
401
  value_type = :string
421
402
  v = inlinestr_content
422
403
  excelx_type = :string
423
- y, x = Roo::GenericSpreadsheet.split_coordinate(c['r'])
404
+ y, x = Roo::Base.split_coordinate(c['r'])
424
405
  excelx_value = inlinestr_content #cell.content
425
406
  set_cell_values(sheet,x,y,0,v,value_type,formula,excelx_type,excelx_value,s_attribute)
426
407
  end
@@ -461,7 +442,7 @@ class Roo::Excelx < Roo::GenericSpreadsheet
461
442
  value_type = :float
462
443
  cell.content
463
444
  end
464
- y, x = Roo::GenericSpreadsheet.split_coordinate(c['r'])
445
+ y, x = Roo::Base.split_coordinate(c['r'])
465
446
  set_cell_values(sheet,x,y,0,v,value_type,formula,excelx_type,excelx_value,s_attribute)
466
447
  end
467
448
  end
@@ -519,7 +500,7 @@ Datei xl/comments1.xml
519
500
  return unless @comments_doc[n] #>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
520
501
  @comments_doc[n].xpath("//xmlns:comments/xmlns:commentList/xmlns:comment").each do |comment|
521
502
  ref = comment.attributes['ref'].to_s
522
- row,col = Roo::GenericSpreadsheet.split_coordinate(ref)
503
+ row,col = Roo::Base.split_coordinate(ref)
523
504
  comment.xpath('./xmlns:text/xmlns:r/xmlns:t').each do |text|
524
505
  @comment[sheet] ||= {}
525
506
  @comment[sheet][[row,col]] = text.text
@@ -637,4 +618,21 @@ Datei xl/comments1.xml
637
618
  @numFmts[id] || Format::STANDARD_FORMATS[id.to_i]
638
619
  end
639
620
 
621
+ def base_date
622
+ @base_date ||= read_base_date
623
+ end
624
+
625
+ # Default to 1900 (minus one day due to excel quirk) but use 1904 if
626
+ # it's set in the Workbook's workbookPr
627
+ # http://msdn.microsoft.com/en-us/library/ff530155(v=office.12).aspx
628
+ def read_base_date
629
+ base_date = Date.new(1899,12,30)
630
+ @workbook_doc.xpath("//xmlns:workbookPr").map do |workbookPr|
631
+ if workbookPr["date1904"] && workbookPr["date1904"] =~ /true|1/i
632
+ base_date = Date.new(1904,01,01)
633
+ end
634
+ end
635
+ base_date
636
+ end
637
+
640
638
  end # class