lib/roo/openoffice.rb in roo-0.4.1 vs lib/roo/openoffice.rb in roo-0.5.0
- old
+ new
@@ -3,21 +3,28 @@
require 'rexml/document'
require 'fileutils'
require 'zip/zipfilesystem'
require 'date'
require 'llip'
+require 'base64'
#require 'lib/roo/spreadsheetparser'
class Openoffice
@@nr = 0
- def initialize(filename)
+ # initialization and opening of a spreasheet file
+ # file will be created if 'create' is true
+ # and the file does not exist
+ def initialize(filename, create = false)
if filename[-4..-1] != ".ods"
warn "are you sure, this is an openoffice file?"
end
+ if create and ! File.exists?(filename)
+ self.create_openoffice(filename)
+ end
@cells_read = false
@filename = filename
@tmpdir = "oo_"+$$.to_s
unless File.exists?(@tmpdir)
FileUtils::mkdir(@tmpdir)
@@ -29,18 +36,33 @@
@doc = REXML::Document.new file
file.close
@cell = Hash.new
@cell_type = Hash.new
@formula = Hash.new
-# if ENV["roo_local"] != "thomas-p"
+ if ENV["roo_local"] != "thomas-p"
FileUtils::rm_r(@tmpdir)
-# end
- @default_sheet = nil
+ end
+ @default_sheet = nil
@first_column = @last_column = nil
@first_row = @last_row = nil
+ trap('INT') {
+ FileUtils::rm_r(@tmpdir)
+ }
end
+ # creates a new empty openoffice-spreadsheet file
+ def create_openoffice(filename)
+ #TODO: a better way for creating the file contents
+ # now you have to call mkbase64...rb to create an include file with all
+ # the empty files in an openoffice zip-file
+ load 'base64include.rb'
+ # puts @@empty_spreadsheet
+ f = File.open(filename,'w')
+ f.print(Base64.decode64(@@empty_spreadsheet))
+ f.close
+ end
+
# reopens and read a spreadsheet document
if false
def reload
@cells_read = false
@tmpdir = "oo_"+$$.to_s
@@ -73,11 +95,11 @@
# (1,1), (1,'A'), ('A',1), ('a',1) all refers to the
# cell at first line, first row
def cell(row,col)
read_cells unless @cells_read
row,col = normalize(row,col)
- if celltype(row,col) == "date"
+ if celltype(row,col) == :date
yyyy,mm,dd = @cell["#{row},#{col}"].split('-')
return Date.new(yyyy.to_i,mm.to_i,dd.to_i)
end
@cell["#{row},#{col}"]
end
@@ -102,10 +124,11 @@
end
# set a cell to a certain value
# (this will not be saved back to the spreadsheet file!)
def set(row,col,value)
+ read_cells unless @cells_read
row,col = normalize(row,col)
set_value(row,col,value)
if value.class == Fixnum
set_type(row,col,:float)
elsif value.class == String
@@ -161,10 +184,12 @@
@cell = Hash.new
@cell_type = Hash.new
@formula = Hash.new
end
+ alias set_default_sheet default_sheet=
+
# version of the openoffice document
# at 2007 this is always "1.0"
def officeversion
read_cells(:ignore_default_sheet => true) unless @cells_read
@officeversion
@@ -282,20 +307,18 @@
# true if cell is empty
def empty?(row, col)
read_cells unless @cells_read
return true unless cell(row, col)
- return true if celltype(row, col) == "string" && cell(row, col).empty?
+ return true if celltype(row, col) == :string && cell(row, col).empty?
false
end
-=begin
# save spreadsheet
def save
42
end
-=end
# evaluate the formula at this cell
# experimental: DO NOT USE THIS!
def solve(row,col)
parser = SpreadsheetParser.new
@@ -394,36 +417,36 @@
if skip
if v == nil
x += (skip.to_i - 1)
else
0.upto(skip.to_i-1) do |i|
- @cell_type["#{y},#{x+i}"] = vt
+ @cell_type["#{y},#{x+i}"] = Openoffice.oo_type_2_roo_type(vt)
@formula["#{y},#{x+i}"] = formula if formula
- if @cell_type["#{y},#{x+i}"] == 'float'
+ if @cell_type["#{y},#{x+i}"] == :float
@cell["#{y},#{x+i}"] = v.to_f
- elsif @cell_type["#{y},#{x+i}"] == 'string'
+ elsif @cell_type["#{y},#{x+i}"] == :string
@cell["#{y},#{x+i}"] = v
- elsif @cell_type["#{y},#{x+i}"] == 'date'
+ elsif @cell_type["#{y},#{x+i}"] == :date
@cell["#{y},#{x+i}"] = tr.attributes['date-value']
else
@cell["#{y},#{x+i}"] = v
end
end
x += 1
end
end # if skip
@formula["#{y},#{x}"] = formula if formula
- @cell_type["#{y},#{x}"] = vt
- if @cell_type["#{y},#{x}"] == 'float'
+ @cell_type["#{y},#{x}"] = Openoffice.oo_type_2_roo_type(vt)
+ if @cell_type["#{y},#{x}"] == :float
@cell["#{y},#{x}"] = v.to_f
- elsif @cell_type["#{y},#{x}"] == 'string'
+ elsif @cell_type["#{y},#{x}"] == :string
tr.each_element do |str|
if str.name == 'p'
@cell["#{y},#{x}"] = str.text
end
end
- elsif @cell_type["#{y},#{x}"] == 'date'
+ elsif @cell_type["#{y},#{x}"] == :date
@cell["#{y},#{x}"] = tr.attributes['date-value']
else
@cell["#{y},#{x}"] = v
end
x += 1
@@ -443,10 +466,11 @@
end
@cells_read = true
end
def process_zipfile(zip, path='')
+ #p path
if zip.file.file? path
if path == "content.xml"
open(@tmpdir+'/'+@file_nr.to_s+'_roo_content.xml','w') {|f|
f << zip.read(path)
}
@@ -474,11 +498,11 @@
if col.class == Fixnum
# ('A',1):
# ('B', 5) -> (5, 2)
row, col = col, row
else
- raise FormatError
+ raise ArgumentError
end
end
if col.class == String
col = Openoffice.letter_to_number(col)
end
@@ -515,6 +539,16 @@
def set_type(row,col,type)
@cell_type["#{row},#{col}"] = type
end
+ A_ROO_TYPE = {
+ "float" => :float,
+ "string" => :string,
+ "date" => :date,
+ "percentage" => :percentage,
+ }
+
+ def Openoffice.oo_type_2_roo_type(ootype)
+ return A_ROO_TYPE[ootype]
+ end
end # class