excel_to_code 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README +41 -0
- data/bin/excel_to_c +63 -0
- data/bin/excel_to_ruby +9 -0
- data/src/commands.rb +2 -0
- data/src/commands/excel_to_c.rb +858 -0
- data/src/commands/excel_to_ruby.rb +620 -0
- data/src/compile.rb +2 -0
- data/src/compile/c.rb +5 -0
- data/src/compile/c/compile_to_c.rb +62 -0
- data/src/compile/c/compile_to_c_header.rb +26 -0
- data/src/compile/c/compile_to_c_unit_test.rb +42 -0
- data/src/compile/c/excel_to_c_runtime.c +2029 -0
- data/src/compile/c/map_formulae_to_c.rb +184 -0
- data/src/compile/c/map_sheet_names_to_c_names.rb +19 -0
- data/src/compile/c/map_values_to_c.rb +85 -0
- data/src/compile/c/map_values_to_c_structs.rb +37 -0
- data/src/compile/ruby.rb +3 -0
- data/src/compile/ruby/compile_to_ruby.rb +33 -0
- data/src/compile/ruby/compile_to_ruby_unit_test.rb +28 -0
- data/src/compile/ruby/excel_to_ruby_runtime.rb +1 -0
- data/src/compile/ruby/map_formulae_to_ruby.rb +95 -0
- data/src/compile/ruby/map_sheet_names_to_ruby_names.rb +19 -0
- data/src/compile/ruby/map_values_to_ruby.rb +65 -0
- data/src/excel.rb +5 -0
- data/src/excel/area.rb +93 -0
- data/src/excel/excel_functions.rb +84 -0
- data/src/excel/excel_functions/abs.rb +14 -0
- data/src/excel/excel_functions/add.rb +18 -0
- data/src/excel/excel_functions/and.rb +30 -0
- data/src/excel/excel_functions/apply_to_range.rb +17 -0
- data/src/excel/excel_functions/average.rb +12 -0
- data/src/excel/excel_functions/choose.rb +18 -0
- data/src/excel/excel_functions/cosh.rb +9 -0
- data/src/excel/excel_functions/count.rb +9 -0
- data/src/excel/excel_functions/counta.rb +8 -0
- data/src/excel/excel_functions/divide.rb +23 -0
- data/src/excel/excel_functions/excel_equal.rb +20 -0
- data/src/excel/excel_functions/excel_if.rb +8 -0
- data/src/excel/excel_functions/excel_match.rb +51 -0
- data/src/excel/excel_functions/find.rb +39 -0
- data/src/excel/excel_functions/iferror.rb +10 -0
- data/src/excel/excel_functions/index.rb +48 -0
- data/src/excel/excel_functions/left.rb +12 -0
- data/src/excel/excel_functions/less_than.rb +26 -0
- data/src/excel/excel_functions/less_than_or_equal.rb +26 -0
- data/src/excel/excel_functions/max.rb +12 -0
- data/src/excel/excel_functions/min.rb +12 -0
- data/src/excel/excel_functions/mod.rb +15 -0
- data/src/excel/excel_functions/more_than.rb +26 -0
- data/src/excel/excel_functions/more_than_or_equal.rb +26 -0
- data/src/excel/excel_functions/multiply.rb +24 -0
- data/src/excel/excel_functions/negative.rb +12 -0
- data/src/excel/excel_functions/not_equal.rb +19 -0
- data/src/excel/excel_functions/number_argument.rb +30 -0
- data/src/excel/excel_functions/pi.rb +7 -0
- data/src/excel/excel_functions/pmt.rb +16 -0
- data/src/excel/excel_functions/power.rb +18 -0
- data/src/excel/excel_functions/round.rb +13 -0
- data/src/excel/excel_functions/rounddown.rb +14 -0
- data/src/excel/excel_functions/roundup.rb +17 -0
- data/src/excel/excel_functions/string_join.rb +19 -0
- data/src/excel/excel_functions/subtotal.rb +13 -0
- data/src/excel/excel_functions/subtract.rb +18 -0
- data/src/excel/excel_functions/sum.rb +8 -0
- data/src/excel/excel_functions/sumif.rb +7 -0
- data/src/excel/excel_functions/sumifs.rb +74 -0
- data/src/excel/excel_functions/sumproduct.rb +32 -0
- data/src/excel/excel_functions/vlookup.rb +49 -0
- data/src/excel/formula_peg.rb +238 -0
- data/src/excel/formula_peg.txt +45 -0
- data/src/excel/reference.rb +56 -0
- data/src/excel/table.rb +108 -0
- data/src/excel_to_code.rb +7 -0
- data/src/extract.rb +13 -0
- data/src/extract/check_for_unknown_functions.rb +20 -0
- data/src/extract/extract_array_formulae.rb +23 -0
- data/src/extract/extract_formulae.rb +36 -0
- data/src/extract/extract_named_references.rb +38 -0
- data/src/extract/extract_relationships.rb +10 -0
- data/src/extract/extract_shared_formulae.rb +23 -0
- data/src/extract/extract_shared_strings.rb +20 -0
- data/src/extract/extract_simple_formulae.rb +18 -0
- data/src/extract/extract_table.rb +24 -0
- data/src/extract/extract_values.rb +29 -0
- data/src/extract/extract_worksheet_dimensions.rb +11 -0
- data/src/extract/extract_worksheet_names.rb +10 -0
- data/src/extract/extract_worksheet_table_relationships.rb +10 -0
- data/src/extract/simple_extract_from_xml.rb +19 -0
- data/src/rewrite.rb +10 -0
- data/src/rewrite/ast_copy_formula.rb +42 -0
- data/src/rewrite/ast_expand_array_formulae.rb +180 -0
- data/src/rewrite/rewrite_array_formulae.rb +71 -0
- data/src/rewrite/rewrite_array_formulae_to_arrays.rb +18 -0
- data/src/rewrite/rewrite_cell_references_to_include_sheet.rb +56 -0
- data/src/rewrite/rewrite_formulae_to_ast.rb +24 -0
- data/src/rewrite/rewrite_merge_formulae_and_values.rb +18 -0
- data/src/rewrite/rewrite_relationship_id_to_filename.rb +22 -0
- data/src/rewrite/rewrite_shared_formulae.rb +38 -0
- data/src/rewrite/rewrite_values_to_ast.rb +28 -0
- data/src/rewrite/rewrite_whole_row_column_references_to_areas.rb +90 -0
- data/src/rewrite/rewrite_worksheet_names.rb +20 -0
- data/src/simplify.rb +16 -0
- data/src/simplify/count_formula_references.rb +58 -0
- data/src/simplify/identify_dependencies.rb +56 -0
- data/src/simplify/identify_repeated_formula_elements.rb +37 -0
- data/src/simplify/inline_formulae.rb +77 -0
- data/src/simplify/map_formulae_to_values.rb +157 -0
- data/src/simplify/remove_cells.rb +18 -0
- data/src/simplify/replace_arrays_with_single_cells.rb +27 -0
- data/src/simplify/replace_blanks.rb +58 -0
- data/src/simplify/replace_common_elements_in_formulae.rb +19 -0
- data/src/simplify/replace_formulae_with_calculated_values.rb +21 -0
- data/src/simplify/replace_indirects_with_references.rb +44 -0
- data/src/simplify/replace_named_references.rb +82 -0
- data/src/simplify/replace_ranges_with_array_literals.rb +54 -0
- data/src/simplify/replace_shared_strings.rb +49 -0
- data/src/simplify/replace_table_references.rb +71 -0
- data/src/simplify/replace_values_with_constants.rb +47 -0
- data/src/simplify/simplify_arithmetic.rb +54 -0
- data/src/util.rb +2 -0
- data/src/util/not_supported_exception.rb +2 -0
- data/src/util/try.rb +9 -0
- metadata +207 -0
@@ -0,0 +1,45 @@
|
|
1
|
+
formula := space? expression+
|
2
|
+
expression = string_join | comparison | arithmetic | thing
|
3
|
+
thing = function | array | brackets | any_reference | string | percentage | number | boolean | prefix | named_reference
|
4
|
+
argument = expression | null
|
5
|
+
function := /[A-Z]+/ `'(' space argument? (space `',' space argument)* space `')'
|
6
|
+
brackets := `'(' space expression+ space `')'
|
7
|
+
array := `'{' space row ( space `';' space row )* space `'}'
|
8
|
+
row := basic_type ( space `',' space basic_type )*
|
9
|
+
basic_type = string | percentage | number | boolean
|
10
|
+
string_join := (arithmetic | thing) (space `"&" space (arithmetic | thing))+
|
11
|
+
arithmetic := thing (space operator space thing)+
|
12
|
+
comparison := (arithmetic | thing) space comparator space (arithmetic | thing)
|
13
|
+
comparator := '>=' | '<=' | '<>' | '>' | '<' | '='
|
14
|
+
string := `'"' /(""|[^"])*/ `'"'
|
15
|
+
any_reference = external_reference | any_internal_reference
|
16
|
+
any_internal_reference = table_reference | local_table_reference | sheet_reference | sheetless_reference
|
17
|
+
percentage := /[-+]?[0-9]+\.?[0-9]*/ `'%'
|
18
|
+
number := /[-+]?[0-9]+\.?[0-9]*([eE][-+]?[0-9]+)?/
|
19
|
+
operator := '+' | '-' | '/' | '*' | '^'
|
20
|
+
external_reference := /\[\d+\]!?/ any_internal_reference
|
21
|
+
table_reference := table_name `'[' (range_structured_reference | complex_structured_reference | simple_structured_reference) `']'
|
22
|
+
local_table_reference := `'[' (range_structured_reference | complex_structured_reference | overly_structured_reference | simple_structured_reference) `']'
|
23
|
+
table_name = /[.a-zA-Z0-9_]+/
|
24
|
+
range_structured_reference = /\[[^\u005d]*\],\[[^\u005d]*\]:\[[^\u005d]*\]/
|
25
|
+
complex_structured_reference = /\[[^\u005d]*\],\[[^\u005d]*\]/
|
26
|
+
overly_structured_reference = `'[' simple_structured_reference `']'
|
27
|
+
simple_structured_reference = /[^\u005d]*/
|
28
|
+
named_reference := /[#a-zA-Z][\w_.!]+/
|
29
|
+
sheet_reference := (single_quoted_string | /[a-zA-Z0-9][\w_.]+/) `'!' (sheetless_reference | named_reference)
|
30
|
+
single_quoted_string = `"'" /[^']*/ `"'"
|
31
|
+
sheetless_reference = column_range | row_range | area | cell
|
32
|
+
column_range := column `':' column
|
33
|
+
row_range := row_number `':' row_number
|
34
|
+
area := reference `':' reference
|
35
|
+
cell := reference
|
36
|
+
row_number = /\$?\d+/
|
37
|
+
column = /\$?[A-Za-z]{1,3}/
|
38
|
+
reference = /\$?[A-Za-z]{1,3}\$?[0-9]+(?![0-9A-Za-z_])/
|
39
|
+
boolean = boolean_true | boolean_false
|
40
|
+
boolean_true := `'TRUE'
|
41
|
+
boolean_false := `'FALSE'
|
42
|
+
prefix := /[-+]/ thing
|
43
|
+
space = `/[ \n]*/
|
44
|
+
null := &','
|
45
|
+
|
@@ -0,0 +1,56 @@
|
|
1
|
+
class Reference < String
|
2
|
+
|
3
|
+
# This is so that we only have one instance for a given reference
|
4
|
+
@@references_for_text ||= Hash.new do |hash,text|
|
5
|
+
hash[text] = reference = Reference.new(text)
|
6
|
+
reference
|
7
|
+
end
|
8
|
+
|
9
|
+
# This is so that we only have one instance of a given reference specified by its variables
|
10
|
+
def Reference.for(text)
|
11
|
+
@@references_for_text[text]
|
12
|
+
end
|
13
|
+
|
14
|
+
# This caches the calculation for turning column letters (e.g., AAB) into column numbers (e.g., 127)
|
15
|
+
@@column_number_for_column ||= Hash.new do |hash,letters|
|
16
|
+
number = letters.downcase.each_byte.to_a.reverse.each.with_index.inject(0) do |memo,byte_with_index,c|
|
17
|
+
memo + ((byte_with_index.first - 96) * (26**byte_with_index.last))
|
18
|
+
end
|
19
|
+
hash[letters] = number
|
20
|
+
@@column_letters_for_column_number[number] = letters.upcase
|
21
|
+
number
|
22
|
+
end
|
23
|
+
|
24
|
+
# This caches the calculation for turning column numbers (e.g., 127) into column letters (e.g., AAB)
|
25
|
+
@@column_letters_for_column_number ||= Hash.new do |hash,number|
|
26
|
+
letters = (number-1).to_i.to_s(26)
|
27
|
+
letters = (letters[0...-1].tr('1-9a-z','abcdefghijklmnopqrstuvwxyz') + letters[-1,1].tr('0-9a-z','abcdefghijklmnopqrstuvwxyz')).gsub('a0','z').gsub(/([b-z])0/) { $1.tr('b-z','a-y')+"z" }
|
28
|
+
letters.upcase!
|
29
|
+
hash[number] = letters
|
30
|
+
@@column_number_for_column[letters] = number
|
31
|
+
letters
|
32
|
+
end
|
33
|
+
|
34
|
+
attr_reader :excel_row_number, :excel_column_number, :excel_column, :excel_row
|
35
|
+
|
36
|
+
def calculate_excel_variables
|
37
|
+
return if @excel_variables_calculated
|
38
|
+
self =~ /(\$)?([A-Za-z]{1,3})(\$)?([0-9]+)/
|
39
|
+
@excel_fixed_column, @excel_column, @excel_fixed_row, @excel_row = $1, $2, $3, $4
|
40
|
+
@excel_row_number = @excel_row.to_i
|
41
|
+
@excel_column_number = @@column_number_for_column[@excel_column]
|
42
|
+
@excel_variables_calculated = true
|
43
|
+
end
|
44
|
+
|
45
|
+
def offset(rows,columns)
|
46
|
+
calculate_excel_variables
|
47
|
+
new_column = @excel_fixed_column ? @excel_column : @@column_letters_for_column_number[@excel_column_number + columns]
|
48
|
+
new_row = @excel_fixed_row ? @excel_row : @excel_row_number + rows
|
49
|
+
Reference.new([@excel_fixed_column,new_column,@excel_fixed_row,new_row].join)
|
50
|
+
end
|
51
|
+
|
52
|
+
def unfix
|
53
|
+
gsub("$","")
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
data/src/excel/table.rb
ADDED
@@ -0,0 +1,108 @@
|
|
1
|
+
require_relative '../excel'
|
2
|
+
require_relative '../util'
|
3
|
+
|
4
|
+
class Table
|
5
|
+
|
6
|
+
attr_accessor :name
|
7
|
+
|
8
|
+
def initialize(name,worksheet,reference,number_of_total_rows,*column_name_array)
|
9
|
+
@name, @worksheet, @area, @number_of_total_rows, @column_name_array = name, worksheet, Area.for(reference), number_of_total_rows.to_i, column_name_array.map { |c| c.strip.downcase }
|
10
|
+
@area.calculate_excel_variables
|
11
|
+
@data_area = Area.for("#{@area.excel_start.offset(1,0)}:#{@area.excel_finish.offset(-@number_of_total_rows,0)}")
|
12
|
+
end
|
13
|
+
|
14
|
+
def reference_for(table_name,structured_reference,calling_worksheet,calling_cell)
|
15
|
+
raise NotSupportedException.new("Local table reference not supported in #{structured_reference.inspect}") unless table_name
|
16
|
+
case structured_reference
|
17
|
+
when /\[#Headers\],\[(.*?)\]:\[(.*?)\]/io
|
18
|
+
column_number_start = @column_name_array.find_index($1.strip.downcase)
|
19
|
+
column_number_finish = @column_name_array.find_index($2.strip.downcase)
|
20
|
+
return ref_error unless column_number_start && column_number_finish
|
21
|
+
ast_for_area @area.excel_start.offset(0,column_number_start), @area.excel_start.offset(0,column_number_finish)
|
22
|
+
when /\[#Totals\],\[(.*?)\]:\[(.*?)\]/io
|
23
|
+
column_number_start = @column_name_array.find_index($1.strip.downcase)
|
24
|
+
column_number_finish = @column_name_array.find_index($2.strip.downcase)
|
25
|
+
return ref_error unless column_number_start && column_number_finish
|
26
|
+
ast_for_area @area.excel_start.offset(@area.height,column_number_start), @area.excel_start.offset(@area.height,column_number_finish)
|
27
|
+
when /\[#This Row\],\[(.*?)\]:\[(.*?)\]/io
|
28
|
+
r = Reference.for(calling_cell)
|
29
|
+
r.calculate_excel_variables
|
30
|
+
row = r.excel_row_number
|
31
|
+
column_number_start = @column_name_array.find_index($1.strip.downcase)
|
32
|
+
column_number_finish = @column_name_array.find_index($2.strip.downcase)
|
33
|
+
return ref_error unless column_number_start && column_number_finish
|
34
|
+
ast_for_area @area.excel_start.offset(row - @area.excel_start.excel_row_number,column_number_start), @area.excel_start.offset(row - @area.excel_start.excel_row_number,column_number_finish)
|
35
|
+
when /\[#Headers\],\[(.*?)\]/io
|
36
|
+
column_number = @column_name_array.find_index($1.strip.downcase)
|
37
|
+
return ref_error unless column_number
|
38
|
+
ast_for_cell @area.excel_start.offset(0,column_number)
|
39
|
+
when /\[#Totals\],\[(.*?)\]/io
|
40
|
+
column_number = @column_name_array.find_index($1.strip.downcase)
|
41
|
+
return ref_error unless column_number
|
42
|
+
ast_for_cell @area.excel_start.offset(@area.height,column_number)
|
43
|
+
when /\[#This Row\],\[(.*?)\]/io
|
44
|
+
r = Reference.for(calling_cell)
|
45
|
+
r.calculate_excel_variables
|
46
|
+
row = r.excel_row_number
|
47
|
+
column_number = @column_name_array.find_index($1.strip.downcase)
|
48
|
+
return ref_error unless column_number
|
49
|
+
ast_for_cell @area.excel_start.offset(row - @area.excel_start.excel_row_number,column_number)
|
50
|
+
when /#Headers/io
|
51
|
+
if calling_worksheet == @worksheet && @data_area.includes?(calling_cell)
|
52
|
+
r = Reference.for(calling_cell)
|
53
|
+
r.calculate_excel_variables
|
54
|
+
ast_for_cell "#{r.excel_column}#{@area.excel_start.excel_row_number}"
|
55
|
+
else
|
56
|
+
ast_for_area @area.excel_start.offset(0,0), @area.excel_start.offset(0,@area.width)
|
57
|
+
end
|
58
|
+
when /#Totals/io
|
59
|
+
if calling_worksheet == @worksheet && @data_area.includes?(calling_cell)
|
60
|
+
r = Reference.for(calling_cell)
|
61
|
+
r.calculate_excel_variables
|
62
|
+
ast_for_cell "#{r.excel_column}#{@area.excel_finish.excel_row_number}"
|
63
|
+
else
|
64
|
+
ast_for_area @area.excel_start.offset(@area.height,0), @area.excel_start.offset(@area.height,@area.width)
|
65
|
+
end
|
66
|
+
when /#Data/io, ""
|
67
|
+
ast_for_area @data_area.excel_start, @data_area.excel_finish
|
68
|
+
when /#All/io, ""
|
69
|
+
ast_for_area @area.excel_start, @area.excel_finish
|
70
|
+
when /#This Row/io
|
71
|
+
r = Reference.for(calling_cell)
|
72
|
+
r.calculate_excel_variables
|
73
|
+
row = r.excel_row_number
|
74
|
+
ast_for_area "#{@area.excel_start.excel_column}#{row}", "#{@area.excel_finish.excel_column}#{row}"
|
75
|
+
else
|
76
|
+
if calling_worksheet == @worksheet && @data_area.includes?(calling_cell)
|
77
|
+
r = Reference.for(calling_cell)
|
78
|
+
r.calculate_excel_variables
|
79
|
+
row = r.excel_row_number
|
80
|
+
column_number = @column_name_array.find_index(structured_reference.strip.downcase)
|
81
|
+
return ref_error unless column_number
|
82
|
+
ast_for_cell @area.excel_start.offset(row - @area.excel_start.excel_row_number,column_number)
|
83
|
+
else
|
84
|
+
column_number = @column_name_array.find_index(structured_reference.strip.downcase)
|
85
|
+
return ref_error unless column_number
|
86
|
+
ast_for_area @area.excel_start.offset(1,column_number), @area.excel_start.offset(@area.height - @number_of_total_rows,column_number)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def ast_for_area(start,finish)
|
92
|
+
[:sheet_reference,@worksheet,[:area,start,finish]]
|
93
|
+
end
|
94
|
+
|
95
|
+
def ast_for_cell(ref)
|
96
|
+
[:sheet_reference,@worksheet,[:cell,ref]]
|
97
|
+
end
|
98
|
+
|
99
|
+
def ref_error
|
100
|
+
[:error,"#REF!"]
|
101
|
+
end
|
102
|
+
|
103
|
+
def includes?(sheet,reference)
|
104
|
+
return false unless @worksheet == sheet
|
105
|
+
@area.includes?(reference)
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
data/src/extract.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require_relative 'extract/check_for_unknown_functions'
|
2
|
+
require_relative "extract/extract_array_formulae"
|
3
|
+
require_relative "extract/extract_formulae"
|
4
|
+
require_relative "extract/extract_relationships"
|
5
|
+
require_relative "extract/extract_shared_formulae"
|
6
|
+
require_relative "extract/extract_shared_strings"
|
7
|
+
require_relative "extract/extract_simple_formulae"
|
8
|
+
require_relative "extract/extract_values"
|
9
|
+
require_relative "extract/extract_worksheet_dimensions"
|
10
|
+
require_relative "extract/extract_worksheet_names"
|
11
|
+
require_relative "extract/extract_named_references"
|
12
|
+
require_relative "extract/extract_worksheet_table_relationships"
|
13
|
+
require_relative "extract/extract_table"
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require_relative '../compile/ruby/map_formulae_to_ruby'
|
2
|
+
|
3
|
+
class CheckForUnknownFunctions
|
4
|
+
|
5
|
+
attr_accessor :settable
|
6
|
+
|
7
|
+
def self.rewrite(*args)
|
8
|
+
self.new.rewrite(*args)
|
9
|
+
end
|
10
|
+
|
11
|
+
def check(input,output)
|
12
|
+
self.settable ||= lambda { |ref| false }
|
13
|
+
input.lines do |line|
|
14
|
+
line.scan(/\[:function, "(.*?)"/).each do |match|
|
15
|
+
output.puts $1 unless MapFormulaeToRuby::FUNCTIONS.has_key?($1)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require_relative 'extract_formulae'
|
2
|
+
|
3
|
+
class ExtractArrayFormulae < ExtractFormulae
|
4
|
+
|
5
|
+
attr_accessor :array_range
|
6
|
+
|
7
|
+
def start_formula(type,attributes)
|
8
|
+
return unless type == 'array' && attributes.assoc('ref')
|
9
|
+
@array_range = attributes.assoc('ref').last
|
10
|
+
@parsing = true
|
11
|
+
end
|
12
|
+
|
13
|
+
def write_formula
|
14
|
+
return false if @formula.empty?
|
15
|
+
output.write @ref
|
16
|
+
output.write "\t"
|
17
|
+
output.write @array_range
|
18
|
+
output.write "\t"
|
19
|
+
output.write @formula.join
|
20
|
+
output.write "\n"
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require_relative 'simple_extract_from_xml'
|
2
|
+
|
3
|
+
class ExtractFormulae < SimpleExtractFromXML
|
4
|
+
|
5
|
+
attr_accessor :ref, :formula
|
6
|
+
|
7
|
+
def start_element(name,attributes)
|
8
|
+
if name == 'c'
|
9
|
+
@ref = attributes.assoc('r').last
|
10
|
+
elsif name == "f"
|
11
|
+
type = attributes.assoc('t')
|
12
|
+
@formula = []
|
13
|
+
start_formula( type && type.last, attributes)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def start_formula(type,attributes)
|
18
|
+
# Should be overriden in sub classes
|
19
|
+
end
|
20
|
+
|
21
|
+
def write_formula
|
22
|
+
# Should be overriden in sub classes
|
23
|
+
end
|
24
|
+
|
25
|
+
def end_element(name)
|
26
|
+
return unless parsing && name == "f"
|
27
|
+
self.parsing = false
|
28
|
+
write_formula
|
29
|
+
end
|
30
|
+
|
31
|
+
def characters(string)
|
32
|
+
return unless parsing
|
33
|
+
@formula.push(string)
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require_relative 'simple_extract_from_xml'
|
2
|
+
|
3
|
+
class ExtractNamedReferences < SimpleExtractFromXML
|
4
|
+
|
5
|
+
attr_accessor :sheet_names
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
super
|
9
|
+
@sheet_names = []
|
10
|
+
end
|
11
|
+
|
12
|
+
def start_element(name,attributes)
|
13
|
+
if name == "sheet"
|
14
|
+
sheet_names << attributes.assoc('name').last
|
15
|
+
elsif name == "definedName"
|
16
|
+
@parsing = true
|
17
|
+
sheet = attributes.assoc('localSheetId')
|
18
|
+
if sheet
|
19
|
+
output.write sheet_names[sheet.last.to_i]
|
20
|
+
end
|
21
|
+
output.write "\t"
|
22
|
+
output.write attributes.assoc('name').last
|
23
|
+
output.write "\t"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def end_element(name)
|
28
|
+
return unless name == "definedName"
|
29
|
+
self.parsing = false
|
30
|
+
output.putc "\n"
|
31
|
+
end
|
32
|
+
|
33
|
+
def characters(string)
|
34
|
+
return unless parsing
|
35
|
+
output.write string
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require_relative 'simple_extract_from_xml'
|
2
|
+
|
3
|
+
class ExtractRelationships < SimpleExtractFromXML
|
4
|
+
|
5
|
+
def start_element(name,attributes)
|
6
|
+
return false unless name == "Relationship"
|
7
|
+
output.puts "#{attributes.assoc('Id').last}\t#{attributes.assoc('Target').last}"
|
8
|
+
end
|
9
|
+
|
10
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require_relative 'extract_formulae'
|
2
|
+
|
3
|
+
class ExtractSharedFormulae < ExtractFormulae
|
4
|
+
|
5
|
+
attr_accessor :shared_range
|
6
|
+
|
7
|
+
def start_formula(type,attributes)
|
8
|
+
return unless type == 'shared' && attributes.assoc('ref')
|
9
|
+
@shared_range = attributes.assoc('ref').last
|
10
|
+
@parsing = true
|
11
|
+
end
|
12
|
+
|
13
|
+
def write_formula
|
14
|
+
return if @formula.empty?
|
15
|
+
output.write @ref
|
16
|
+
output.write "\t"
|
17
|
+
output.write @shared_range
|
18
|
+
output.write "\t"
|
19
|
+
output.write @formula.join
|
20
|
+
output.write "\n"
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require_relative 'simple_extract_from_xml'
|
2
|
+
|
3
|
+
class ExtractSharedStrings < SimpleExtractFromXML
|
4
|
+
|
5
|
+
def start_element(name,attributes)
|
6
|
+
self.parsing = true if name == "si"
|
7
|
+
end
|
8
|
+
|
9
|
+
def end_element(name)
|
10
|
+
return unless name == "si"
|
11
|
+
self.parsing = false
|
12
|
+
output.putc "\n"
|
13
|
+
end
|
14
|
+
|
15
|
+
def characters(string)
|
16
|
+
return unless parsing
|
17
|
+
output.write string.gsub("\n","")
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require_relative 'extract_formulae'
|
2
|
+
|
3
|
+
class ExtractSimpleFormulae < ExtractFormulae
|
4
|
+
|
5
|
+
def start_formula(type,attributes)
|
6
|
+
return if type
|
7
|
+
@parsing = true
|
8
|
+
end
|
9
|
+
|
10
|
+
def write_formula
|
11
|
+
return if @formula.empty?
|
12
|
+
output.write @ref
|
13
|
+
output.write "\t"
|
14
|
+
output.write @formula.join
|
15
|
+
output.write "\n"
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require_relative 'simple_extract_from_xml'
|
2
|
+
|
3
|
+
class ExtractTable < SimpleExtractFromXML
|
4
|
+
|
5
|
+
attr_accessor :worksheet_name
|
6
|
+
|
7
|
+
def initialize(worksheet_name = nil)
|
8
|
+
super()
|
9
|
+
@worksheet_name = worksheet_name
|
10
|
+
end
|
11
|
+
|
12
|
+
def start_element(name,attributes)
|
13
|
+
if name == "table"
|
14
|
+
output.write "#{attributes.assoc('displayName').last}\t#{@worksheet_name}\t#{attributes.assoc('ref').last}\t#{attributes.assoc('totalsRowCount').try(:last) || 0}"
|
15
|
+
elsif name == "tableColumn"
|
16
|
+
output.write "\t#{attributes.assoc('name').last}"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def end_element(name)
|
21
|
+
return unless name == "table"
|
22
|
+
output.putc "\n"
|
23
|
+
end
|
24
|
+
end
|