lib/roo/excel.rb in roo-0.8.0 vs lib/roo/excel.rb in roo-0.8.1
- old
+ new
@@ -2,22 +2,22 @@
gem 'parseexcel', '>= 0.5.2'
require 'parseexcel'
CHARGUESS=false
require 'charguess' if CHARGUESS
-module Spreadsheet
+module Spreadsheet # :nodoc
module ParseExcel
class Worksheet
include Enumerable
attr_reader :min_row, :max_row, :min_col, :max_col
end
end
end
+# Class for handling Excel-Spreadsheets
+class Excel < GenericSpreadsheet
-class Excel < GenericSpreadsheet #Openoffice
-
EXCEL_NO_FORMULAS = 'formulas are not supported for excel spreadsheets'
# Creates a new Excel spreadsheet object.
# Parameter packed: :zip - File is a zip-file
def initialize(filename, packed = nil)
@@ -49,10 +49,11 @@
@first_column = Hash.new
@last_column = Hash.new
@cells_read = Hash.new
end
+ # returns an array of sheet names in the spreadsheet
def sheets
result = []
0.upto(@workbook.sheet_count - 1) do |i|
# TODO: is there a better way to do conversion?
if CHARGUESS
@@ -62,13 +63,21 @@
result << Iconv.new('utf-8',encoding).iconv(
@workbook.worksheet(i).name
)
else
- result << Iconv.new('utf-8','unicode').iconv(
- @workbook.worksheet(i).name
- )
+ result << platform_specific_iconv(@workbook.worksheet(i).name)
+ #case RUBY_PLATFORM.downcase
+ #when /darwin/
+ # result << Iconv.new('utf-8','utf-8').iconv(
+ # @workbook.worksheet(i).name
+ # )
+ #else
+ # result << Iconv.new('utf-8','unicode').iconv(
+ # @workbook.worksheet(i).name
+ # )
+ #end # case
end
end
return result
end
@@ -103,11 +112,11 @@
return nil unless cell
case cell.type
when :numeric then return cell.to_f
when :text then return cell.to_s('utf-8')
when :date then return cell.date
- else
+ else
return nil # cell.to_s('utf-8')
end
end
line += 1
}
@@ -126,17 +135,17 @@
if line == row
return nil unless row_par
cell = row_par.at(col-1)
return nil unless cell
case cell.type
- when :numeric
+ when :numeric
return :float
- when :text
+ when :text
return :string
- when :date
+ when :date
return :date
- else
+ else
return cell.type.to_sym
end
end
line += 1
}
@@ -146,11 +155,11 @@
# row numbers are 1,2,3,... like in the spreadsheet
def row(rownumber,sheet=nil)
sheet = @default_sheet unless sheet
default_sheet_check
worksheet = @workbook.worksheet(sheet_no(sheet))
- #therow = worksheet.row(rownumber-1)
+ #therow = worksheet.row(rownumber-1)
result = []
worksheet.row(rownumber-1).each {|cell|
if cell
case cell.type
when :numeric then result << cell.to_i
@@ -193,11 +202,11 @@
result << nil
end
else
result << nil
end
- }
+ }
result
end
# returns the first non empty column
def first_column(sheet=nil)
@@ -228,21 +237,21 @@
sheet = @default_sheet unless sheet
return @last_row[sheet] if @last_row[sheet]
fr, lr, fc, lc = get_firsts_lasts(sheet)
lr
end
-
+
# returns NO formula in excel spreadsheets
def formula(row,col,sheet=nil)
raise EXCEL_NO_FORMULAS
end
# raises an exception because formulas are not supported for excel files
def formula?(row,col,sheet=nil)
raise EXCEL_NO_FORMULAS
end
-
+
# returns NO formulas in excel spreadsheets
def formulas(sheet=nil)
raise EXCEL_NO_FORMULAS
end
@@ -255,23 +264,41 @@
# determine the first and last boundaries
def get_firsts_lasts(sheet=nil)
sheet = @default_sheet unless sheet
fr = fc = 999_999
- lr = lc = -999_999
+ lr = lc = -999_999
worksheet = @workbook.worksheet(sheet_no(sheet))
- fr = worksheet.min_row + 1
- lr = worksheet.max_row + 1
- fc = worksheet.min_col + 1
- lc = worksheet.max_col + 1
- # 2007-11-05 BEGIN
- # parsexcel liefert (mir unverstaendlich) eine Zeile als letzte Zeile
- # zurueck, die aber leer ist. Deshalb Korrekturfunktion, die wirklich
- # die letzte nicht leere Zeile liefert.
- while empty_row? row(lr,sheet)
- lr -= 1
+ unless worksheet.min_row
+ fr = nil
+ else
+ fr = worksheet.min_row + 1
end
+ unless worksheet.max_row
+ lr = nil
+ else
+ lr = worksheet.max_row + 1
+ end
+ unless worksheet.min_col
+ fc = nil
+ else
+ fc = worksheet.min_col + 1
+ end
+ unless worksheet.max_col
+ lc = nil
+ else
+ lc = worksheet.max_col + 1
+ end
+ if lr
+ # 2007-11-05 BEGIN
+ # parsexcel liefert (mir unverstaendlich) eine Zeile als letzte Zeile
+ # zurueck, die aber leer ist. Deshalb Korrekturfunktion, die wirklich
+ # die letzte nicht leere Zeile liefert.
+ while empty_row? row(lr,sheet)
+ lr -= 1
+ end
+ end
# 2007-11-05 END
@first_row[sheet] = fr
@last_row[sheet] = lr
@first_column[sheet] = fc
@last_column[sheet] = lc
@@ -281,13 +308,15 @@
# converts name of a sheet to index (0,1,2,..)
def sheet_no(name)
return name-1 if name.kind_of?(Fixnum)
0.upto(@workbook.sheet_count - 1) do |i|
# TODO: is there a better way to do conversion?
- return i if name == Iconv.new('utf-8','unicode').iconv(
- @workbook.worksheet(i).name
- )
+ return i if name == platform_specific_iconv(
+ @workbook.worksheet(i).name)
+#Iconv.new('utf-8','unicode').iconv(
+# @workbook.worksheet(i).name
+# )
end
raise StandardError, "sheet '#{name}' not found"
end
# writes csv output to stdout or file
@@ -302,25 +331,25 @@
cell = row_par.at(col-1)
unless cell
empty = true
else
case cell.type
- when :numeric
+ when :numeric
onecelltype = :float
onecell = cell.to_f
- when :text
+ when :text
onecelltype = :string
onecell = cell.to_s('utf-8')
- when :date
+ when :date
onecelltype = :date
onecell = cell.date
else
onecelltype = nil
- onecell = nil
+ onecell = nil
end
- end
- file.print one_cell_output(onecelltype,onecell,empty)
+ end
+ file.print one_cell_output(onecelltype,onecell,empty)
}
file.print("\n")
}
end
@@ -329,10 +358,22 @@
row.each {|elem|
if elem != ''
#if elem.class == String and elem.size > 0
content = true
end
- }
+ }
! content
end
+
+def platform_specific_iconv(value)
+ case RUBY_PLATFORM.downcase
+ when /darwin/
+ result = Iconv.new('utf-8','utf-8').iconv(value)
+ when /mswin32/
+ result = Iconv.new('utf-8','iso-8859-1').iconv(value)
+ else
+ result = Iconv.new('utf-8','unicode').iconv(value)
+ end # case
+ result
+end
end