Skip to content

Commit

Permalink
common excel api. more generate options, specs
Browse files Browse the repository at this point in the history
  • Loading branch information
Thomas Statter committed Sep 25, 2012
1 parent 37757a4 commit 62583d9
Show file tree
Hide file tree
Showing 23 changed files with 434 additions and 421 deletions.
62 changes: 62 additions & 0 deletions lib/applications/apache_poi_extensions.rb
@@ -0,0 +1,62 @@
# Copyright:: Autotelik Media Ltd
# Author :: Tom Statter
# Date :: July 2010
# License::
#
#
if(DataShift::Guards::jruby?)

require 'java'
require "poi-3.7-20101029.jar"

# Extend the Poi classes with some syntactic sugar

class Java::OrgApachePoiHssfUsermodel::HSSFSheet
def name()
getSheetName
end

def num_rows
getPhysicalNumberOfRows
end

end

class Java::OrgApachePoiHssfUsermodel::HSSFRow

include RubyPoiTranslations

include Enumerable

def []( column)
cell_value( get_or_create_cell( column ) )
end

def []=( column, value )
get_or_create_cell(column, value).setCellValue((value.to_s || ""))
end

def get_or_create_cell( column, value = nil )
if(value)
java_send(:getCell, [Java::int], column) || createCell(column, poi_cell_type(value))
else
java_send(:getCell, [Java::int], column) || java_send(:createCell, [Java::int], column)
end
end

def idx
getRowNum()
end

# Iterate over each column in the row and yield on the cell
def each(&block)
cellIterator.each {|c| yield cell_value(c) }
end

# TODO
# for min, max and sort from enumerable need <=>
# def <=> end

end

end
65 changes: 65 additions & 0 deletions lib/applications/excel_base.rb
@@ -0,0 +1,65 @@
# To change this template, choose Tools | Templates
# and open the template in the editor.

module ExcelBase

def sanitize_sheet_name( name )
name.gsub(/[\[\]:\*\/\\\?]/, '')
end

# Helpers for dealing with Active Record models and collections

def ar_to_headers( records )
return if( !records.first.is_a?(ActiveRecord::Base) || records.empty?)

headers = records.first.class.columns.collect( &:name )
set_headers( headers )
end


# Pass a set of AR records
def ar_to_xls(records, options = {})
return if( ! records.first.is_a?(ActiveRecord::Base) || records.empty?)

row_index =
if(options[:no_headers])
0
else
ar_to_headers( records )
1
end

records.each do |record|
create_row(row_index)

ar_to_xls_row(0, record)

row_index += 1
end
end


# Save data from an AR record to the current row, based on the record's columns [c1,c2,c3]
# Returns the number of the final column written to
def ar_to_xls_row(row, start_column, record)
return unless( record.is_a?(ActiveRecord::Base))

column = start_column
record.class.columns.each do |connection_column|
ar_to_xls_cell(row, column, record, connection_column)
column += 1
end
column
end

def ar_to_xls_cell(row, column, record, connection_column)
begin
datum = record.send(connection_column.name)

self[row, column] = datum
rescue => e
puts "Failed to export #{datum} from #{connection_column.inspect} to column #{column}"
puts e, e.backtrace
end
end
end
18 changes: 11 additions & 7 deletions lib/applications/jexcel_file.rb
Expand Up @@ -13,12 +13,17 @@

require 'java'

require 'jexcel'
require 'excel_base'
require 'ruby_poi_translations'

class JExcelFile

include JExcel
extend JExcel
include ExcelBase

include RubyPoiTranslations
extend RubyPoiTranslations

include Enumerable

include_class 'org.apache.poi.hssf.util.HSSFColor'
java_import 'org.apache.poi.poifs.filesystem.POIFSFileSystem'
Expand All @@ -29,9 +34,6 @@ class JExcelFile
java_import 'org.apache.poi.hssf.usermodel.HSSFDataFormat'
java_import 'org.apache.poi.hssf.usermodel.HSSFClientAnchor'
java_import 'org.apache.poi.hssf.usermodel.HSSFRichTextString'


include Enumerable

attr_accessor :workbook, :row, :date_style
attr_reader :sheet, :current_sheet_index
Expand Down Expand Up @@ -203,16 +205,18 @@ def to_s
private

def create_sheet_and_set_styles( sheet_name )
@sheet = @workbook.createSheet(sheet_name)
@sheet = @workbook.createSheet( sanitize_sheet_name(sheet_name) )

@patriarchs.store(sheet_name, @sheet.createDrawingPatriarch())

@date_style = @workbook.createCellStyle
@date_style.setDataFormat( JExcelFile::date_format )
@sheet
end

end

require 'jexcel_file_extensions'
require 'apache_poi_extensions'

end
66 changes: 0 additions & 66 deletions lib/applications/jexcel_file_extensions.rb
Expand Up @@ -116,72 +116,6 @@ def create_freeze_pane(row=1, column=0)
@sheet.createFreezePane(row, column)
end

# TODO - Move into an ActiveRecord helper module of it's own
def ar_to_headers( records )
return if( !records.first.is_a?(ActiveRecord::Base) || records.empty?)

headers = records.first.class.columns.collect( &:name )
set_headers( headers )
end


# Pass a set of AR records
def ar_to_xls(records, options = {})
return if( ! records.first.is_a?(ActiveRecord::Base) || records.empty?)

row_index =
if(options[:no_headers])
0
else
ar_to_headers( records )
1
end

records.each do |record|
create_row(row_index)

ar_to_xls_row(0, record)

row_index += 1
end
end

# Save data from an AR record to the current row, based on the record's columns [c1,c2,c3]
# Returns the number of the final column written to
def ar_to_xls_row(start_column, record)
return unless( record.is_a?(ActiveRecord::Base))

column = start_column
record.class.columns.each do |connection_column|
ar_to_xls_cell(column, record, connection_column)
column += 1
end
column
end

def ar_to_xls_cell(column, record, connection_column)
begin
datum = record.send(connection_column.name)

@row[column] = datum

#if(connection_column.sql_type =~ /date/)
# @row[column] = datum.to_s

# elsif(connection_column.type == :boolean || connection_column.sql_type =~ /tinyint/)
# @row.createCell(column, HSSFCell::CELL_TYPE_BOOLEAN).setCellValue(datum)

# elsif(connection_column.sql_type =~ /int/)
# @row.createCell(column, HSSFCell::CELL_TYPE_NUMERIC).setCellValue(datum.to_i)
## else
# @row.createCell(column, HSSFCell::CELL_TYPE_STRING).setCellValue( datum.to_s )
# end

rescue => e
puts "Failed to export #{datum} from #{connection_column.inspect} to column #{column}"
puts e, e.backtrace
end
end

# Use execute to run sql query provided
# and write to a csv file (path required)
Expand Down
Expand Up @@ -11,7 +11,7 @@
require 'benchmark'
require "poi-3.7-20101029.jar"

module JExcel
module RubyPoiTranslations

java_import 'org.apache.poi.poifs.filesystem.POIFSFileSystem'

Expand Down Expand Up @@ -60,39 +60,5 @@ def poi_cell_type(data)
# HSSFCell::CELL_TYPE_FORMULA
end
end

# Extend the Poi classes with some syntactic sugar

class Java::OrgApachePoiHssfUsermodel::HSSFSheet
def name()
getSheetName
end
end

class Java::OrgApachePoiHssfUsermodel::HSSFRow

include JExcel

def []( column)
cell_value( get_or_create_cell( column ) )
end

def []=( column, value )
get_or_create_cell(column, value).setCellValue((value.to_s || ""))
end

def get_or_create_cell( column, value = nil )
if(value)
java_send(:getCell, [Java::int], column) || createCell(column, poi_cell_type(value))
else
java_send(:getCell, [Java::int], column) || java_send(:createCell, [Java::int], column)
end
end

def idx
getRowNum()
end

end

end
9 changes: 6 additions & 3 deletions lib/applications/spreadsheet_extensions.rb
Expand Up @@ -8,9 +8,12 @@
#
# ... to do extract into separate module with pure ruby that works with both POI and Spreadsheet


class Spreadsheet::Worksheet
require 'excel_base'

class Spreadsheet::Worksheet

include ExcelBase

# Convert array into a header row
def set_headers(headers, apply_style = nil)
return if headers.empty?
Expand All @@ -23,6 +26,6 @@ def set_headers(headers, apply_style = nil)
def num_rows
rows.size
end

end

4 changes: 4 additions & 0 deletions lib/datashift/method_details_manager.rb
Expand Up @@ -50,9 +50,13 @@ def get_list( type )
@method_details_list[type.to_sym] || []
end

alias_method(:get_list_of_method_details, :get_list)

def get_operators( op_type )
get_list(op_type).collect { |md| md.operator }
end

alias_method(:get_list_of_operators, :get_list)

def all_available_operators
method_details_list.values.flatten.collect(&:operator)
Expand Down
2 changes: 2 additions & 0 deletions lib/exporters/csv_exporter.rb
Expand Up @@ -125,6 +125,8 @@ def export_with_associations(klass, records, options = {})
if(assoc_object.is_a?ActiveRecord::Base)
column_text = record_to_column(assoc_object) # belongs_to or has_one

# TODO -ColumnPacker class shared between excel/csv

csv << "#{@text_delim}#{column_text}#{@text_delim}" << Delimiters::csv_delim
#csv << record_to_csv(r)

Expand Down
18 changes: 8 additions & 10 deletions lib/exporters/excel_exporter.rb
Expand Up @@ -39,11 +39,8 @@ def export(records, options = {})
excel.ar_to_headers(records)

excel.ar_to_xls(records)


# => :methods => List of methods to additionally export on each record

excel.save( filename() )

excel.write( filename() )
end

# Create an Excel file from list of ActiveRecord objects
Expand Down Expand Up @@ -91,14 +88,15 @@ def export_with_associations(klass, items, options = {})

excel.set_headers( headers )

row_index = 1
row = 1
column = 0

items.each do |datum|
excel.create_row(row_index += 1)
excel.ar_to_xls_row(1, datum)
items.each do |row_of_data|
excel.ar_to_xls_row(row, column, row_of_data)
row += 1
end

excel.save( filename() )
excel.write( filename() )
end
end
end # ExcelGenerator
Expand Down

0 comments on commit 62583d9

Please sign in to comment.