Class: DataShift::ExcelExporter

Inherits:
ExporterBase show all
Includes:
ColumnPacker, ExcelBase, Logging
Defined in:
lib/datashift/exporters/excel_exporter.rb

Instance Attribute Summary collapse

Attributes included from ExcelBase

#excel, #sheet

Attributes included from Delimiters

#attribute_list_end, #attribute_list_start, #csv_delimiter, #key_value_sep, #text_delim

Attributes inherited from ExporterBase

#configuration, #file_name

Instance Method Summary collapse

Methods included from ExcelBase

#ar_to_xls, #ar_to_xls_cell, #ar_to_xls_row, max_columns, #open_excel, #parse_headers, #sanitize_sheet_name, #start_excel

Methods included from Logging

#logdir, #logdir=, #logger, #verbose

Methods included from ColumnPacker

#escape_for_csv, #escape_text_delim, #record_to_column, #record_to_csv

Methods included from Delimiters

#column_delim, #column_delim=, #eol, #multi_assoc_delim, #multi_assoc_delim=, #multi_facet_delim, #multi_value_delim, #multi_value_delim=, #name_value_delim, #name_value_delim=, #setmulti_facet_delim

Constructor Details

#initializeExcelExporter

Returns a new instance of ExcelExporter.



23
24
25
# File 'lib/datashift/exporters/excel_exporter.rb', line 23

def initialize
  super
end

Instance Attribute Details

#data_flow_schemaObject

Optional, otherwise uses the standard collection of Model Methods for supplied klass



21
22
23
# File 'lib/datashift/exporters/excel_exporter.rb', line 21

def data_flow_schema
  @data_flow_schema
end

Instance Method Details

#export(file, export_records, options = {}) ⇒ Object

Creates an Excel file from list of ActiveRecord objects. Supply the full path to write XLS file to, OR to access output as String, rather than writing to disc, pass StringIO e.g

file_contents = StringIO.new
exporter.export(file_contents, some_records)

Raises:

  • (ArgumentError)


43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/datashift/exporters/excel_exporter.rb', line 43

def export(file, export_records, options = {})
  records = [*export_records]

  if records.blank?
    logger.warn('Excel Export - No objects supplied for export - no file written')
    return
  end

  first = records[0]

  raise(ArgumentError, 'Please supply set of ActiveRecord objects to export') unless exportable?(first)

  klass = first.class

  excel = start_excel(klass, options)

  prepare_data_flow_schema(klass) unless @data_flow_schema && @data_flow_schema.nodes.klass == klass

  headers = export_headers(klass)

  logger.info("Exporting #{records.size} #{klass} to Excel")

  excel.ar_to_xls(records, headers: headers, data_flow_schema: data_flow_schema)

  excel.auto_fit_rows.auto_fit_columns

  logger.info("Writing Excel to file [#{file}]")

  excel.write( file )

  excel
end

#export_headers(klass) ⇒ Object



76
77
78
79
80
81
82
83
84
# File 'lib/datashift/exporters/excel_exporter.rb', line 76

def export_headers(klass)
  headers = if(data_flow_schema)
              data_flow_schema.headers
            else
              Headers.klass_to_headers(klass)
            end
  excel.set_headers( headers )
  headers
end

#export_with_associations(file_name, klass, records, options = {}) ⇒ Object

Create an Excel file from list of ActiveRecord objects, includes relationships

The Associations/relationships to include are driven by Configuration Options

See - lib/exporters/configuration.rb


99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/datashift/exporters/excel_exporter.rb', line 99

def export_with_associations(file_name, klass, records, options = {})

  state = DataShift::Configuration.call.with

  DataShift::Configuration.call.with = :all

  @file_name = file_name

  excel = start_excel(klass, options)

  logger.info("Processing [#{records.size}] #{klass} records to Excel")

  # TODO: - prepare_data_flow_schema here in middle of export, plus reaching through nodes to klass, does not smell right
  prepare_data_flow_schema(klass) unless @data_flow_schema && @data_flow_schema.nodes.klass == klass

  export_headers(klass)

  nodes = data_flow_schema.nodes

  row = 1

  records.each do |obj|
    column = 0

    nodes.each do |node|

      logger.info("Send to Excel: #{node.inspect}")

      model_method = node.model_method

      logger.info("Send to Excel: #{model_method.pp}")

      begin
        # pack association instances into single column
        if model_method.association_type?
          logger.info("Processing #{model_method.inspect} associations")
          excel[row, column] = record_to_column( obj.send( model_method.operator ), configuration.json )
        else
          excel[row, column] = obj.send( model_method.operator )
        end
      rescue StandardError => x
        logger.error("Failed to write #{model_method.inspect} to Excel")
        logger.error(x.inspect)
      end

      column += 1
    end

    row += 1
  end

  logger.info("Writing Excel to file [#{file_name}]")
  excel.write( file_name )
ensure
  DataShift::Configuration.call.with = state

end

#exportable?(record) ⇒ Boolean

Returns:

  • (Boolean)


27
28
29
30
31
32
33
34
# File 'lib/datashift/exporters/excel_exporter.rb', line 27

def exportable?(record)

  return true if record.is_a?(ActiveRecord::Base)

  return true if Module.const_defined?(:Mongoid) && record.is_a?(Mongoid::Document)

  false
end

#prepare_data_flow_schema(klass) ⇒ Object



86
87
88
89
90
91
# File 'lib/datashift/exporters/excel_exporter.rb', line 86

def prepare_data_flow_schema(klass)
  @data_flow_schema = DataShift::DataFlowSchema.new
  @data_flow_schema.prepare_from_klass( klass )

  data_flow_schema
end