diff options
Diffstat (limited to 'lib/roo/formatters')
| -rw-r--r-- | lib/roo/formatters/base.rb | 15 | ||||
| -rw-r--r-- | lib/roo/formatters/csv.rb | 84 | ||||
| -rw-r--r-- | lib/roo/formatters/matrix.rb | 23 | ||||
| -rw-r--r-- | lib/roo/formatters/xml.rb | 31 | ||||
| -rw-r--r-- | lib/roo/formatters/yaml.rb | 40 |
5 files changed, 193 insertions, 0 deletions
diff --git a/lib/roo/formatters/base.rb b/lib/roo/formatters/base.rb new file mode 100644 index 0000000..2d32d6d --- /dev/null +++ b/lib/roo/formatters/base.rb @@ -0,0 +1,15 @@ +module Roo + module Formatters + module Base + # converts an integer value to a time string like '02:05:06' + def integer_to_timestring(content) + h = (content / 3600.0).floor + content -= h * 3600 + m = (content / 60.0).floor + content -= m * 60 + s = content + Kernel.format("%02d:%02d:%02d", h, m, s) + end + end + end +end diff --git a/lib/roo/formatters/csv.rb b/lib/roo/formatters/csv.rb new file mode 100644 index 0000000..3181f09 --- /dev/null +++ b/lib/roo/formatters/csv.rb @@ -0,0 +1,84 @@ +module Roo + module Formatters + module CSV + def to_csv(filename = nil, separator = ",", sheet = default_sheet) + if filename + File.open(filename, "w") do |file| + write_csv_content(file, sheet, separator) + end + true + else + sio = ::StringIO.new + write_csv_content(sio, sheet, separator) + sio.rewind + sio.read + end + end + + private + + # Write all cells to the csv file. File can be a filename or nil. If the + # file argument is nil the output goes to STDOUT + def write_csv_content(file = nil, sheet = nil, separator = ",") + file ||= STDOUT + return unless first_row(sheet) # The sheet is empty + + 1.upto(last_row(sheet)) do |row| + 1.upto(last_column(sheet)) do |col| + # TODO: use CSV.generate_line + file.print(separator) if col > 1 + file.print cell_to_csv(row, col, sheet) + end + file.print("\n") + end + end + + # The content of a cell in the csv output + def cell_to_csv(row, col, sheet) + return "" if empty?(row, col, sheet) + + onecell = cell(row, col, sheet) + + case celltype(row, col, sheet) + when :string + %("#{onecell.gsub('"', '""')}") unless onecell.empty? + when :boolean + # TODO: this only works for excelx + onecell = self.sheet_for(sheet).cells[[row, col]].formatted_value + %("#{onecell.gsub('"', '""').downcase}") + when :float, :percentage + if onecell == onecell.to_i + onecell.to_i.to_s + else + onecell.to_s + end + when :formula + case onecell + when String + %("#{onecell.gsub('"', '""')}") unless onecell.empty? + when Integer + onecell.to_s + when Float + if onecell == onecell.to_i + onecell.to_i.to_s + else + onecell.to_s + end + when Date, DateTime, TrueClass, FalseClass + onecell.to_s + else + fail "unhandled onecell-class #{onecell.class}" + end + when :date, :datetime + onecell.to_s + when :time + integer_to_timestring(onecell) + when :link + %("#{onecell.url.gsub('"', '""')}") + else + fail "unhandled celltype #{celltype(row, col, sheet)}" + end || "" + end + end + end +end diff --git a/lib/roo/formatters/matrix.rb b/lib/roo/formatters/matrix.rb new file mode 100644 index 0000000..39c7381 --- /dev/null +++ b/lib/roo/formatters/matrix.rb @@ -0,0 +1,23 @@ +module Roo + module Formatters + module Matrix + # returns a matrix object from the whole sheet or a rectangular area of a sheet + def to_matrix(from_row = nil, from_column = nil, to_row = nil, to_column = nil, sheet = default_sheet) + require 'matrix' + + return ::Matrix.empty unless first_row + + from_row ||= first_row(sheet) + to_row ||= last_row(sheet) + from_column ||= first_column(sheet) + to_column ||= last_column(sheet) + + ::Matrix.rows(from_row.upto(to_row).map do |row| + from_column.upto(to_column).map do |col| + cell(row, col, sheet) + end + end) + end + end + end +end diff --git a/lib/roo/formatters/xml.rb b/lib/roo/formatters/xml.rb new file mode 100644 index 0000000..ebb8cde --- /dev/null +++ b/lib/roo/formatters/xml.rb @@ -0,0 +1,31 @@ +# returns an XML representation of all sheets of a spreadsheet file +module Roo + module Formatters + module XML + def to_xml + Nokogiri::XML::Builder.new do |xml| + xml.spreadsheet do + sheets.each do |sheet| + self.default_sheet = sheet + xml.sheet(name: sheet) do |x| + if first_row && last_row && first_column && last_column + # sonst gibt es Fehler bei leeren Blaettern + first_row.upto(last_row) do |row| + first_column.upto(last_column) do |col| + next if empty?(row, col) + + x.cell(cell(row, col), + row: row, + column: col, + type: celltype(row, col)) + end + end + end + end + end + end + end.to_xml + end + end + end +end diff --git a/lib/roo/formatters/yaml.rb b/lib/roo/formatters/yaml.rb new file mode 100644 index 0000000..69ef3ab --- /dev/null +++ b/lib/roo/formatters/yaml.rb @@ -0,0 +1,40 @@ +module Roo + module Formatters + module YAML + # returns a rectangular area (default: all cells) as yaml-output + # you can add additional attributes with the prefix parameter like: + # oo.to_yaml({"file"=>"flightdata_2007-06-26", "sheet" => "1"}) + def to_yaml(prefix = {}, from_row = nil, from_column = nil, to_row = nil, to_column = nil, sheet = default_sheet) + # return an empty string if there is no first_row, i.e. the sheet is empty + return "" unless first_row + + from_row ||= first_row(sheet) + to_row ||= last_row(sheet) + from_column ||= first_column(sheet) + to_column ||= last_column(sheet) + + result = "--- \n" + from_row.upto(to_row) do |row| + from_column.upto(to_column) do |col| + next if empty?(row, col, sheet) + + result << "cell_#{row}_#{col}: \n" + prefix.each do|k, v| + result << " #{k}: #{v} \n" + end + result << " row: #{row} \n" + result << " col: #{col} \n" + result << " celltype: #{celltype(row, col, sheet)} \n" + value = cell(row, col, sheet) + if celltype(row, col, sheet) == :time + value = integer_to_timestring(value) + end + result << " value: #{value} \n" + end + end + + result + end + end + end +end |
