ar_loader 0.0.4

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.
@@ -0,0 +1,182 @@
1
+ # Copyright:: (c) Autotelik Media Ltd 2011
2
+ # Author :: Tom Statter
3
+ # Date :: Aug 2010
4
+ # License:: MIT
5
+ #
6
+ # An Excel file helper. Create and populate XSL files
7
+ #
8
+ # The maximum number of columns and rows in an Excel file is fixed at 256 Columns and 65536 Rows
9
+ #
10
+ # POI jar location needs to be added to class path.
11
+ #
12
+ # TODO - Check out http://poi.apache.org/poi-ruby.html
13
+ #
14
+ class Object
15
+ def add_to_classpath(path)
16
+ $CLASSPATH << File.join( ArLoader.root_path, 'lib', path.gsub("\\", "/") )
17
+ end
18
+ end
19
+
20
+ require 'java'
21
+ require 'rubygems'
22
+
23
+ add_to_classpath 'java/poi-3.6.jar'
24
+
25
+ class JExcelFile
26
+ include_class 'org.apache.poi.poifs.filesystem.POIFSFileSystem'
27
+ include_class 'org.apache.poi.hssf.usermodel.HSSFCell'
28
+ include_class 'org.apache.poi.hssf.usermodel.HSSFWorkbook'
29
+ include_class 'org.apache.poi.hssf.usermodel.HSSFCellStyle'
30
+ include_class 'org.apache.poi.hssf.usermodel.HSSFDataFormat'
31
+
32
+ include_class 'java.io.ByteArrayOutputStream'
33
+ include_class 'java.util.Date'
34
+ include_class 'java.io.FileInputStream'
35
+
36
+ attr_accessor :book, :row, :current_sheet
37
+
38
+ attr_reader :sheet
39
+
40
+ MAX_COLUMNS = 256.freeze
41
+ MAX_ROWS = 65536.freeze
42
+
43
+ # The HSSFWorkbook uses 0 based indexes
44
+
45
+ def initialize()
46
+ @book = nil
47
+ end
48
+
49
+ def open(filename)
50
+ inp = FileInputStream.new(filename)
51
+
52
+ @book = HSSFWorkbook.new(inp)
53
+
54
+ sheet(0) # also sets @current_sheet
55
+ end
56
+
57
+ def create(sheet_name)
58
+ @book = HSSFWorkbook.new()
59
+ @sheet = @book.createSheet(sheet_name.gsub(" ", ''))
60
+ date_style = @book.createCellStyle()
61
+ date_style.setDataFormat(HSSFDataFormat.getBuiltinFormat("m/d/yy h:mm"))
62
+ end
63
+
64
+ # Return the current or specified HSSFSheet
65
+ def sheet(i = nil)
66
+ @current_sheet = i if i
67
+ @sheet = @book.getSheetAt(@current_sheet)
68
+ @sheet
69
+ end
70
+
71
+ def num_rows
72
+ @sheet.getPhysicalNumberOfRows
73
+ end
74
+
75
+ # Process each row. (type is org.apache.poi.hssf.usermodel.HSSFRow)
76
+
77
+ def each_row
78
+ @sheet.rowIterator.each { |row| yield row }
79
+ end
80
+
81
+
82
+ # Create new row, bring index in line with POI usage (our 1 is their 0)
83
+ def create_row(index)
84
+ @row = @sheet.createRow(index)
85
+ @row
86
+ end
87
+
88
+ def set_cell(row, column, data)
89
+ @row = @sheet.getRow(row) || create_row(row)
90
+ @row.createCell(column).setCellValue(data)
91
+ end
92
+
93
+ def value(row, column)
94
+ raise TypeError, "Expect row argument of type HSSFRow" unless row.is_a?(Java::OrgApachePoiHssfUsermodel::HSSFRow)
95
+ #puts "DEBUG - CELL VALUE : #{column} => #{ cell_value( row.getCell(column) ).inspect}"
96
+ cell_value( row.getCell(column) )
97
+ end
98
+
99
+ def cell_value(cell)
100
+ return nil unless cell
101
+ #puts "DEBUG CELL TYPE : #{cell} => #{cell.getCellType().inspect}"
102
+ case (cell.getCellType())
103
+ when HSSFCell::CELL_TYPE_FORMULA then return cell.getCellFormula()
104
+ when HSSFCell::CELL_TYPE_NUMERIC then return cell.getNumericCellValue()
105
+ when HSSFCell::CELL_TYPE_STRING then return cell.getStringCellValue()
106
+ when HSSFCell::CELL_TYPE_BOOLEAN then return cell.getBooleanCellValue()
107
+ when HSSFCell::CELL_TYPE_BLANK then return ""
108
+ end
109
+ end
110
+
111
+ def save( filename )
112
+ File.open( filename, 'w') {|f| f.write(to_s) }
113
+ end
114
+
115
+
116
+ # The internal representation of a Excel File
117
+
118
+ def to_s
119
+ outs = ByteArrayOutputStream.new
120
+ @book.write(outs);
121
+ outs.close();
122
+ String.from_java_bytes(outs.toByteArray)
123
+ end
124
+
125
+ end
126
+
127
+ module ExcelHelper
128
+ require 'java'
129
+
130
+ include_class 'org.apache.poi.poifs.filesystem.POIFSFileSystem'
131
+ include_class 'org.apache.poi.hssf.usermodel.HSSFCell'
132
+ include_class 'org.apache.poi.hssf.usermodel.HSSFWorkbook'
133
+ include_class 'org.apache.poi.hssf.usermodel.HSSFCellStyle'
134
+ include_class 'org.apache.poi.hssf.usermodel.HSSFDataFormat'
135
+ include_class 'java.io.ByteArrayOutputStream'
136
+ include_class 'java.util.Date'
137
+
138
+ # ActiveRecord Helper - Export model data to XLS file format
139
+ #
140
+ def to_xls(items=[])
141
+
142
+ @excel = ExcelFile.new(items[0].class.name)
143
+
144
+ @excel.create_row(0)
145
+
146
+ sheet = @excel.sheet
147
+
148
+ # header row
149
+ if !items.empty?
150
+ row = sheet.createRow(0)
151
+ cell_index = 0
152
+ items[0].class.columns.each do |column|
153
+ row.createCell(cell_index).setCellValue(column.name)
154
+ cell_index += 1
155
+ end
156
+ end
157
+
158
+ # value rows
159
+ row_index = 1
160
+ items.each do |item|
161
+ row = sheet.createRow(row_index);
162
+
163
+ cell_index = 0
164
+ item.class.columns.each do |column|
165
+ cell = row.createCell(cell_index)
166
+ if column.sql_type =~ /date/ then
167
+ millis = item.send(column.name).to_f * 1000
168
+ cell.setCellValue(Date.new(millis))
169
+ cell.setCellStyle(dateStyle);
170
+ elsif column.sql_type =~ /int/ then
171
+ cell.setCellValue(item.send(column.name).to_i)
172
+ else
173
+ value = item.send(column.name)
174
+ cell.setCellValue(item.send(column.name)) unless value.nil?
175
+ end
176
+ cell_index += 1
177
+ end
178
+ row_index += 1
179
+ end
180
+ @excel.to_s
181
+ end
182
+ end
@@ -0,0 +1,44 @@
1
+ # Copyright:: (c) Autotelik Media Ltd 2011
2
+ # Author :: Tom Statter
3
+ # Date :: Jan 2011
4
+ # License:: MIT
5
+ #
6
+ # JAVA SPECIFIC LOAD
7
+ require 'java'
8
+ require 'rubygems'
9
+ require 'jexcel_file'
10
+ require 'method_mapper'
11
+
12
+ class MethodMapperExcel < MethodMapper
13
+
14
+ attr_accessor :excel, :sheet
15
+
16
+ # Read the headers from a spreadsheet and map to ActiveRecord members/associations
17
+
18
+ def initialize( file_name, klass, sheet_number = 0 )
19
+ super()
20
+
21
+ @excel = JExcelFile.new
22
+
23
+ @excel.open(file_name)
24
+
25
+ @sheet = @excel.sheet( sheet_number )
26
+
27
+ @header_row = @sheet.getRow(0)
28
+
29
+ raise "ERROR: No headers found - Check Sheet #{@sheet} is completed sheet and Row 1 contains headers" unless @header_row
30
+
31
+ @headers = []
32
+ (0..JExcelFile::MAX_COLUMNS).each do |i|
33
+ cell = @header_row.getCell(i)
34
+ break unless cell
35
+ @headers << "#{@excel.cell_value(cell).to_s}".strip
36
+ end
37
+
38
+ # Gather list of all possible 'setter' methods on AR class (instance variables and associations)
39
+ MethodMapperExcel.find_operators( klass )
40
+
41
+ # Convert the list of headers into suitable calls on the Active Record class
42
+ find_method_details( klass, @headers )
43
+ end
44
+ end
@@ -0,0 +1,88 @@
1
+ # This class provides a value map (hash) from a text mapping file
2
+ #
3
+ # The map file is a text file of delimeted key -> values pairs
4
+ #
5
+ # SUPPORTED FILE FORMATS:
6
+ #
7
+ # 2 column e.g. a,b
8
+ # creates a simple hash {a => b)
9
+ #
10
+ # 3 column e.g. a,b,c
11
+ # a,b becomes the key, c is the vaule
12
+ # creates a hash { [a,b] => c }
13
+ #
14
+ # 4 column e.g. a,b,c,d
15
+ # a,b becomes the key, c,d the value
16
+ # creates a hash { [a,b] => [c,d] }
17
+ #
18
+ # TODO allow mapping file to be an xml file
19
+ #
20
+ class ValueMapFromFile < Hash
21
+
22
+ def intialize(file_path, delim = ',')
23
+ @delegate_to = {}
24
+ @delim = delim
25
+ load_map(file_path)
26
+ end
27
+
28
+ def load_map(file_path = nil, delim = ',')
29
+ @file = file_path unless file_path.nil?
30
+ @delim = delim
31
+
32
+ raise BadConfigError.new("Can not read map file: #{@file}") unless File.readable?(@file)
33
+
34
+ File.open(@file).each_line do |line|
35
+ next unless(line && line.chomp!)
36
+
37
+ values = line.split(@delim)
38
+
39
+ case values.nitems
40
+ when 2: self.store(values[0], values[1])
41
+ when 3: self.store([values[0], values[1]], values[2])
42
+ when 4: self.store([values[0], values[1]],[values[2], values[3]])
43
+ else
44
+ raise BadConfigError.new("Bad key,value row in #{@file}: #{values.nitems} number of columns not supported")
45
+ end
46
+ end
47
+
48
+ return self
49
+ end
50
+ end
51
+
52
+
53
+ # Expects file of format [TradeType,LDN_TradeId,HUB_TradeId,LDN_AssetId,HUB_AssetId,LDN_StrutureId,HUB_StructureId,LDN_ProductType,HUB_ProductType]
54
+ # Convets in to and araya containing rows [LDN_TradeId, LDN_AssetId, HUB_TradeId, HUB_AssetId]
55
+ class AssetMapFromFile < Array
56
+
57
+ def intialize(file_path, delim = ',')
58
+ @delegate_to = {}
59
+ @delim = delim
60
+ load_map(file_path)
61
+ end
62
+
63
+ def load_map(file_path = nil, delim = ',')
64
+ @file = file_path unless file_path.nil?
65
+ @delim = delim
66
+
67
+ raise BadConfigError.new("Can not read asset map file: #{@file}") unless File.readable?(@file)
68
+
69
+ File.open(@file).each_line do |line|
70
+ next unless(line && line.chomp!)
71
+ # skip the header row
72
+ next if line.include?('TradeType')
73
+
74
+ values = line.split(@delim)
75
+
76
+ self.push(Array[values[1], values[3], values[2], values[4]])
77
+ end
78
+
79
+ return self
80
+ end
81
+
82
+ def write_map(file_path = nil, delim = ',')
83
+ mapfile = File.open( file_path, 'w')
84
+
85
+ self.each{|row| mapfile.write(row.join(delim)+"\n")}
86
+ end
87
+
88
+ end
@@ -0,0 +1,139 @@
1
+ # Copyright:: (c) Autotelik Media Ltd 2011
2
+ # Author :: Tom Statter
3
+ # Date :: Aug 2010
4
+ # License:: MIT
5
+ #
6
+ # Details:: This class provides information and access to the individual methods
7
+ # on an AR model. Populated by, and coupled with MethodMapper,
8
+ # which does the model interrogation work.
9
+ # Enables 'loaders' to iterate over the MethodMapper results set,
10
+ # and assign values to AR object, without knowing anything about that receiving object.
11
+ #
12
+ # =>
13
+ require 'to_b'
14
+
15
+ class MethodDetail
16
+
17
+ # When looking up an association, try each of these in turn till a match
18
+ # i.e find_by_name .. find_by_title and so on
19
+ @@insistent_find_by_list ||= [:id, :name, :title]
20
+
21
+ attr_accessor :klass, :name, :assignment, :col_type
22
+ attr_accessor :has_many, :has_many_class_name, :has_many_class
23
+ attr_accessor :belongs_to, :belongs_to_class_name, :belongs_to_class
24
+
25
+ @@default_values = {}
26
+ @@prefixes = {}
27
+
28
+
29
+ def initialize(klass, name, assignment, belongs_to, has_many, col_type = nil)
30
+ @klass, @name, @assignment, @has_many, @belongs_to, @col_type = klass, name, assignment, has_many, belongs_to, col_type
31
+
32
+ if(@has_many)
33
+ begin
34
+ @has_many_class = Kernel.const_get(@has_many.classify)
35
+ @has_many_class_name = @has_many.classify
36
+ rescue
37
+ end
38
+ end
39
+
40
+ if(@belongs_to)
41
+ begin
42
+ @belongs_to_class = Kernel.const_get(@belongs_to.classify)
43
+ @belongs_to_class_name = @belongs_to.classify
44
+ rescue
45
+ # TODO - try other forms of the name, set to nil, or bomb out ?
46
+ end
47
+ end
48
+ end
49
+
50
+ def assign( record, value )
51
+ #puts "DEBUG: assign: [#{@name}]"
52
+
53
+ data = value
54
+
55
+ if(@@default_values[@name])
56
+ puts "WARNING nil value supplied for [#{@name}] - Using default : [#{@@default_values[@name]}]"
57
+ data = @@default_values[@name]
58
+ else
59
+ puts "WARNING nil value supplied for [#{@name}] - No default"
60
+ end if(data.nil?)
61
+
62
+ data = "#{@@prefixes[@name]}#{data}" if(@@prefixes[@name])
63
+
64
+ if( @belongs_to )
65
+
66
+ #puts "DEBUG : BELONGS_TO #{@belongs_to} - Lookup #{data} in DB"
67
+ insistent_belongs_to(record, data)
68
+
69
+ elsif( @assignment && @col_type )
70
+ #puts "DEBUG : COl TYPE defined for #{@name} : #{@assignment} => #{data} #{@col_type.inspect}"
71
+ record.send( @assignment, @col_type.type_cast( data ) )
72
+
73
+ elsif( @assignment )
74
+ #puts "DEBUG : No COL TYPE found for #{@name} : #{@assignment} => #{data}"
75
+ insistent_assignment(record, data)
76
+ end
77
+ end
78
+
79
+ # Attempt to find the associated object via id, name, title ....
80
+ def insistent_belongs_to( record, value )
81
+
82
+ @@insistent_find_by_list.each do |x|
83
+ begin
84
+ item = @belongs_to_class.send( "find_by_#{x}", value)
85
+ if(item)
86
+ record.send("#{@belongs_to}=", item)
87
+ break
88
+ end
89
+ rescue => e
90
+ puts e.inspect
91
+ if(x == @@insistent_method_list.last)
92
+ puts "I'm sorry I have failed to assign [#{value}] to #{@assignment}"
93
+ raise "I'm sorry I have failed to assign [#{value}] to #{@assignment}" unless value.nil?
94
+ end
95
+ end
96
+ end
97
+ end
98
+
99
+ def insistent_assignment( record, value )
100
+ @@insistent_method_list ||= [:to_i, :to_f, :to_b]
101
+ begin
102
+ record.send(@assignment, value)
103
+ rescue => e
104
+ puts e.inspect
105
+ @@insistent_method_list.each do |f|
106
+ begin
107
+ record.send(@assignment, value.send( f) )
108
+ break
109
+ rescue => e
110
+ #puts "DEBUG: insistent_assignment: #{e.inspect}"
111
+ if f == @@insistent_method_list.last
112
+ puts "I'm sorry I have failed to assign [#{value}] to #{@assignment}"
113
+ raise "I'm sorry I have failed to assign [#{value}] to #{@assignment}" unless value.nil?
114
+ end
115
+ end
116
+ end
117
+ end
118
+ end
119
+
120
+ def self.set_default_value( name, value )
121
+ @@default_values[name] = value
122
+ end
123
+
124
+ def self.default_value(name)
125
+ @@default_values[name]
126
+ end
127
+
128
+ def self.set_prefix( name, value )
129
+ @@prefixes[name] = value
130
+ end
131
+
132
+ def self.default_value(name)
133
+ @@prefixes[name]
134
+ end
135
+
136
+ def pp
137
+ "#{@name} => #{@assignment} : #{@has_many}"
138
+ end
139
+ end
@@ -0,0 +1,157 @@
1
+ # Copyright:: (c) Autotelik Media Ltd 2011
2
+ # Author :: Tom Statter
3
+ # Date :: Aug 2010
4
+ # License:: MIT
5
+ #
6
+ # Details:: A base class that stores details of all possible associations on AR classes and,
7
+ # given user supplied class and name, attempts to find correct attribute/association.
8
+ #
9
+ # Derived classes define where the user supplied list of names originates from.
10
+ #
11
+ # Example usage, load from a spreadsheet where the column names are only
12
+ # an approximation of the actual associations. Given a column heading of
13
+ # 'Product Properties' on class Product, find_method_detail() would search AR model,
14
+ # and return details of real has_many association 'product_properties'.
15
+ #
16
+ # This real association can then be used to send spreadsheet row data to the AR object.
17
+ #
18
+ require 'method_detail'
19
+
20
+ class MethodMapper
21
+
22
+ attr_accessor :header_row, :headers
23
+ attr_accessor :methods
24
+
25
+ @@has_many = Hash.new
26
+ @@belongs_to = Hash.new
27
+ @@assignments = Hash.new
28
+ @@column_types = Hash.new
29
+
30
+ def initialize
31
+ @methods = []
32
+ @headers = []
33
+ end
34
+
35
+ # Build complete picture of the methods whose names listed in method_list
36
+ # Handles method names as defined by a user or in file headers where names may
37
+ # not be exactly as required e.g handles capitalisation, white space, _ etc
38
+
39
+ def find_method_details( klass, method_list )
40
+ @methods = method_list.collect { |x| MethodMapper::find_method_detail( klass, x ) }
41
+ end
42
+
43
+ def method_names()
44
+ @methods.collect( &:name )
45
+ end
46
+
47
+ def check_mandatory( mandatory_list )
48
+ method_list = method_names()
49
+
50
+ mandatory_list.each { |x| raise "Mandatory column missing - need a '#{x}' column" unless(method_list.index(x)) }
51
+ end
52
+
53
+ # Create picture of the operators for assignment available on an AR model,
54
+ # including via associations (which provide both << and = )
55
+ #
56
+ def self.find_operators(klass, options = {} )
57
+
58
+ if( options[:reload] || @@has_many[klass].nil? )
59
+ @@has_many[klass] = klass.reflect_on_all_associations(:has_many).map { |i| i.name.to_s }
60
+ klass.reflect_on_all_associations(:has_and_belongs_to_many).inject(@@has_many[klass]) { |x,i| x << i.name.to_s }
61
+ end
62
+
63
+ # puts "DEBUG: Has Many Associations:", @@has_many[klass].inspect
64
+
65
+ if( options[:reload] || @@belongs_to[klass].nil? )
66
+ @@belongs_to[klass] = klass.reflect_on_all_associations(:belongs_to).map { |i| i.name.to_s }
67
+ end
68
+
69
+ # puts "DEBUG: Belongs To Associations:", @@belongs_to[klass].inspect
70
+
71
+ if( options[:reload] || @@assignments[klass].nil? )
72
+ @@assignments[klass] = (klass.column_names + klass.instance_methods.grep(/=/).map{|i| i.gsub(/=/, '')})
73
+ @@assignments[klass] = @@assignments[klass] - @@has_many[klass] if(@@has_many[klass])
74
+ @@assignments[klass] = @@assignments[klass] - @@belongs_to[klass] if(@@belongs_to[klass])
75
+
76
+ @@assignments[klass].uniq!
77
+
78
+ @@assignments[klass].each do |assign|
79
+ found = klass.columns.find{ |col| col.name == assign }
80
+ @@column_types[column_key(klass, assign)] = found if found
81
+ end
82
+ end
83
+ end
84
+
85
+ # Find the proper format of name, appropriate call + column type for a given name.
86
+ # e.g Given users entry in spread sheet check for pluralization, missing underscores etc
87
+ #
88
+ # If not nil returned method can be used directly in for example klass.new.send( call, .... )
89
+ #
90
+ def self.find_method_detail( klass, name )
91
+ true_name, assign, belongs_to, has_many = nil, nil, nil, nil
92
+
93
+ # TODO - check out regexp to do this work better plus Inflections ??
94
+ [
95
+ name,
96
+ name.gsub(' ', '_'),
97
+ name.gsub(' ', ''),
98
+ name.gsub(' ', '_').downcase,
99
+ name.gsub(' ', '').downcase,
100
+ name.gsub(' ', '_').underscore
101
+
102
+ ].each do |n|
103
+ has_many = (@@has_many[klass] && @@has_many[klass].include?(n)) ? n : nil
104
+ belongs_to = (@@belongs_to[klass] && @@belongs_to[klass].include?(n)) ? n : nil
105
+ assign = (@@assignments[klass] && @@assignments[klass].include?(n))? n + '=' : nil
106
+
107
+ if(assign || has_many || belongs_to)
108
+ true_name = n
109
+ break
110
+ end
111
+ end
112
+
113
+ return MethodDetail.new(klass, true_name, assign, belongs_to, has_many, @@column_types[column_key(klass, true_name)])
114
+ end
115
+
116
+ def self.clear
117
+ @@has_many.clear
118
+ @@assignments.clear
119
+ @@column_types.clear
120
+ end
121
+
122
+ def self.column_key(klass, column)
123
+ "#{klass.name}:#{column}"
124
+ end
125
+
126
+ def self.has_many
127
+ @@has_many
128
+ end
129
+ def self.assignments
130
+ @@assignments
131
+ end
132
+ def self.column_types
133
+ @@column_types
134
+ end
135
+
136
+ def self.has_many_for(klass)
137
+ @@has_many[klass]
138
+ end
139
+ def self.assignments_for(klass)
140
+ @@assignments[klass]
141
+ end
142
+
143
+ def self.column_type_for(klass, column)
144
+ @@column_types[column_key(klass, column)]
145
+ end
146
+
147
+
148
+ def find_or_new( klass, condition_hash = {} )
149
+ @records[klass] = klass.find(:all, :conditions => condition_hash)
150
+ if @records[klass].any?
151
+ return @records[klass].first
152
+ else
153
+ return klass.new
154
+ end
155
+ end
156
+
157
+ end
@@ -0,0 +1,28 @@
1
+ # Copyright:: (c) Autotelik Media Ltd 2011
2
+ # Author :: Tom Statter
3
+ # Date :: Jan 2011
4
+ # License:: MIT
5
+ #
6
+ # Details:: Extract the headings from a user supplied CSV file, and map heading names
7
+ # to the attributes and/or assocaiitons of an AR Model defined by supplied klass.
8
+ #
9
+ require 'method_mapper'
10
+
11
+ class MethodMapperCsv < MethodMapper
12
+
13
+ # Read the headers from CSV file and map to ActiveRecord members/associations
14
+
15
+ def initialize( file_name, klass, sheet_number = 0 )
16
+ super
17
+
18
+ File.open(file_name) do
19
+ @headers = @header_row.split(/,/)
20
+ end
21
+
22
+ # Gather list of all possible 'setter' methods on AR class (instance variables and associations)
23
+ self.find_operators( klass )
24
+
25
+ # Convert the list of headers into suitable calls on the Active Record class
26
+ find_method_details( klass, @headers )
27
+ end
28
+ end
@@ -0,0 +1,70 @@
1
+ # Author:: Tom Statter
2
+ # License:: MIT ?
3
+ #
4
+ # NOTES ON INVESTIGATING OLE METHODS in irb
5
+ #
6
+ # visible = @word_app.ole_method_help( 'Visible' ) # Get a Method Object
7
+
8
+ # log( visible.return_type_detail.to_s ) # => ["BOOL"]
9
+ # log( visible.invoke_kind.to_s ) # => "PROPERTYGET"
10
+ # log( visible.params.to_s ) # => []
11
+
12
+ # @fc.ole_method_help( 'Report' ).params[1].ole_type_detail
13
+ #
14
+ # prefs = @word_app.Preferences.Strings.ole_method_help( 'Set' ).params
15
+ # => [index, newVal]
16
+ #
17
+ # WORD_OLE_CONST.constants
18
+ #
19
+ # WORD_OLE_CONST.constants.sort.grep /CR/
20
+ # => ["ClHideCRLF", "LesCR", "LesCRLF"]
21
+ #
22
+ # WORD_OLE_CONST.const_get( 'LesCR' ) or WORD_OLE_CONST::LesCR
23
+ # => 1
24
+ require 'win32ole'
25
+
26
+ # Module for constants to be loaded int
27
+
28
+ module WORD_OLE_CONST
29
+ end
30
+
31
+ class Word
32
+
33
+ attr_reader :wd, :doc
34
+
35
+ def initialize( visible )
36
+ @wd = WIN32OLE.new('Word.Application')
37
+
38
+ WIN32OLE.const_load(@wd, WORD_OLE_CONST) if WORD_OLE_CONST.constants.empty?
39
+
40
+ @wd.Visible = visible
41
+ end
42
+
43
+ def open(file)
44
+ @doc = @wd.Documents.Open(file)
45
+ @doc
46
+ end
47
+
48
+ def save()
49
+ @doc.Save()
50
+ @doc
51
+ end
52
+
53
+ # Format : From WORD_OLE_CONST e.g WORD_OLE_CONST::WdFormatHTML
54
+ #
55
+ def save_as(name, format)
56
+ @doc.SaveAs(name, format)
57
+ return @doc
58
+ end
59
+
60
+ # WdFormatFilteredHTML
61
+ # WdFormatHTML
62
+ def save_as_html(name)
63
+ @doc.SaveAs(name, WORD_OLE_CONST::WdFormatHTML)
64
+ return @doc
65
+ end
66
+
67
+ def quit
68
+ @wd.quit()
69
+ end
70
+ end
Binary file