ooxl 0.0.1.5.0 → 0.0.1.5.1
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.
- checksums.yaml +4 -4
- data/lib/ooxl/util.rb +12 -7
- data/lib/ooxl/version.rb +1 -1
- data/lib/ooxl/xl_objects/row.rb +5 -1
- data/lib/ooxl/xl_objects/row_cache.rb +33 -5
- data/lib/ooxl/xl_objects/sheet.rb +15 -18
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b4f14b323fab2a3362235d62a449584a6b980482
|
4
|
+
data.tar.gz: 696182e5392827ccc8754300c8e9e9df49fc020b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7c4a10ad5b476b807649a94541ce6c7a516a8efbebbd527eceab608a01eb1c0e80edbf1fd535511b521a92725c969b6196cf79b8437391a115fcf04529e853ad
|
7
|
+
data.tar.gz: c1b0926146a8b4cdf68bb55ea1b0307dd4cae502dd11a4fd7fba4b137b16fcc56931b806e651bf2a12e2d2df43c953f0b7c16232b5d5b1e7b59e56b64bade18f
|
data/lib/ooxl/util.rb
CHANGED
@@ -1,12 +1,13 @@
|
|
1
|
-
class OOXL
|
1
|
+
class OOXL
|
2
2
|
module Util
|
3
|
-
COLUMN_LETTERS = ('A'..'ZZZZ').to_a
|
4
|
-
|
5
|
-
|
3
|
+
COLUMN_LETTERS = [nil] + ('A'..'ZZZZ').to_a
|
4
|
+
|
5
|
+
def letter_index(col_letter)
|
6
|
+
column_letter_to_number(col_letter) - 1
|
6
7
|
end
|
7
8
|
|
8
|
-
def
|
9
|
-
|
9
|
+
def letter_equivalent(col_index)
|
10
|
+
column_number_to_letter(col_index + 1)
|
10
11
|
end
|
11
12
|
|
12
13
|
def to_column_letter(reference)
|
@@ -14,13 +15,17 @@ class OOXL
|
|
14
15
|
end
|
15
16
|
|
16
17
|
def uniform_reference(ref)
|
17
|
-
ref.to_s[/[A-Z]/] ?
|
18
|
+
ref.to_s[/[A-Z]/] ? column_letter_to_number(ref) : ref
|
18
19
|
end
|
19
20
|
|
20
21
|
def node_value_extractor(node)
|
21
22
|
node.try(:value)
|
22
23
|
end
|
23
24
|
|
25
|
+
def column_number_to_letter(index)
|
26
|
+
COLUMN_LETTERS.fetch(index)
|
27
|
+
end
|
28
|
+
|
24
29
|
def column_letter_to_number(column_letter)
|
25
30
|
pow = column_letter.length - 1
|
26
31
|
result = 0
|
data/lib/ooxl/version.rb
CHANGED
data/lib/ooxl/xl_objects/row.rb
CHANGED
@@ -45,12 +45,16 @@ class OOXL
|
|
45
45
|
end
|
46
46
|
|
47
47
|
def self.load_from_node(row_node, shared_strings, styles, options)
|
48
|
-
new(id: row_node
|
48
|
+
new(id: extract_id(row_node),
|
49
49
|
spans: row_node.attributes["spans"].try(:value),
|
50
50
|
height: row_node.attributes["ht"].try(:value),
|
51
51
|
cells: row_node.xpath('c').map { |cell_node| OOXL::Cell.load_from_node(cell_node, shared_strings, styles)},
|
52
52
|
options: options )
|
53
53
|
end
|
54
|
+
|
55
|
+
def self.extract_id(row_node)
|
56
|
+
row_node.attributes["r"].try(:value)
|
57
|
+
end
|
54
58
|
end
|
55
59
|
end
|
56
60
|
|
@@ -10,6 +10,8 @@ class OOXL
|
|
10
10
|
# built on-demand -- use fetch_row_by_id instead
|
11
11
|
attr_reader :row_id_map
|
12
12
|
|
13
|
+
delegate :size, to: :row_nodes
|
14
|
+
|
13
15
|
def initialize(sheet_xml, shared_strings, options = {})
|
14
16
|
@shared_strings = shared_strings
|
15
17
|
@sheet_xml = sheet_xml
|
@@ -47,11 +49,33 @@ class OOXL
|
|
47
49
|
row_cache
|
48
50
|
end
|
49
51
|
|
52
|
+
def row_range(start_index, end_index)
|
53
|
+
return enum_for(:row_range, start_index, end_index) unless block_given?
|
54
|
+
|
55
|
+
rows do |row|
|
56
|
+
row_id = row.id.to_i
|
57
|
+
next if row_id < start_index
|
58
|
+
break if row_id > end_index
|
59
|
+
|
60
|
+
yield row
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def max_row_index
|
65
|
+
return 0 if row_nodes.empty?
|
66
|
+
|
67
|
+
if all_rows_loaded?
|
68
|
+
row_cache.last.id.to_i
|
69
|
+
else
|
70
|
+
Row.extract_id(row_nodes.last).to_i
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
50
74
|
private
|
51
75
|
|
52
76
|
def parse_more_rows
|
53
77
|
row_nodes.drop(row_cache.count).each do |row_node|
|
54
|
-
row =
|
78
|
+
row = parse_row(row_node)
|
55
79
|
row_cache << row
|
56
80
|
row_id_map[row.id] = row
|
57
81
|
yield row if block_given?
|
@@ -62,10 +86,6 @@ class OOXL
|
|
62
86
|
row_cache.count == row_nodes.count
|
63
87
|
end
|
64
88
|
|
65
|
-
def row_nodes
|
66
|
-
@row_nodes ||= @sheet_xml.xpath('//sheetData/row')
|
67
|
-
end
|
68
|
-
|
69
89
|
def fetch_row_by_id(row_id)
|
70
90
|
row_id = row_id.to_s
|
71
91
|
return row_id_map[row_id] if all_rows_loaded? || row_id_map.key?(row_id)
|
@@ -95,6 +115,14 @@ class OOXL
|
|
95
115
|
end
|
96
116
|
yielded_rows
|
97
117
|
end
|
118
|
+
|
119
|
+
def row_nodes
|
120
|
+
@row_nodes ||= @sheet_xml.xpath('//sheetData/row')
|
121
|
+
end
|
122
|
+
|
123
|
+
def parse_row(row_node)
|
124
|
+
Row.load_from_node(row_node, @shared_strings, @styles, @options)
|
125
|
+
end
|
98
126
|
end
|
99
127
|
end
|
100
128
|
|
@@ -128,7 +128,7 @@ class OOXL
|
|
128
128
|
# cell_range values separated by comma
|
129
129
|
if cell_range.include?(":")
|
130
130
|
cell_letters = cell_range.gsub(/[\d]/, '').split(':')
|
131
|
-
start_index, end_index = cell_range[/[A-Z]{1,}\d+/] ? cell_range.gsub(/[^\d:]/, '').split(':').map(&:to_i) : [1,
|
131
|
+
start_index, end_index = cell_range[/[A-Z]{1,}\d+/] ? cell_range.gsub(/[^\d:]/, '').split(':').map(&:to_i) : [1, @row_cache.max_row_index]
|
132
132
|
if cell_letters.uniq.size > 1
|
133
133
|
list_values_from_rectangle(cell_letters, start_index, end_index)
|
134
134
|
else
|
@@ -148,22 +148,19 @@ class OOXL
|
|
148
148
|
# 3 => end_index
|
149
149
|
# Expected output would be: [['value', 'value', 'value'], ['value', 'value', 'value'], ['value', 'value', 'value']]
|
150
150
|
def list_values_from_rectangle(cell_letters, start_index, end_index)
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
row["#{cell_letter}#{row_index}"].value
|
151
|
+
start_col = column_letter_to_number(cell_letters.first)
|
152
|
+
end_col = column_letter_to_number(cell_letters.last)
|
153
|
+
@row_cache.row_range(start_index, end_index).map do |row|
|
154
|
+
(start_col..end_col).map do |col_index|
|
155
|
+
col_letter = column_number_to_letter(col_index)
|
156
|
+
row["#{col_letter}#{row.id}"].value
|
158
157
|
end
|
159
158
|
end
|
160
159
|
end
|
161
160
|
|
162
161
|
def list_values_from_column(column_letter, start_index, end_index)
|
163
|
-
(start_index
|
164
|
-
row
|
165
|
-
next if row.blank?
|
166
|
-
row["#{column_letter}#{row_index}"].value
|
162
|
+
@row_cache.row_range(start_index, end_index).map do |row|
|
163
|
+
row["#{column_letter}#{row.id}"].value
|
167
164
|
end
|
168
165
|
end
|
169
166
|
|
@@ -174,19 +171,19 @@ class OOXL
|
|
174
171
|
[row[cell_ref].value]
|
175
172
|
end
|
176
173
|
|
177
|
-
def self.load_from_stream(xml_stream, shared_strings)
|
178
|
-
self.new(Nokogiri.XML(xml_stream).remove_namespaces!, shared_strings)
|
179
|
-
end
|
180
|
-
|
181
174
|
def in_merged_cells?(cell_id)
|
182
175
|
column_letter, column_index = cell_id.partition(/\d+/)
|
183
|
-
range =
|
176
|
+
range = merged_cells.find { |column_range, index_range| column_range.cover?(column_letter) && index_range.cover?(column_index) }
|
184
177
|
range.present?
|
185
178
|
end
|
186
179
|
|
180
|
+
def self.load_from_stream(xml_stream, shared_strings)
|
181
|
+
self.new(xml_stream, shared_strings)
|
182
|
+
end
|
183
|
+
|
187
184
|
private
|
188
185
|
|
189
|
-
def
|
186
|
+
def merged_cells
|
190
187
|
@merged_cells ||= @xml.xpath('//mergeCells/mergeCell').map do |merged_cell|
|
191
188
|
# <mergeCell ref="Q381:R381"/>
|
192
189
|
start_reference, end_reference = merged_cell.attributes["ref"].try(:value).split(':')
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ooxl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.1.5.
|
4
|
+
version: 0.0.1.5.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- James Mones
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-10-
|
11
|
+
date: 2019-10-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|