ar_loader 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -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