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 CHANGED
@@ -1,3 +1,8 @@
1
+ ### 0.9.2
2
+
3
+ * Support reading files written by ex. simple_xlsx_writer that don't
4
+ specify sheet dimensions explicitly (which Excel does).
5
+
1
6
  ### 0.9.1
2
7
 
3
8
  * Fixed an important parse bug that ignored empty 'Generic' cells
@@ -1,3 +1,3 @@
1
1
  module SimpleXlsxReader
2
- VERSION = "0.9.1"
2
+ VERSION = "0.9.2"
3
3
  end
@@ -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.xpath('/xmlns:worksheet/xmlns:dimension').first.
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
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: simple_xlsx_reader
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.1
4
+ version: 0.9.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors: