xsv 0.2.1 → 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/lib/xsv/helpers.rb +4 -4
- data/lib/xsv/sheet.rb +42 -22
- data/lib/xsv/version.rb +1 -1
- data/lib/xsv/workbook.rb +5 -5
- data/lib/xsv.rb +3 -0
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2b097ec44b4cee4a7f6331a3a94f15e24f33c88258d375923f965dafe88ee13e
|
4
|
+
data.tar.gz: c2da68b26d04cb6bd28496d810f7721e327a655c1c96b695d9b091e569767d21
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b0a7b30c258e16d391990881f4574577eeee6ec3424524cdc360901ffa62033102c518b005d3b181d0b6e7887f52afa7dfc9415cb2cd762f3f0779d9801aaf5a
|
7
|
+
data.tar.gz: 32ab543df470d94eb4a81e2b271a18ba9295c0d7d9fd63cf918a18baa02b6c01e6bcfb35e6d6e42021d36f773affce5ace52fb07dd7d2ea4110b4a0cbe22fc9c
|
data/Gemfile.lock
CHANGED
data/lib/xsv/helpers.rb
CHANGED
@@ -32,14 +32,14 @@ module Xsv
|
|
32
32
|
47 => "mm:ss.0",
|
33
33
|
48 => "##0.0E+0",
|
34
34
|
49 => "@",
|
35
|
-
}
|
35
|
+
}.freeze
|
36
36
|
|
37
|
-
MINUTE = 60
|
38
|
-
HOUR = 3600
|
37
|
+
MINUTE = 60.freeze
|
38
|
+
HOUR = 3600.freeze
|
39
39
|
|
40
40
|
# Return the index number for the given Excel column name
|
41
41
|
def column_index(col)
|
42
|
-
col = col
|
42
|
+
col = col[/^[A-Z]+/]
|
43
43
|
|
44
44
|
val = 0
|
45
45
|
while col.length > 0
|
data/lib/xsv/sheet.rb
CHANGED
@@ -14,24 +14,14 @@ module Xsv
|
|
14
14
|
@mode = :array
|
15
15
|
@row_skip = 0
|
16
16
|
|
17
|
-
|
17
|
+
@has_cells = !xml.at_css("sheetData c").nil?
|
18
18
|
|
19
|
-
if
|
20
|
-
|
21
|
-
end
|
22
|
-
|
23
|
-
if lastCell
|
24
|
-
# Assume the dimension reflects the content
|
25
|
-
@column_count = column_index(lastCell) + 1
|
19
|
+
if @has_cells
|
20
|
+
@column_count, @last_row = get_sheet_dimensions
|
26
21
|
else
|
27
|
-
|
28
|
-
|
29
|
-
@column_count = rightmost_cells.max + 1
|
30
|
-
|
22
|
+
@column_count = 0
|
23
|
+
@last_row = 0
|
31
24
|
end
|
32
|
-
|
33
|
-
# Find the last row that contains actual values
|
34
|
-
@last_row = @xml.xpath("//xmlns:row[*[xmlns:v]][last()]").first["r"].to_i
|
35
25
|
end
|
36
26
|
|
37
27
|
def inspect
|
@@ -69,7 +59,7 @@ module Xsv
|
|
69
59
|
|
70
60
|
# Get row by number, starting at 0
|
71
61
|
def [](number)
|
72
|
-
row_xml = xml.
|
62
|
+
row_xml = xml.at_css("sheetData row[r=#{number + @row_skip + 1}]")
|
73
63
|
|
74
64
|
if row_xml
|
75
65
|
parse_row(row_xml)
|
@@ -81,18 +71,24 @@ module Xsv
|
|
81
71
|
# Load headers in the top row of the worksheet. After parsing of headers
|
82
72
|
# all methods return hashes instead of arrays
|
83
73
|
def parse_headers!
|
84
|
-
@mode = :array
|
85
74
|
@headers = parse_headers
|
86
|
-
|
87
75
|
@mode = :hash
|
88
76
|
|
89
77
|
true
|
90
78
|
end
|
91
79
|
|
80
|
+
def headers
|
81
|
+
if @headers.any?
|
82
|
+
@headers
|
83
|
+
else
|
84
|
+
parse_headers
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
92
88
|
private
|
93
89
|
|
94
90
|
def parse_headers
|
95
|
-
parse_row(@xml.css("sheetData row")[@row_skip])
|
91
|
+
parse_row(@xml.css("sheetData row")[@row_skip], :array)
|
96
92
|
end
|
97
93
|
|
98
94
|
def empty_row
|
@@ -104,7 +100,8 @@ module Xsv
|
|
104
100
|
end
|
105
101
|
end
|
106
102
|
|
107
|
-
def parse_row(xml)
|
103
|
+
def parse_row(xml, mode = nil)
|
104
|
+
mode ||= @mode
|
108
105
|
row = empty_row
|
109
106
|
|
110
107
|
xml.css("c").first(@column_count).each do |c_xml|
|
@@ -116,7 +113,7 @@ module Xsv
|
|
116
113
|
when "e" # N/A
|
117
114
|
nil
|
118
115
|
when nil
|
119
|
-
v = c_xml.
|
116
|
+
v = c_xml.at_css("v")
|
120
117
|
|
121
118
|
if v.nil?
|
122
119
|
nil
|
@@ -147,7 +144,7 @@ module Xsv
|
|
147
144
|
# Determine column position and pad row with nil values
|
148
145
|
col_index = column_index(c_xml["r"])
|
149
146
|
|
150
|
-
case
|
147
|
+
case mode
|
151
148
|
when :array
|
152
149
|
row[col_index] = value
|
153
150
|
when :hash
|
@@ -157,5 +154,28 @@ module Xsv
|
|
157
154
|
|
158
155
|
row
|
159
156
|
end
|
157
|
+
|
158
|
+
# Read or estimate outer bounds of sheet
|
159
|
+
def get_sheet_dimensions
|
160
|
+
dimension = xml.at_css("dimension")
|
161
|
+
|
162
|
+
if dimension
|
163
|
+
_firstCell, lastCell = dimension["ref"].split(":")
|
164
|
+
end
|
165
|
+
|
166
|
+
if lastCell
|
167
|
+
# Assume the dimension reflects the content
|
168
|
+
column_count = column_index(lastCell) + 1
|
169
|
+
else
|
170
|
+
# Find the last cell in every row that has a value
|
171
|
+
rightmost_cells = @xml.xpath("//xmlns:row/xmlns:c[*[local-name() = 'v']][last()]").map { |c| column_index(c["r"]) }
|
172
|
+
column_count = rightmost_cells.max + 1
|
173
|
+
end
|
174
|
+
|
175
|
+
# Find the last row that contains actual values
|
176
|
+
last_row = @xml.at_xpath("//xmlns:row[*[xmlns:v]][last()]")["r"].to_i
|
177
|
+
|
178
|
+
return [column_count, last_row]
|
179
|
+
end
|
160
180
|
end
|
161
181
|
end
|
data/lib/xsv/version.rb
CHANGED
data/lib/xsv/workbook.rb
CHANGED
@@ -17,7 +17,7 @@ module Xsv
|
|
17
17
|
|
18
18
|
@sheets = []
|
19
19
|
@xfs = []
|
20
|
-
@numFmts = Xsv::Helpers::BUILT_IN_NUMBER_FORMATS
|
20
|
+
@numFmts = Xsv::Helpers::BUILT_IN_NUMBER_FORMATS.dup
|
21
21
|
|
22
22
|
fetch_shared_strings
|
23
23
|
fetch_styles
|
@@ -33,11 +33,11 @@ module Xsv
|
|
33
33
|
def fetch_shared_strings
|
34
34
|
stream = @zip.glob("xl/sharedStrings.xml").first.get_input_stream
|
35
35
|
xml = Nokogiri::XML(stream)
|
36
|
-
expected_count = xml.
|
37
|
-
@shared_strings = xml.css("sst si t").map(&:inner_text)
|
36
|
+
expected_count = xml.at_css("sst")["uniqueCount"].to_i
|
37
|
+
@shared_strings = xml.css("sst si").map { |si| si.css("t").map(&:inner_text).join }
|
38
38
|
|
39
39
|
if @shared_strings.count != expected_count
|
40
|
-
raise Xsv::
|
40
|
+
raise Xsv::AssertionFailed, "Mismatch in shared strings count! #{expected_count} <> #{@shared_strings.count}"
|
41
41
|
end
|
42
42
|
|
43
43
|
stream.close
|
@@ -58,7 +58,7 @@ module Xsv
|
|
58
58
|
|
59
59
|
def fetch_sheets
|
60
60
|
@zip.glob("xl/worksheets/sheet*.xml").sort do |a, b|
|
61
|
-
a.name
|
61
|
+
a.name[/\d+/].to_i <=> b.name[/\d+/].to_i
|
62
62
|
end.each do |entry|
|
63
63
|
@sheets << Xsv::Sheet.new(self, Nokogiri::XML(entry.get_input_stream))
|
64
64
|
end
|
data/lib/xsv.rb
CHANGED