1
+ # frozen_string_literal: true
2
+
1
3
require 'zip/filesystem'
2
4
require 'nokogiri'
3
5
4
6
module Creek
5
7
class Creek ::Sheet
6
8
include Creek ::Utils
7
9
10
+ HEADERS_ROW_NUMBER = '1'
11
+
12
+ attr_accessor :with_headers
8
13
attr_reader :book ,
9
14
:name ,
10
15
:sheetid ,
11
16
:state ,
12
17
:visible ,
13
18
:rid ,
14
- :index
15
-
19
+ :index ,
20
+ :headers
16
21
17
- def initialize book , name , sheetid , state , visible , rid , sheetfile
22
+ def initialize ( book , name , sheetid , state , visible , rid , sheetfile )
18
23
@book = book
19
24
@name = name
20
25
@sheetid = sheetid
@@ -46,7 +51,6 @@ def images_at(cell)
46
51
@drawing . images_at ( cell ) if @images_present
47
52
end
48
53
49
-
50
54
##
51
55
# Provides an Enumerator that returns a hash representing each row.
52
56
# The key of the hash is the column ID and the value is the value of the cell.
@@ -89,35 +93,37 @@ def rows_generator include_meta_data=false, use_simple_rows_format=false
89
93
closer = Nokogiri ::XML ::Reader ::TYPE_END_ELEMENT
90
94
Enumerator . new do |y |
91
95
row , cells , cell = nil , { } , nil
92
- cell_type = nil
96
+ cell_type = nil
93
97
cell_style_idx = nil
94
98
@book . files . file . open ( path ) do |xml |
95
99
Nokogiri ::XML ::Reader . from_io ( xml ) . each do |node |
96
- if ( node . name . eql? 'row' ) and ( node . node_type . eql? opener )
100
+ if node . name == 'row' && node . node_type == opener
97
101
row = node . attributes
98
- row [ 'cells' ] = Hash . new
99
- cells = Hash . new
102
+ row [ 'cells' ] = { }
103
+ cells = { }
100
104
y << ( include_meta_data ? row : cells ) if node . self_closing?
101
- elsif ( node . name . eql? 'row' ) and ( node . node_type . eql? closer )
105
+ elsif node . name == 'row' && node . node_type == closer
102
106
processed_cells = fill_in_empty_cells ( cells , row [ 'r' ] , cell , use_simple_rows_format )
107
+ @headers = processed_cells if row [ 'r' ] == HEADERS_ROW_NUMBER
103
108
104
109
if @images_present
105
110
processed_cells . each do |cell_name , cell_value |
106
111
next unless cell_value . nil?
112
+
107
113
processed_cells [ cell_name ] = images_at ( cell_name )
108
114
end
109
115
end
110
116
111
117
row [ 'cells' ] = processed_cells
112
118
y << ( include_meta_data ? row : processed_cells )
113
- elsif ( node . name . eql? 'c' ) and ( node . node_type . eql? opener )
119
+ elsif node . name == 'c' && node . node_type == opener
114
120
cell_type = node . attributes [ 't' ]
115
121
cell_style_idx = node . attributes [ 's' ]
116
122
cell = node . attributes [ 'r' ]
117
- elsif ( [ 'v' , 't' ] . include? node . name ) and ( node . node_type . eql? opener )
123
+ elsif %w[ v t ] . include? ( node . name ) && node . node_type == opener
118
124
unless cell . nil?
119
125
node . read
120
- cells [ ( use_simple_rows_format ? cell . tr ( "0-9" , "" ) : cell ) ] = convert ( node . value , cell_type , cell_style_idx )
126
+ cells [ cell ] = convert ( node . value , cell_type , cell_style_idx )
121
127
end
122
128
end
123
129
end
@@ -142,15 +148,13 @@ def converter_options
142
148
# The unzipped XML file does not contain any node for empty cells.
143
149
# Empty cells are being padded in using this function
144
150
def fill_in_empty_cells ( cells , row_number , last_col , use_simple_rows_format )
145
- new_cells = Hash . new
151
+ new_cells = { }
152
+ return new_cells if cells . empty?
146
153
147
- unless cells . empty?
148
- last_col = last_col . gsub ( row_number , '' )
149
-
150
- ( "A" ..last_col ) . to_a . each do |column |
151
- id = use_simple_rows_format ? "#{ column } " : "#{ column } #{ row_number } "
152
- new_cells [ id ] = cells [ id ]
153
- end
154
+ last_col = last_col . gsub ( row_number , '' )
155
+ ( 'A' ..last_col ) . to_a . each do |column |
156
+ id = cell_id ( column , use_simple_rows_format , row_number )
157
+ new_cells [ id ] = cells [ "#{ column } #{ row_number } " ]
154
158
end
155
159
156
160
new_cells
@@ -172,5 +176,11 @@ def extract_drawing_filepath
172
176
sheet_rels_filepath = expand_to_rels_path ( sheet_filepath )
173
177
parse_xml ( sheet_rels_filepath ) . css ( "Relationship[@Id='#{ drawing_rid } ']" ) . first . attributes [ 'Target' ] . value
174
178
end
179
+
180
+ def cell_id ( column , use_simple_rows_format , row_number = '' )
181
+ return "#{ column } #{ row_number } " unless use_simple_rows_format
182
+
183
+ with_headers && headers ? headers [ column ] : column
184
+ end
175
185
end
176
186
end
0 commit comments