sp-excel-loader 0.3.40
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 +7 -0
- data/Gemfile +4 -0
- data/LICENSE +661 -0
- data/README.md +8 -0
- data/lib/sp-excel-loader.rb +6 -0
- data/lib/sp/excel/loader.rb +61 -0
- data/lib/sp/excel/loader/jrxml/band.rb +80 -0
- data/lib/sp/excel/loader/jrxml/band_container.rb +229 -0
- data/lib/sp/excel/loader/jrxml/box.rb +75 -0
- data/lib/sp/excel/loader/jrxml/casper_checkbox.rb +97 -0
- data/lib/sp/excel/loader/jrxml/casper_combo.rb +86 -0
- data/lib/sp/excel/loader/jrxml/casper_date.rb +54 -0
- data/lib/sp/excel/loader/jrxml/casper_radio_button.rb +48 -0
- data/lib/sp/excel/loader/jrxml/casper_text_field.rb +157 -0
- data/lib/sp/excel/loader/jrxml/client_combo_text_field.rb +72 -0
- data/lib/sp/excel/loader/jrxml/excel_to_jrxml.rb +1183 -0
- data/lib/sp/excel/loader/jrxml/extensions.rb +330 -0
- data/lib/sp/excel/loader/jrxml/field.rb +65 -0
- data/lib/sp/excel/loader/jrxml/group.rb +71 -0
- data/lib/sp/excel/loader/jrxml/image.rb +63 -0
- data/lib/sp/excel/loader/jrxml/jasper.rb +228 -0
- data/lib/sp/excel/loader/jrxml/parameter.rb +73 -0
- data/lib/sp/excel/loader/jrxml/pen.rb +97 -0
- data/lib/sp/excel/loader/jrxml/property.rb +52 -0
- data/lib/sp/excel/loader/jrxml/property_expression.rb +52 -0
- data/lib/sp/excel/loader/jrxml/report_element.rb +92 -0
- data/lib/sp/excel/loader/jrxml/static_text.rb +59 -0
- data/lib/sp/excel/loader/jrxml/style.rb +99 -0
- data/lib/sp/excel/loader/jrxml/text_field.rb +83 -0
- data/lib/sp/excel/loader/jrxml/variable.rb +77 -0
- data/lib/sp/excel/loader/json_to_xlsx.rb +159 -0
- data/lib/sp/excel/loader/model_exporter.rb +249 -0
- data/lib/sp/excel/loader/payrollexporter.rb +168 -0
- data/lib/sp/excel/loader/rubyxl_table_patch.rb +91 -0
- data/lib/sp/excel/loader/version.rb +26 -0
- data/lib/sp/excel/loader/workbookloader.rb +480 -0
- data/spec/calc_spec.rb +87 -0
- data/spec/model.xls +0 -0
- metadata +151 -0
@@ -0,0 +1,159 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
#
|
3
|
+
# Copyright (c) 2011-2016 Cloudware S.A. All rights reserved.
|
4
|
+
#
|
5
|
+
# This file is part of sp-excel-loader.
|
6
|
+
#
|
7
|
+
# sp-excel-loader is free software: you can redistribute it and/or modify
|
8
|
+
# it under the terms of the GNU Affero General Public License as published by
|
9
|
+
# the Free Software Foundation, either version 3 of the License, or
|
10
|
+
# (at your option) any later version.
|
11
|
+
#
|
12
|
+
# sp-excel-loader is distributed in the hope that it will be useful,
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
+
# GNU General Public License for more details.
|
16
|
+
#
|
17
|
+
# You should have received a copy of the GNU Affero General Public License
|
18
|
+
# along with sp-excel-loader. If not, see <http://www.gnu.org/licenses/>.
|
19
|
+
#
|
20
|
+
|
21
|
+
module Sp
|
22
|
+
module Excel
|
23
|
+
module Loader
|
24
|
+
|
25
|
+
class JsonToXlsx < WorkbookLoader
|
26
|
+
|
27
|
+
attr_accessor :json_data
|
28
|
+
attr_accessor :fields
|
29
|
+
|
30
|
+
def initialize (a_excel_template, a_json)
|
31
|
+
super(a_excel_template)
|
32
|
+
@json_data = a_json
|
33
|
+
end
|
34
|
+
|
35
|
+
def convert_to_xls ()
|
36
|
+
ws, tbl, ref = find_table('lines')
|
37
|
+
|
38
|
+
# Detect optional report mode
|
39
|
+
is_report = false
|
40
|
+
if !ws[0].nil? && !ws[0][0].nil?
|
41
|
+
ws[0][0].value.lines.each do |line|
|
42
|
+
directive, value = line.split(':')
|
43
|
+
if directive.strip == 'IsReport' and value.strip == 'true'
|
44
|
+
is_report = true
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
headers_idx = 0 .. ref.row_range.begin() - 1
|
50
|
+
footers_idx = ref.row_range.end() + 1 .. ws.count - 1
|
51
|
+
|
52
|
+
# Replace parameters in header and footer rows
|
53
|
+
(headers_idx.to_a + footers_idx.to_a).each do |row|
|
54
|
+
ref.col_range.each do |col|
|
55
|
+
next if ws[row].nil?
|
56
|
+
next if ws[row][col].nil?
|
57
|
+
value = ws[row][col].value
|
58
|
+
next if value.nil?
|
59
|
+
|
60
|
+
value = value.to_s
|
61
|
+
@json_data['data']['attributes'].each do |key, val|
|
62
|
+
value = value.gsub('$P{' + key +'}', val.to_s)
|
63
|
+
end
|
64
|
+
value = value.gsub('$V{PAGE_NUMBER}', '1')
|
65
|
+
|
66
|
+
unless @json_data['included'].nil? or @json_data['included'].size == 0
|
67
|
+
@json_data['included'][0]['attributes'].each do |key,val|
|
68
|
+
value = value.gsub('$FN?{' + key +'}', val.to_s)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
ws[row][col].change_contents(value)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# Collect mapped fields
|
76
|
+
header_row = ref.row_range.begin()
|
77
|
+
dst_row = header_row + 1
|
78
|
+
fields = Hash.new
|
79
|
+
null_fields = Array.new
|
80
|
+
|
81
|
+
ref.col_range.each do |col|
|
82
|
+
cell = ws[dst_row][col]
|
83
|
+
next if cell.nil?
|
84
|
+
next if cell.value.nil?
|
85
|
+
m = /\A\$(FN?){(.+)}\z/.match cell.value.strip()
|
86
|
+
next if m.nil?
|
87
|
+
null_fields[col] = m[1] == 'FN' ? true : false
|
88
|
+
fields[col] = m[2]
|
89
|
+
end
|
90
|
+
|
91
|
+
# Make space for the expanded data table, shift the merged cells down
|
92
|
+
if is_report && !@json_data['included'].nil? && @json_data['included'].size != 0
|
93
|
+
row_cnt = @json_data['included'].size
|
94
|
+
if row_cnt != 0
|
95
|
+
(row_cnt - 1).times { ws.insert_row(dst_row + 1) }
|
96
|
+
end
|
97
|
+
ws.merged_cells.each do |cell|
|
98
|
+
next unless cell.ref.row_range.min >= dst_row
|
99
|
+
cell.ref.instance_variable_set(:"@row_range", Range.new(cell.ref.row_range.min + row_cnt - 1, cell.ref.row_range.max + row_cnt - 1))
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
# In report mode empty the first row and column
|
104
|
+
if is_report
|
105
|
+
ws.change_row_height(0, 6)
|
106
|
+
ws.change_column_width(0, 1)
|
107
|
+
ws.each_with_index do |row, ridx|
|
108
|
+
ws.delete_cell(ridx, 0)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
# Create the table rows
|
113
|
+
if @json_data['included'].nil?
|
114
|
+
ref.col_range.each do |col|
|
115
|
+
ws[dst_row][col].change_contents('')
|
116
|
+
ws[dst_row][col].style_index = ws[header_row + 1][col].style_index
|
117
|
+
end
|
118
|
+
else
|
119
|
+
@json_data['included'].each do |line|
|
120
|
+
fields.each do |col,field|
|
121
|
+
|
122
|
+
value = line['attributes'][field]
|
123
|
+
if value.nil? and false == null_fields[col]
|
124
|
+
value = 0
|
125
|
+
end
|
126
|
+
|
127
|
+
if ws[dst_row].nil? || ws[dst_row][col].nil?
|
128
|
+
ws.add_cell(dst_row, col, value)
|
129
|
+
else
|
130
|
+
ws[dst_row][col].change_contents(value)
|
131
|
+
end
|
132
|
+
ws[dst_row][col].style_index = ws[header_row + 1][col].style_index
|
133
|
+
end
|
134
|
+
dst_row += 1
|
135
|
+
end
|
136
|
+
# Update the table size
|
137
|
+
tbl.ref = RubyXL::Reference.ind2ref(ref.row_range.begin(),
|
138
|
+
ref.col_range.begin()) + ":" +
|
139
|
+
RubyXL::Reference.ind2ref(ref.row_range.begin() + (dst_row - header_row - 1),
|
140
|
+
ref.col_range.end())
|
141
|
+
end
|
142
|
+
|
143
|
+
# In report mode delete all worksheets except the one that contains the lines table and wipe comments
|
144
|
+
if is_report
|
145
|
+
@workbook.worksheets.delete_if {|sheet| sheet.sheet_name != ws.sheet_name}
|
146
|
+
ws.comments = Array.new
|
147
|
+
end
|
148
|
+
|
149
|
+
end
|
150
|
+
|
151
|
+
def workbook
|
152
|
+
@workbook
|
153
|
+
end
|
154
|
+
|
155
|
+
end
|
156
|
+
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
@@ -0,0 +1,249 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
#
|
3
|
+
# Copyright (c) 2011-2016 Cloudware S.A. All rights reserved.
|
4
|
+
#
|
5
|
+
# This file is part of sp-excel-loader.
|
6
|
+
#
|
7
|
+
# sp-excel-loader is free software: you can redistribute it and/or modify
|
8
|
+
# it under the terms of the GNU Affero General Public License as published by
|
9
|
+
# the Free Software Foundation, either version 3 of the License, or
|
10
|
+
# (at your option) any later version.
|
11
|
+
#
|
12
|
+
# sp-excel-loader is distributed in the hope that it will be useful,
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
+
# GNU General Public License for more details.
|
16
|
+
#
|
17
|
+
# You should have received a copy of the GNU Affero General Public License
|
18
|
+
# along with sp-excel-loader. If not, see <http://www.gnu.org/licenses/>.
|
19
|
+
#
|
20
|
+
|
21
|
+
module Sp
|
22
|
+
module Excel
|
23
|
+
module Loader
|
24
|
+
|
25
|
+
class ModelExporter < WorkbookLoader
|
26
|
+
|
27
|
+
attr_accessor :model
|
28
|
+
|
29
|
+
def initialize (a_file, a_typed_export)
|
30
|
+
super(a_file)
|
31
|
+
@model = Hash.new
|
32
|
+
@typed_export = a_typed_export
|
33
|
+
end
|
34
|
+
|
35
|
+
def read_model(a_sheet_name, a_table_name)
|
36
|
+
read_model_with_typed_option(a_sheet_name, a_table_name, @typed_export)
|
37
|
+
end
|
38
|
+
|
39
|
+
def read_model_with_typed_option(a_sheet_name, a_table_name, a_typed_export)
|
40
|
+
|
41
|
+
read_cell_names(a_sheet_name)
|
42
|
+
col_names = Hash.new
|
43
|
+
header_columns = Hash.new
|
44
|
+
scalar_formulas = Hash.new
|
45
|
+
formula_lines = Array.new
|
46
|
+
scalar_values = Hash.new
|
47
|
+
value_lines = Array.new
|
48
|
+
|
49
|
+
worksheet = @workbook[a_sheet_name]
|
50
|
+
ref = nil
|
51
|
+
|
52
|
+
parse_shared_formulas(worksheet)
|
53
|
+
|
54
|
+
# Capture the columns names
|
55
|
+
worksheet.generic_storage.each do |tbl|
|
56
|
+
next unless tbl.is_a? RubyXL::Table and tbl.name == a_table_name
|
57
|
+
|
58
|
+
ref = RubyXL::Reference.new(tbl.ref)
|
59
|
+
type_row = ref.row_range.first() - 1
|
60
|
+
i = ref.col_range.first()
|
61
|
+
tbl.table_columns.each do |table_col|
|
62
|
+
if a_typed_export
|
63
|
+
col_names[i] = { 'name' => table_col.name, 'type' => get_column_type(worksheet, type_row, i) }
|
64
|
+
else
|
65
|
+
col_names[i] = table_col.name
|
66
|
+
end
|
67
|
+
i += 1
|
68
|
+
end
|
69
|
+
|
70
|
+
col_names.sort.map do |key, value|
|
71
|
+
header_columns[RubyXL::Reference.new(ref.row_range.first(),ref.col_range.first() + key - 1)] = value
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# Build the formula and value arrays
|
76
|
+
for row in ref.row_range.begin()+1..ref.row_range.end()
|
77
|
+
formula = Hash.new
|
78
|
+
value = Hash.new
|
79
|
+
col_index = 1
|
80
|
+
|
81
|
+
ref.col_range.each do |col|
|
82
|
+
|
83
|
+
cell = worksheet[row][col]
|
84
|
+
if a_typed_export
|
85
|
+
column = col_names[col_index]['name']
|
86
|
+
else
|
87
|
+
column = col_names[col_index]
|
88
|
+
end
|
89
|
+
if cell
|
90
|
+
key, expression = cell_expression(cell)
|
91
|
+
if cell.formula
|
92
|
+
formula[column] = expression
|
93
|
+
else
|
94
|
+
value[column] = expression unless expression.nil?
|
95
|
+
end
|
96
|
+
end
|
97
|
+
col_index += 1
|
98
|
+
end
|
99
|
+
formula_lines << formula
|
100
|
+
value_lines << value
|
101
|
+
end
|
102
|
+
|
103
|
+
# Read scalar values and formulas, from the rows that are not part of the lines table
|
104
|
+
renum = Array.new
|
105
|
+
renum = (0..ref.row_range.begin()).to_a
|
106
|
+
renum += (ref.row_range.end()+1..worksheet.dimension.ref.row_range.end()).to_a
|
107
|
+
for idx in renum
|
108
|
+
next if worksheet[idx].nil?
|
109
|
+
next if worksheet[idx].cells.nil?
|
110
|
+
worksheet[idx].cells.each do |cell|
|
111
|
+
if cell
|
112
|
+
key, expression = cell_expression(cell)
|
113
|
+
|
114
|
+
if cell.formula
|
115
|
+
scalar_formulas[key] = a_typed_export ? get_typed_scalar(cell, expression, worksheet) : expression
|
116
|
+
else
|
117
|
+
unless expression.nil?
|
118
|
+
scalar_values[key] = a_typed_export ? get_typed_scalar(cell, expression, worksheet) : expression
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
@model = {
|
126
|
+
'values' => scalar_values,
|
127
|
+
'formulas' => scalar_formulas,
|
128
|
+
'lines' => {
|
129
|
+
'header' => header_columns,
|
130
|
+
'formulas' => formula_lines,
|
131
|
+
'values' => value_lines
|
132
|
+
},
|
133
|
+
}
|
134
|
+
end
|
135
|
+
|
136
|
+
def cell_expression (a_cell)
|
137
|
+
|
138
|
+
cell_reference = RubyXL::Reference.ind2ref(a_cell.row, a_cell.column)
|
139
|
+
name = @cellnames[cell_reference]
|
140
|
+
formula = read_formula_expression(a_cell)
|
141
|
+
|
142
|
+
if formula != nil
|
143
|
+
if name
|
144
|
+
expression = "#{name}=#{formula}"
|
145
|
+
else
|
146
|
+
expression = "#{cell_reference}=#{formula}"
|
147
|
+
end
|
148
|
+
elsif a_cell.value
|
149
|
+
if name
|
150
|
+
if a_cell.is_date?
|
151
|
+
expression = "#{name}=excel_date(#{a_cell.value})"
|
152
|
+
else
|
153
|
+
begin
|
154
|
+
Float(a_cell.value)
|
155
|
+
expression = "#{name}=#{a_cell.value}"
|
156
|
+
rescue
|
157
|
+
expression = "#{name}=\"#{a_cell.value}\""
|
158
|
+
end
|
159
|
+
end
|
160
|
+
else
|
161
|
+
if a_cell.is_date?
|
162
|
+
expression = "#{cell_reference}=excel_date(#{a_cell.value})"
|
163
|
+
else
|
164
|
+
begin
|
165
|
+
Float(a_cell.value)
|
166
|
+
expression = "#{cell_reference}=#{a_cell.value}"
|
167
|
+
rescue
|
168
|
+
expression = "#{cell_reference}=\"#{a_cell.value}\""
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
173
|
+
return cell_reference, expression
|
174
|
+
end
|
175
|
+
|
176
|
+
def read_cell_names (a_sheet_name)
|
177
|
+
@cellnames = {}
|
178
|
+
ref_regexp = a_sheet_name + '!\$*([A-Z]+)\$*(\d+)'
|
179
|
+
@workbook.defined_names.each do |dn|
|
180
|
+
next unless dn.local_sheet_id.nil?
|
181
|
+
match = dn.reference.match(ref_regexp)
|
182
|
+
if match and match.size == 3
|
183
|
+
matched_name = match[1].to_s + match[2].to_s
|
184
|
+
if @cellnames[matched_name]
|
185
|
+
raise "**** Fatal error:\n duplicate cellname for #{matched_name}: #{@cellnames[matched_name]} and #{dn.name}"
|
186
|
+
end
|
187
|
+
@cellnames[matched_name] = dn.name
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
def get_column_type (a_worksheet, a_row_idx, a_column)
|
193
|
+
return 'TEXT' if a_worksheet[a_row_idx].nil? or a_worksheet[a_row_idx][a_column].nil? or a_worksheet[a_row_idx][a_column].value.nil?
|
194
|
+
return a_worksheet[a_row_idx][a_column].value
|
195
|
+
end
|
196
|
+
|
197
|
+
def get_typed_scalar (a_cell, a_expression, a_worksheet)
|
198
|
+
|
199
|
+
type = get_type_from_comment(a_cell.row, a_cell.column, a_worksheet)
|
200
|
+
unless type.nil?
|
201
|
+
return { 'type' => type, 'value' => a_expression }
|
202
|
+
end
|
203
|
+
|
204
|
+
if a_cell.is_date?
|
205
|
+
return { 'type' => 'DATE', 'value' => a_expression }
|
206
|
+
end
|
207
|
+
case a_cell.datatype
|
208
|
+
when RubyXL::DataType::NUMBER, nil
|
209
|
+
return { 'type' => 'DECIMAL', 'value' => a_expression }
|
210
|
+
when RubyXL::DataType::BOOLEAN
|
211
|
+
return { 'type' => 'BOOLEAN', 'value' => a_expression }
|
212
|
+
when RubyXL::DataType::DATE # Only available in Office2010
|
213
|
+
return { 'type' => 'DATE', 'value' => a_expression }
|
214
|
+
end
|
215
|
+
return { 'type' => 'TEXT', 'value' => a_expression }
|
216
|
+
end
|
217
|
+
|
218
|
+
|
219
|
+
def get_type_from_comment (a_row, a_col, a_worksheet)
|
220
|
+
|
221
|
+
if a_worksheet.comments != nil && a_worksheet.comments.size > 0 && a_worksheet.comments[0].comment_list != nil
|
222
|
+
|
223
|
+
a_worksheet.comments[0].comment_list.each do |comment|
|
224
|
+
if comment.ref.col_range.begin == a_col && comment.ref.row_range.begin == a_row
|
225
|
+
comment.text.to_s.lines.each do |text|
|
226
|
+
text.strip!
|
227
|
+
next if text == '' or text.nil?
|
228
|
+
idx = text.index(':')
|
229
|
+
next if idx.nil?
|
230
|
+
tag = text[0..(idx-1)]
|
231
|
+
value = text[(idx+1)..-1]
|
232
|
+
next if tag.nil? or value.nil?
|
233
|
+
tag.strip!
|
234
|
+
value.strip!
|
235
|
+
|
236
|
+
if tag == 'type'
|
237
|
+
return value
|
238
|
+
end
|
239
|
+
end
|
240
|
+
end
|
241
|
+
end
|
242
|
+
end
|
243
|
+
return nil
|
244
|
+
end
|
245
|
+
|
246
|
+
end
|
247
|
+
end
|
248
|
+
end
|
249
|
+
end
|
@@ -0,0 +1,168 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
#
|
3
|
+
# Copyright (c) 2011-2016 Cloudware S.A. All rights reserved.
|
4
|
+
#
|
5
|
+
# This file is part of sp-excel-loader.
|
6
|
+
#
|
7
|
+
# sp-excel-loader is free software: you can redistribute it and/or modify
|
8
|
+
# it under the terms of the GNU Affero General Public License as published by
|
9
|
+
# the Free Software Foundation, either version 3 of the License, or
|
10
|
+
# (at your option) any later version.
|
11
|
+
#
|
12
|
+
# sp-excel-loader is distributed in the hope that it will be useful,
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
+
# GNU General Public License for more details.
|
16
|
+
#
|
17
|
+
# You should have received a copy of the GNU Affero General Public License
|
18
|
+
# along with sp-excel-loader. If not, see <http://www.gnu.org/licenses/>.
|
19
|
+
#
|
20
|
+
|
21
|
+
module Sp
|
22
|
+
module Excel
|
23
|
+
module Loader
|
24
|
+
|
25
|
+
class PayrollExporter < ModelExporter
|
26
|
+
|
27
|
+
attr_accessor :tables
|
28
|
+
attr_accessor :model
|
29
|
+
|
30
|
+
def initialize (a_file, a_typed_export)
|
31
|
+
super(a_file, a_typed_export)
|
32
|
+
@tables = Hash.new
|
33
|
+
@pretty = true
|
34
|
+
end
|
35
|
+
|
36
|
+
def read_untyped_table (a_worksheet, a_table, a_table_name)
|
37
|
+
|
38
|
+
tbl = Array.new
|
39
|
+
ref = RubyXL::Reference.new(a_table.ref)
|
40
|
+
|
41
|
+
ref.col_range.each do |col|
|
42
|
+
|
43
|
+
col_obj = Hash.new
|
44
|
+
col_data = Array.new
|
45
|
+
|
46
|
+
type = 'number'
|
47
|
+
for row in ref.row_range.begin()+1..ref.row_range.end()
|
48
|
+
next if a_worksheet[row][col].nil?
|
49
|
+
next if a_worksheet[row][col].value.nil?
|
50
|
+
next if a_worksheet[row][col].value.is_a? Numeric
|
51
|
+
next if a_worksheet[row][col].value.is_a? String and a_worksheet[row][col].value.length() == 0
|
52
|
+
begin
|
53
|
+
Float(a_worksheet[row][col].value)
|
54
|
+
rescue
|
55
|
+
type = 'text'
|
56
|
+
break
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
col_obj['name'] = a_worksheet[ref.row_range.begin()][col].value.to_s
|
61
|
+
col_obj['type'] = type
|
62
|
+
col_obj['data'] = col_data
|
63
|
+
|
64
|
+
for row in ref.row_range.begin()+1..ref.row_range.end()
|
65
|
+
if type == 'number'
|
66
|
+
if a_worksheet[row][col].nil?
|
67
|
+
col_data << 0.0
|
68
|
+
else
|
69
|
+
col_data << a_worksheet[row][col].value.to_f
|
70
|
+
end
|
71
|
+
else
|
72
|
+
if a_worksheet[row][col].nil?
|
73
|
+
col_data << ''
|
74
|
+
else
|
75
|
+
col_data << a_worksheet[row][col].value.to_s
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
tbl << col_obj
|
81
|
+
end
|
82
|
+
@tables[a_table.name] = tbl
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
def read_see_table (a_table_name)
|
87
|
+
tbl = []
|
88
|
+
|
89
|
+
tbl_instances = self.send "#{a_table_name}"
|
90
|
+
|
91
|
+
# Get all columns reading all getter methods from first instance of a_table_name
|
92
|
+
columns = tbl_instances.first.class.instance_methods(false).select { |method| method.to_s[-1] != '=' }
|
93
|
+
|
94
|
+
columns.each do |column|
|
95
|
+
col_obj = Hash.new
|
96
|
+
col_data = Array.new
|
97
|
+
|
98
|
+
tbl_instances.each do |line|
|
99
|
+
column_value = line.send(column)
|
100
|
+
is_numeric = column_value.class.in?([Fixnum, BigDecimal])
|
101
|
+
|
102
|
+
# We are at the first line of table, so prepare the structure
|
103
|
+
if col_obj.empty?
|
104
|
+
col_obj['name'] = column.to_s
|
105
|
+
col_obj['type'] = is_numeric ? 'number' : 'text'
|
106
|
+
col_obj['data'] = col_data
|
107
|
+
end
|
108
|
+
|
109
|
+
col_data << (is_numeric ? column_value.to_f : column_value.to_s)
|
110
|
+
end
|
111
|
+
|
112
|
+
tbl << col_obj
|
113
|
+
end
|
114
|
+
|
115
|
+
tbl
|
116
|
+
end
|
117
|
+
|
118
|
+
def read_all_untyped_tables ()
|
119
|
+
@workbook.worksheets.each do |ws|
|
120
|
+
ws.generic_storage.each do |tbl|
|
121
|
+
next unless tbl.is_a? RubyXL::Table
|
122
|
+
next if tbl.name == 'LINES'
|
123
|
+
read_untyped_table(ws, tbl, tbl.name)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def write_json_file (a_directory, a_name, a_object)
|
129
|
+
FileUtils::mkdir_p(a_directory)
|
130
|
+
File.open(File.join(a_directory, a_name + '.json'),"w") do |f|
|
131
|
+
if @pretty
|
132
|
+
f.write(JSON.pretty_generate(a_object))
|
133
|
+
else
|
134
|
+
f.write(a_object.to_json)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
def write_json_tables (a_directory)
|
140
|
+
a_directory = File.join(a_directory, 'tables')
|
141
|
+
@tables.each do |name, table|
|
142
|
+
write_json_file(a_directory, name, table)
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def write_typed_json_tables (a_directory)
|
147
|
+
a_directory = File.join(a_directory, 'tables')
|
148
|
+
@table_names.each do |name|
|
149
|
+
next if name == 'LINES'
|
150
|
+
next if name != 'TABELA_RETROATIVOS'
|
151
|
+
|
152
|
+
write_json_file(a_directory, name, read_see_table(name))
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
def export(a_directory)
|
157
|
+
self.read_all_untyped_tables # Legacy code when all tables of excel are typed
|
158
|
+
self.read_all_tables
|
159
|
+
self.write_json_file(a_directory, 'model', self.read_model_with_typed_option('PROCESSAMENTO', 'LINES', false))
|
160
|
+
self.write_json_file(a_directory, 'model_typed', self.read_model_with_typed_option('PROCESSAMENTO', 'LINES', true))
|
161
|
+
self.write_json_tables(a_directory) # Legacy code when all tables of excel are typed
|
162
|
+
self.write_typed_json_tables(a_directory)
|
163
|
+
self
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|