roo 2.6.0 → 2.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.codeclimate.yml +17 -0
- data/.travis.yml +2 -4
- data/CHANGELOG.md +11 -0
- data/Gemfile +2 -4
- data/Gemfile_ruby2 +4 -3
- data/README.md +10 -0
- data/lib/roo/base.rb +14 -165
- data/lib/roo/csv.rb +93 -98
- data/lib/roo/excelx.rb +8 -3
- data/lib/roo/excelx/cell/datetime.rb +38 -28
- data/lib/roo/excelx/cell/number.rb +19 -23
- data/lib/roo/excelx/cell/time.rb +13 -13
- data/lib/roo/formatters/base.rb +15 -0
- data/lib/roo/formatters/csv.rb +84 -0
- data/lib/roo/formatters/matrix.rb +23 -0
- data/lib/roo/formatters/xml.rb +31 -0
- data/lib/roo/formatters/yaml.rb +40 -0
- data/lib/roo/open_office.rb +9 -3
- data/lib/roo/tempdir.rb +5 -10
- data/lib/roo/version.rb +1 -1
- data/roo.gemspec +1 -0
- data/spec/spec_helper.rb +2 -6
- data/test/excelx/cell/test_time.rb +3 -3
- data/test/formatters/test_csv.rb +119 -0
- data/test/formatters/test_matrix.rb +76 -0
- data/test/formatters/test_xml.rb +74 -0
- data/test/formatters/test_yaml.rb +20 -0
- data/test/roo/test_csv.rb +52 -0
- data/test/roo/test_excelx.rb +186 -0
- data/test/roo/test_libre_office.rb +9 -0
- data/test/roo/test_open_office.rb +126 -0
- data/test/test_helper.rb +74 -3
- data/test/test_roo.rb +22 -928
- metadata +55 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 416c34282c125b08fbf46e19c398f6a1c07d269a
|
4
|
+
data.tar.gz: 56a97234a7ddef8c1cd8aa0aa308949bc9f00d52
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8d318576088c9fd269ffc3702c38aa00f9bca4bddf97f1125d0d289c9674b0bae4136dbf43b70f635bba8f597d14bd22894b739e5306ec0690aa244638a374dd
|
7
|
+
data.tar.gz: a578beb4286e83f6a308aac442bc39bc829badc7ff35d9b0b6914550ccf587106cfbcc9974c51c957d8c16cf08dacabdf7383be1170f91ed207834035a302d8a
|
data/.codeclimate.yml
ADDED
data/.travis.yml
CHANGED
@@ -4,8 +4,7 @@ rvm:
|
|
4
4
|
- 2.3.1
|
5
5
|
- 2.4.0
|
6
6
|
- ruby-head
|
7
|
-
- jruby-
|
8
|
-
- rbx-2
|
7
|
+
- jruby-9.1.6.0
|
9
8
|
matrix:
|
10
9
|
include:
|
11
10
|
- rvm: 2.0.0
|
@@ -14,6 +13,5 @@ matrix:
|
|
14
13
|
gemfile: Gemfile_ruby2
|
15
14
|
allow_failures:
|
16
15
|
- rvm: ruby-head
|
17
|
-
- rvm: jruby-
|
18
|
-
- rvm: rbx-2
|
16
|
+
- rvm: jruby-9.1.6.0
|
19
17
|
bundler_args: --without local_development
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,16 @@
|
|
1
1
|
## Unreleased
|
2
2
|
|
3
|
+
## [2.7.0] 2016-12-31
|
4
|
+
### Fixed
|
5
|
+
- Added rack server for testing Roo's download capabilities [365](https://github.com/roo-rb/roo/pull/365)
|
6
|
+
- Refactored tests into different formats [365](https://github.com/roo-rb/roo/pull/365)
|
7
|
+
- Fixed OpenOffice for JRuby [362](https://github.com/roo-rb/roo/pull/362)
|
8
|
+
- Added '0.000000' => '%.6f' number format [354](https://github.com/roo-rb/roo/pull/354)
|
9
|
+
- Add additional formula cell types for to_csv [367][https://github.com/roo-rb/roo/pull/367]
|
10
|
+
|
11
|
+
### Added
|
12
|
+
- Extracted formatters from Roo::Base#to_* methods [364](https://github.com/roo-rb/roo/pull/364)
|
13
|
+
|
3
14
|
## [2.6.0] 2016-12-28
|
4
15
|
### Fixed
|
5
16
|
- Fixed error if sheet name starts with a slash [348](https://github.com/roo-rb/roo/pull/348)
|
data/Gemfile
CHANGED
@@ -4,13 +4,12 @@ gemspec
|
|
4
4
|
|
5
5
|
group :test do
|
6
6
|
# additional testing libs
|
7
|
-
gem 'webmock'
|
8
7
|
gem 'shoulda'
|
9
8
|
gem 'activesupport', '< 5.1'
|
10
9
|
gem 'rspec', '>= 3.0.0'
|
11
|
-
gem 'vcr'
|
12
10
|
gem 'simplecov', '>= 0.9.0', require: false
|
13
11
|
gem 'coveralls', require: false
|
12
|
+
gem "minitest-reporters"
|
14
13
|
end
|
15
14
|
|
16
15
|
group :local_development do
|
@@ -18,8 +17,7 @@ group :local_development do
|
|
18
17
|
gem 'guard-rspec', '>= 4.3.1', require: false
|
19
18
|
gem 'guard-minitest', require: false
|
20
19
|
gem 'guard-bundler', require: false
|
21
|
-
gem 'guard-preek', require: false
|
22
20
|
gem 'guard-rubocop', require: false
|
23
|
-
gem
|
21
|
+
gem "rb-readline"
|
24
22
|
gem 'pry'
|
25
23
|
end
|
data/Gemfile_ruby2
CHANGED
@@ -6,14 +6,14 @@ gem 'nokogiri', "< 1.7.0"
|
|
6
6
|
|
7
7
|
group :test do
|
8
8
|
# additional testing libs
|
9
|
-
gem 'webmock'
|
10
9
|
gem 'shoulda'
|
11
10
|
gem 'rspec', '>= 3.0.0'
|
12
|
-
gem 'vcr'
|
13
11
|
gem 'simplecov', '>= 0.9.0', require: false
|
14
12
|
gem 'coveralls', require: false
|
15
|
-
# gem "pry"
|
16
13
|
gem "activesupport", "~> 4.2.0"
|
14
|
+
gem "tins", '~> 1.6.0'
|
15
|
+
gem "term-ansicolor", "~> 1.3.2"
|
16
|
+
gem "minitest-reporters"
|
17
17
|
end
|
18
18
|
|
19
19
|
group :local_development do
|
@@ -25,5 +25,6 @@ group :local_development do
|
|
25
25
|
gem 'guard-preek', require: false
|
26
26
|
gem 'guard-rubocop', require: false
|
27
27
|
gem 'guard-reek', github: 'pericles/guard-reek', require: false
|
28
|
+
gem 'rb-readline'
|
28
29
|
gem 'pry'
|
29
30
|
end
|
data/README.md
CHANGED
@@ -262,6 +262,16 @@ Roo's public methods have stayed relatively consistent between 1.13.x and 2.0.0,
|
|
262
262
|
5. Push to the branch (`git push origin my-new-feature`)
|
263
263
|
6. Create a new Pull Request
|
264
264
|
|
265
|
+
### Testing
|
266
|
+
Roo uses Minitest and RSpec. The best of both worlds! Run `bundle exec rake` to
|
267
|
+
run the tests/examples.
|
268
|
+
|
269
|
+
Roo also has a few tests that take a long time (5+ seconds). To run these, use
|
270
|
+
`LONG_RUN=true bundle exec rake`
|
271
|
+
|
272
|
+
When testing using Ruby 2.0 or 2.1, use this command:
|
273
|
+
`BUNDLE_GEMFILE=Gemfile_ruby2 bundle exec rake`
|
274
|
+
|
265
275
|
### Issues
|
266
276
|
|
267
277
|
If you find an issue, please create a gist and refer to it in an issue ([sample gist](https://gist.github.com/stevendaniels/98a05849036e99bb8b3c)). Here are some instructions for creating such a gist.
|
data/lib/roo/base.rb
CHANGED
@@ -4,10 +4,20 @@ require 'tmpdir'
|
|
4
4
|
require 'stringio'
|
5
5
|
require 'nokogiri'
|
6
6
|
require 'roo/utils'
|
7
|
+
require "roo/formatters/base"
|
8
|
+
require "roo/formatters/csv"
|
9
|
+
require "roo/formatters/matrix"
|
10
|
+
require "roo/formatters/xml"
|
11
|
+
require "roo/formatters/yaml"
|
7
12
|
|
8
13
|
# Base class for all other types of spreadsheets
|
9
14
|
class Roo::Base
|
10
15
|
include Enumerable
|
16
|
+
include Roo::Formatters::Base
|
17
|
+
include Roo::Formatters::CSV
|
18
|
+
include Roo::Formatters::Matrix
|
19
|
+
include Roo::Formatters::XML
|
20
|
+
include Roo::Formatters::YAML
|
11
21
|
|
12
22
|
MAX_ROW_COL = 999_999.freeze
|
13
23
|
MIN_ROW_COL = 0.freeze
|
@@ -22,6 +32,10 @@ class Roo::Base
|
|
22
32
|
Roo::TEMP_PREFIX
|
23
33
|
end
|
24
34
|
|
35
|
+
def self.finalize(object_id)
|
36
|
+
proc { finalize_tempdirs(object_id) }
|
37
|
+
end
|
38
|
+
|
25
39
|
def initialize(filename, options = {}, _file_warning = :error, _tmpdir = nil)
|
26
40
|
@filename = filename
|
27
41
|
@options = options
|
@@ -105,73 +119,6 @@ class Roo::Base
|
|
105
119
|
EOS
|
106
120
|
end
|
107
121
|
|
108
|
-
# returns a rectangular area (default: all cells) as yaml-output
|
109
|
-
# you can add additional attributes with the prefix parameter like:
|
110
|
-
# oo.to_yaml({"file"=>"flightdata_2007-06-26", "sheet" => "1"})
|
111
|
-
def to_yaml(prefix = {}, from_row = nil, from_column = nil, to_row = nil, to_column = nil, sheet = default_sheet)
|
112
|
-
return '' unless first_row # empty result if there is no first_row in a sheet
|
113
|
-
|
114
|
-
from_row ||= first_row(sheet)
|
115
|
-
to_row ||= last_row(sheet)
|
116
|
-
from_column ||= first_column(sheet)
|
117
|
-
to_column ||= last_column(sheet)
|
118
|
-
|
119
|
-
result = "--- \n"
|
120
|
-
from_row.upto(to_row) do |row|
|
121
|
-
from_column.upto(to_column) do |col|
|
122
|
-
next if empty?(row, col, sheet)
|
123
|
-
|
124
|
-
result << "cell_#{row}_#{col}: \n"
|
125
|
-
prefix.each do|k, v|
|
126
|
-
result << " #{k}: #{v} \n"
|
127
|
-
end
|
128
|
-
result << " row: #{row} \n"
|
129
|
-
result << " col: #{col} \n"
|
130
|
-
result << " celltype: #{celltype(row, col, sheet)} \n"
|
131
|
-
value = cell(row, col, sheet)
|
132
|
-
if celltype(row, col, sheet) == :time
|
133
|
-
value = integer_to_timestring(value)
|
134
|
-
end
|
135
|
-
result << " value: #{value} \n"
|
136
|
-
end
|
137
|
-
end
|
138
|
-
|
139
|
-
result
|
140
|
-
end
|
141
|
-
|
142
|
-
# write the current spreadsheet to stdout or into a file
|
143
|
-
def to_csv(filename = nil, separator = ',', sheet = default_sheet)
|
144
|
-
if filename
|
145
|
-
File.open(filename, 'w') do |file|
|
146
|
-
write_csv_content(file, sheet, separator)
|
147
|
-
end
|
148
|
-
true
|
149
|
-
else
|
150
|
-
sio = ::StringIO.new
|
151
|
-
write_csv_content(sio, sheet, separator)
|
152
|
-
sio.rewind
|
153
|
-
sio.read
|
154
|
-
end
|
155
|
-
end
|
156
|
-
|
157
|
-
# returns a matrix object from the whole sheet or a rectangular area of a sheet
|
158
|
-
def to_matrix(from_row = nil, from_column = nil, to_row = nil, to_column = nil, sheet = default_sheet)
|
159
|
-
require 'matrix'
|
160
|
-
|
161
|
-
return Matrix.empty unless first_row
|
162
|
-
|
163
|
-
from_row ||= first_row(sheet)
|
164
|
-
to_row ||= last_row(sheet)
|
165
|
-
from_column ||= first_column(sheet)
|
166
|
-
to_column ||= last_column(sheet)
|
167
|
-
|
168
|
-
Matrix.rows(from_row.upto(to_row).map do |row|
|
169
|
-
from_column.upto(to_column).map do |col|
|
170
|
-
cell(row, col, sheet)
|
171
|
-
end
|
172
|
-
end)
|
173
|
-
end
|
174
|
-
|
175
122
|
def inspect
|
176
123
|
"<##{self.class}:#{object_id.to_s(8)} #{instance_variables.join(' ')}>"
|
177
124
|
end
|
@@ -274,32 +221,6 @@ class Roo::Base
|
|
274
221
|
end
|
275
222
|
end
|
276
223
|
|
277
|
-
# returns an XML representation of all sheets of a spreadsheet file
|
278
|
-
def to_xml
|
279
|
-
Nokogiri::XML::Builder.new do |xml|
|
280
|
-
xml.spreadsheet do
|
281
|
-
sheets.each do |sheet|
|
282
|
-
self.default_sheet = sheet
|
283
|
-
xml.sheet(name: sheet) do |x|
|
284
|
-
if first_row && last_row && first_column && last_column
|
285
|
-
# sonst gibt es Fehler bei leeren Blaettern
|
286
|
-
first_row.upto(last_row) do |row|
|
287
|
-
first_column.upto(last_column) do |col|
|
288
|
-
next if empty?(row, col)
|
289
|
-
|
290
|
-
x.cell(cell(row, col),
|
291
|
-
row: row,
|
292
|
-
column: col,
|
293
|
-
type: celltype(row, col))
|
294
|
-
end
|
295
|
-
end
|
296
|
-
end
|
297
|
-
end
|
298
|
-
end
|
299
|
-
end
|
300
|
-
end.to_xml
|
301
|
-
end
|
302
|
-
|
303
224
|
# when a method like spreadsheet.a42 is called
|
304
225
|
# convert it to a call of spreadsheet.cell('a',42)
|
305
226
|
def method_missing(m, *args)
|
@@ -675,76 +596,4 @@ class Roo::Base
|
|
675
596
|
ret
|
676
597
|
end
|
677
598
|
end
|
678
|
-
|
679
|
-
# Write all cells to the csv file. File can be a filename or nil. If the this
|
680
|
-
# parameter is nil the output goes to STDOUT
|
681
|
-
def write_csv_content(file = nil, sheet = nil, separator = ',')
|
682
|
-
file ||= STDOUT
|
683
|
-
return unless first_row(sheet) # The sheet is empty
|
684
|
-
|
685
|
-
1.upto(last_row(sheet)) do |row|
|
686
|
-
1.upto(last_column(sheet)) do |col|
|
687
|
-
file.print(separator) if col > 1
|
688
|
-
file.print cell_to_csv(row, col, sheet)
|
689
|
-
end
|
690
|
-
file.print("\n")
|
691
|
-
end
|
692
|
-
end
|
693
|
-
|
694
|
-
# The content of a cell in the csv output
|
695
|
-
def cell_to_csv(row, col, sheet)
|
696
|
-
return '' if empty?(row, col, sheet)
|
697
|
-
|
698
|
-
onecell = cell(row, col, sheet)
|
699
|
-
|
700
|
-
case celltype(row, col, sheet)
|
701
|
-
when :string
|
702
|
-
%("#{onecell.gsub('"', '""')}") unless onecell.empty?
|
703
|
-
when :boolean
|
704
|
-
# TODO: this only works for excelx
|
705
|
-
onecell = self.sheet_for(sheet).cells[[row, col]].formatted_value
|
706
|
-
%("#{onecell.gsub('"', '""').downcase}")
|
707
|
-
when :float, :percentage
|
708
|
-
if onecell == onecell.to_i
|
709
|
-
onecell.to_i.to_s
|
710
|
-
else
|
711
|
-
onecell.to_s
|
712
|
-
end
|
713
|
-
when :formula
|
714
|
-
case onecell
|
715
|
-
when String
|
716
|
-
%("#{onecell.gsub('"', '""')}") unless onecell.empty?
|
717
|
-
when Integer
|
718
|
-
onecell.to_s
|
719
|
-
when Float
|
720
|
-
if onecell == onecell.to_i
|
721
|
-
onecell.to_i.to_s
|
722
|
-
else
|
723
|
-
onecell.to_s
|
724
|
-
end
|
725
|
-
when DateTime
|
726
|
-
onecell.to_s
|
727
|
-
else
|
728
|
-
fail "unhandled onecell-class #{onecell.class}"
|
729
|
-
end
|
730
|
-
when :date, :datetime
|
731
|
-
onecell.to_s
|
732
|
-
when :time
|
733
|
-
integer_to_timestring(onecell)
|
734
|
-
when :link
|
735
|
-
%("#{onecell.url.gsub('"', '""')}")
|
736
|
-
else
|
737
|
-
fail "unhandled celltype #{celltype(row, col, sheet)}"
|
738
|
-
end || ''
|
739
|
-
end
|
740
|
-
|
741
|
-
# converts an integer value to a time string like '02:05:06'
|
742
|
-
def integer_to_timestring(content)
|
743
|
-
h = (content / 3600.0).floor
|
744
|
-
content -= h * 3600
|
745
|
-
m = (content / 60.0).floor
|
746
|
-
content -= m * 60
|
747
|
-
s = content
|
748
|
-
sprintf('%02d:%02d:%02d', h, m, s)
|
749
|
-
end
|
750
599
|
end
|
data/lib/roo/csv.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "csv"
|
2
|
+
require "time"
|
3
3
|
|
4
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
|
@@ -9,124 +9,119 @@ require 'time'
|
|
9
9
|
#
|
10
10
|
# You can pass options to the underlying CSV parse operation, via the
|
11
11
|
# :csv_options option.
|
12
|
-
|
13
|
-
|
14
|
-
|
12
|
+
module Roo
|
13
|
+
class CSV < Roo::Base
|
14
|
+
attr_reader :filename
|
15
|
+
|
16
|
+
# Returns an array with the names of the sheets. In CSV class there is only
|
17
|
+
# one dummy sheet, because a csv file cannot have more than one sheet.
|
18
|
+
def sheets
|
19
|
+
["default"]
|
20
|
+
end
|
15
21
|
|
16
|
-
|
22
|
+
def cell(row, col, sheet = nil)
|
23
|
+
sheet ||= default_sheet
|
24
|
+
read_cells(sheet)
|
25
|
+
@cell[normalize(row, col)]
|
26
|
+
end
|
17
27
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
28
|
+
def celltype(row, col, sheet = nil)
|
29
|
+
sheet ||= default_sheet
|
30
|
+
read_cells(sheet)
|
31
|
+
@cell_type[normalize(row, col)]
|
32
|
+
end
|
23
33
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
@cell[normalize(row,col)]
|
28
|
-
end
|
34
|
+
def cell_postprocessing(_row, _col, value)
|
35
|
+
value
|
36
|
+
end
|
29
37
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
@cell_type[normalize(row,col)]
|
34
|
-
end
|
38
|
+
def csv_options
|
39
|
+
@options[:csv_options] || {}
|
40
|
+
end
|
35
41
|
|
36
|
-
|
37
|
-
|
38
|
-
|
42
|
+
def set_value(row, col, value, _sheet)
|
43
|
+
@cell[[row, col]] = value
|
44
|
+
end
|
39
45
|
|
40
|
-
|
41
|
-
|
42
|
-
|
46
|
+
def set_type(row, col, type, _sheet)
|
47
|
+
@cell_type[[row, col]] = type
|
48
|
+
end
|
43
49
|
|
44
|
-
|
45
|
-
@cell[[row, col]] = value
|
46
|
-
end
|
50
|
+
private
|
47
51
|
|
48
|
-
|
49
|
-
|
50
|
-
|
52
|
+
TYPE_MAP = {
|
53
|
+
String => :string,
|
54
|
+
Float => :float,
|
55
|
+
Date => :date,
|
56
|
+
DateTime => :datetime,
|
57
|
+
}
|
51
58
|
|
52
|
-
|
59
|
+
def celltype_class(value)
|
60
|
+
TYPE_MAP[value.class]
|
61
|
+
end
|
53
62
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
63
|
+
def read_cells(sheet = default_sheet)
|
64
|
+
sheet ||= default_sheet
|
65
|
+
return if @cells_read[sheet]
|
66
|
+
set_row_count(sheet)
|
67
|
+
set_column_count(sheet)
|
68
|
+
row_num = 1
|
69
|
+
|
70
|
+
each_row csv_options do |row|
|
71
|
+
row.each_with_index do |elem, col_num|
|
72
|
+
coordinate = [row_num, col_num + 1]
|
73
|
+
@cell[coordinate] = elem
|
74
|
+
@cell_type[coordinate] = celltype_class(elem)
|
75
|
+
end
|
76
|
+
row_num += 1
|
77
|
+
end
|
60
78
|
|
61
|
-
|
62
|
-
|
63
|
-
end
|
79
|
+
@cells_read[sheet] = true
|
80
|
+
end
|
64
81
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
CSV.
|
82
|
+
def each_row(options, &block)
|
83
|
+
if uri?(filename)
|
84
|
+
each_row_using_temp_dir(filename)
|
85
|
+
elsif is_stream?(filename_or_stream)
|
86
|
+
::CSV.new(filename_or_stream, options).each(&block)
|
87
|
+
else
|
88
|
+
::CSV.foreach(filename, options, &block)
|
70
89
|
end
|
71
|
-
elsif is_stream?(filename_or_stream)
|
72
|
-
CSV.new(filename_or_stream, options).each(&block)
|
73
|
-
else
|
74
|
-
CSV.foreach(filename, options, &block)
|
75
90
|
end
|
76
|
-
end
|
77
91
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
@last_row[sheet] = 0
|
83
|
-
@first_column[sheet] = 1
|
84
|
-
@last_column[sheet] = 1
|
85
|
-
rownum = 1
|
86
|
-
each_row csv_options do |row|
|
87
|
-
row.each_with_index do |elem,i|
|
88
|
-
@cell[[rownum,i+1]] = cell_postprocessing rownum,i+1, elem
|
89
|
-
@cell_type[[rownum,i+1]] = celltype_class @cell[[rownum,i+1]]
|
90
|
-
if i+1 > @last_column[sheet]
|
91
|
-
@last_column[sheet] += 1
|
92
|
-
end
|
92
|
+
def each_row_using_tempdir
|
93
|
+
::Dir.mktmpdir(Roo::TEMP_PREFIX, ENV["ROO_TMP"]) do |tmpdir|
|
94
|
+
tmp_filename = download_uri(filename, tmpdir)
|
95
|
+
::CSV.foreach(tmp_filename, options, &block)
|
93
96
|
end
|
94
|
-
rownum += 1
|
95
|
-
@last_row[sheet] += 1
|
96
|
-
end
|
97
|
-
@cells_read[sheet] = true
|
98
|
-
#-- adjust @first_row if neccessary
|
99
|
-
while !row(@first_row[sheet]).any? and @first_row[sheet] < @last_row[sheet]
|
100
|
-
@first_row[sheet] += 1
|
101
|
-
end
|
102
|
-
#-- adjust @last_row if neccessary
|
103
|
-
while !row(@last_row[sheet]).any? and @last_row[sheet] and
|
104
|
-
@last_row[sheet] > @first_row[sheet]
|
105
|
-
@last_row[sheet] -= 1
|
106
97
|
end
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
@
|
98
|
+
|
99
|
+
def set_row_count(sheet)
|
100
|
+
@first_row[sheet] = 1
|
101
|
+
@last_row[sheet] = ::CSV.readlines(@filename).size
|
102
|
+
@last_row[sheet] = @first_row[sheet] if @last_row[sheet].zero?
|
103
|
+
|
104
|
+
nil
|
112
105
|
end
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
@last_column[sheet]
|
106
|
+
|
107
|
+
def set_column_count(sheet)
|
108
|
+
@first_column[sheet] = 1
|
109
|
+
@last_column[sheet] = (::CSV.readlines(@filename).first || []).size
|
110
|
+
@last_column[sheet] = @first_column[sheet] if @last_column[sheet].zero?
|
111
|
+
|
112
|
+
nil
|
118
113
|
end
|
119
|
-
end
|
120
114
|
|
121
|
-
|
122
|
-
|
115
|
+
def clean_sheet(sheet)
|
116
|
+
read_cells(sheet)
|
117
|
+
|
118
|
+
@cell.each_pair do |coord, value|
|
119
|
+
@cell[coord] = sanitize_value(value) if value.is_a?(::String)
|
120
|
+
end
|
123
121
|
|
124
|
-
|
125
|
-
@cell[coord] = sanitize_value(value) if value.is_a?(::String)
|
122
|
+
@cleaned[sheet] = true
|
126
123
|
end
|
127
124
|
|
128
|
-
|
125
|
+
alias_method :filename_or_stream, :filename
|
129
126
|
end
|
130
|
-
|
131
|
-
alias_method :filename_or_stream, :filename
|
132
127
|
end
|