File: row.rb

package info (click to toggle)
ruby-spreadsheet 1.3.4-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 8,980 kB
  • sloc: ruby: 6,939; makefile: 10
file content (106 lines) | stat: -rw-r--r-- 2,584 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
require "date"
require "spreadsheet/row"

module Spreadsheet
  module Excel
    ##
    # Excel-specific Row methods
    class Row < Spreadsheet::Row
      ##
      # The Excel date calculation erroneously assumes that 1900 is a leap-year. All
      # Dates after 28.2.1900 are off by one.
      LEAP_ERROR = Date.new 1900, 2, 28
      ##
      # Force convert the cell at _idx_ to a Date
      def date idx
        set_date at(idx)
      end

      ##
      # Force convert the cell at _idx_ to a DateTime
      def datetime idx
        set_datetime at(idx)
      end

      def each
        size.times do |idx|
          yield self[idx]
        end
      end

      ##
      # Access data in this Row like you would in an Array. If a cell is formatted
      # as a Date or DateTime, the decoded Date or DateTime value is returned.
      def [] idx, len = nil
        if len
          idx = idx...(idx + len)
        end
        if idx.is_a? Range
          data = []
          idx.each do |i|
            data.push enriched_data(i, at(i))
          end
          data
        else
          enriched_data idx, at(idx)
        end
      end

      ##
      # Returns data as an array. If a cell is formatted as a Date or DateTime, the
      # decoded Date or DateTime value is returned.
      def to_a
        self[0...length]
      end

      private

      def set_date data # :nodoc:
        return data if data.is_a?(Date)
        datetime = set_datetime data
        Date.new datetime.year, datetime.month, datetime.day
      end

      def set_datetime data # :nodoc:
        return data if data.is_a?(DateTime)
        base = @worksheet.date_base
        date = base + data.to_f
        hour = (data.to_f % 1) * 24
        min = (hour % 1) * 60
        sec = ((min % 1) * 60).round
        min = min.floor
        hour = hour.floor
        if sec > 59
          sec = 0
          min += 1
        end
        if min > 59
          min = 0
          hour += 1
        end
        if hour > 23
          hour = 0
          date += 1
        end
        if base < LEAP_ERROR
          date -= 1
        end
        DateTime.new(date.year, date.month, date.day, hour, min, sec)
      end

      def enriched_data idx, data # :nodoc:
        res = nil
        if (link = @worksheet.links[[@idx, idx]])
          res = link
        elsif data.is_a?(Numeric) && (fmt = format(idx))
          res = if fmt.datetime? || fmt.time?
            set_datetime data
          elsif fmt.date?
            set_date data
          end
        end
        res || data
      end
    end
  end
end