simple_xlsx_reader 0.9.1 → 0.9.2
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.
- data/CHANGELOG.md +5 -0
- data/lib/simple_xlsx_reader/version.rb +1 -1
- data/lib/simple_xlsx_reader.rb +23 -3
- data/test/simple_xlsx_reader_test.rb +58 -0
- metadata +1 -1
data/CHANGELOG.md
CHANGED
data/lib/simple_xlsx_reader.rb
CHANGED
@@ -109,9 +109,7 @@ module SimpleXlsxReader
|
|
109
109
|
def parse_sheet(sheet_name, xsheet)
|
110
110
|
sheet = Sheet.new(sheet_name)
|
111
111
|
|
112
|
-
last_column = xsheet
|
113
|
-
attributes['ref'].value.match(/:([A-Z]*)[1-9]*/).captures.first
|
114
|
-
|
112
|
+
last_column = last_column(xsheet)
|
115
113
|
rownum = -1
|
116
114
|
sheet.rows =
|
117
115
|
xsheet.xpath("/xmlns:worksheet/xmlns:sheetData/xmlns:row").map do |xrow|
|
@@ -158,6 +156,28 @@ module SimpleXlsxReader
|
|
158
156
|
sheet
|
159
157
|
end
|
160
158
|
|
159
|
+
##
|
160
|
+
# Returns the last column name, ex. 'E'
|
161
|
+
#
|
162
|
+
# Note that excel writes a '/worksheet/dimension' node we can get the
|
163
|
+
# last cell from, but some libs (ex. simple_xlsx_writer) don't record
|
164
|
+
# this. In that case, we assume the data is of uniform column length
|
165
|
+
# and check the column name of the last header row. Obviously this isn't
|
166
|
+
# the most robust strategy, but it likely fits 99% of use cases
|
167
|
+
# considering it's not a problem with actual excel docs.
|
168
|
+
def last_column(xsheet)
|
169
|
+
dimension = xsheet.xpath('/xmlns:worksheet/xmlns:dimension').first
|
170
|
+
if dimension
|
171
|
+
dimension.attributes['ref'].value.
|
172
|
+
match(/:([A-Z]*)[1-9]*/).captures.first
|
173
|
+
else
|
174
|
+
xsheet.at_xpath("/xmlns:worksheet/xmlns:sheetData/xmlns:row/xmlns:c[last()]").
|
175
|
+
attributes['r'].value.
|
176
|
+
match(/([A-Z]*)[1-9]*/).captures.first
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
|
161
181
|
# Excel doesn't record types for some cells, only its display style, so
|
162
182
|
# we have to back out the type from that style.
|
163
183
|
#
|
@@ -56,6 +56,64 @@ describe SimpleXlsxReader do
|
|
56
56
|
end
|
57
57
|
end
|
58
58
|
|
59
|
+
describe '#last_column' do
|
60
|
+
|
61
|
+
let(:generic_style) do
|
62
|
+
Nokogiri::XML(
|
63
|
+
<<-XML
|
64
|
+
<styleSheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
|
65
|
+
<cellXfs count="1">
|
66
|
+
<xf numFmtId="0" />
|
67
|
+
</cellXfs>
|
68
|
+
</styleSheet>
|
69
|
+
XML
|
70
|
+
)
|
71
|
+
end
|
72
|
+
|
73
|
+
# Note, this is not a valid sheet, since the last cell is actually D1 but
|
74
|
+
# the dimension specifies C1. This is just for testing.
|
75
|
+
let(:sheet) do
|
76
|
+
Nokogiri::XML(
|
77
|
+
<<-XML
|
78
|
+
<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
|
79
|
+
<dimension ref="A1:C1" />
|
80
|
+
<sheetData>
|
81
|
+
<row>
|
82
|
+
<c r='A1' s='0'>
|
83
|
+
<v>Cell A</v>
|
84
|
+
</c>
|
85
|
+
<c r='C1' s='0'>
|
86
|
+
<v>Cell C</v>
|
87
|
+
</c>
|
88
|
+
<c r='D1' s='0'>
|
89
|
+
<v>Cell D</v>
|
90
|
+
</c>
|
91
|
+
</row>
|
92
|
+
</sheetData>
|
93
|
+
</worksheet>
|
94
|
+
XML
|
95
|
+
)
|
96
|
+
end
|
97
|
+
|
98
|
+
let(:xml) do
|
99
|
+
SimpleXlsxReader::Document::Xml.new.tap do |xml|
|
100
|
+
xml.sheets = [sheet]
|
101
|
+
xml.styles = generic_style
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
subject { described_class.new(xml) }
|
106
|
+
|
107
|
+
it 'uses /worksheet/dimension if available' do
|
108
|
+
subject.last_column(sheet).must_equal 'C'
|
109
|
+
end
|
110
|
+
|
111
|
+
it 'uses the last header cell if /worksheet/dimension is missing' do
|
112
|
+
sheet.xpath('/xmlns:worksheet/xmlns:dimension').remove
|
113
|
+
subject.last_column(sheet).must_equal 'D'
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
59
117
|
describe "parse errors" do
|
60
118
|
after do
|
61
119
|
SimpleXlsxReader.configuration.catch_cell_load_errors = false
|