summaryrefslogtreecommitdiffhomepage
path: root/lib/axlsx/workbook/worksheet/cell_serializer.rb
blob: 77844ea6e634b823797e8179c8319333b583719a (plain)
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
module Axlsx

  # The Cell Serializer class contains the logic for serializing cells based on their type.
  class CellSerializer
    class << self


      # Calls the proper serialization method based on type.
      # @param [Integer] row_index The index of the cell's row
      # @param [Integer] column_index The index of the cell's column
      # @param [String] str The string to apend serialization to.
      # @return [String]
      def to_xml_string(row_index, column_index, cell, str='')
        str << ('<c r="' << Axlsx::cell_r(column_index, row_index) << '" s="' << cell.style.to_s << '" ')
        return str << '/>' if cell.value.nil?
        method = cell.type
        self.send(method, cell, str)
        str << '</c>'
      end 


      # builds an xml text run based on this cells attributes.
      # @param [String] str The string instance this run will be concated to.
      # @return [String]
      def run_xml_string(cell, str = '')
        if cell.is_text_run?
          data = cell.instance_values.reject{ |key, value| value == nil || key == 'value' || key == 'type' }
          keys = data.keys & Cell::INLINE_STYLES
          str << '<r><rPr>'
          keys.each do |key|
            case key
            when :font_name
              str << ('<rFont val="' << cell.font_name << '"/>')
            when :color
              str << data[key].to_xml_string
            else
              str << ('<' << key.to_s << ' val="' << data[key].to_s << '"/>')
            end
          end
          str << ('</rPr><t>' << cell.value.to_s << '</t></r>')
        else
          str << ('<t>' << cell.value.to_s << '</t>')
        end
        str
      end

      # serializes cells that are type iso_8601
      # @param [Cell] cell The cell that is being serialized
      # @param [String] str The string the serialized content will be appended to.
      # @return [String]
      def iso_8601(cell, str='')
        value_serialization 'd', cell.value, str
      end


      # serializes cells that are type date
      # @param [Cell] cell The cell that is being serialized
      # @param [String] str The string the serialized content will be appended to.
      # @return [String]
      def date(cell, str='')
        value_serialization false, DateTimeConverter::date_to_serial(cell.value).to_s, str
      end

      # Serializes cells that are type time
      # @param [Cell] cell The cell that is being serialized
      # @param [String] str The string the serialized content will be appended to.
      # @return [String]
      def time(cell, str='')
        value_serialization false, DateTimeConverter::time_to_serial(cell.value).to_s, str
      end

      # Serializes cells that are type boolean
      # @param [Cell] cell The cell that is being serialized
      # @param [String] str The string the serialized content will be appended to.
      # @return [String]
      def boolean(cell, str='')
        value_serialization 'b', cell.value.to_s, str
      end

      # Serializes cells that are type float
      # @param [Cell] cell The cell that is being serialized
      # @param [String] str The string the serialized content will be appended to.
      # @return [String]
      def float(cell, str='')
        numeric cell, str
      end

      # Serializes cells that are type integer
      # @param [Cell] cell The cell that is being serialized
      # @param [String] str The string the serialized content will be appended to.
      # @return [String]
      def integer(cell, str = '')
        numeric cell, str
      end


      # Serializes cells that are type formula
      # @param [Cell] cell The cell that is being serialized
      # @param [String] str The string the serialized content will be appended to.
      # @return [String]
      def formula_serialization(cell, str='')
        str << ('t="str"><f>' << cell.value.to_s.sub('=', '') << '</f>')
        str << ('<v>' << cell.formula_value.to_s << '</v>') unless cell.formula_value.nil?
      end

      # Serializes cells that are type inline_string
      # @param [Cell] cell The cell that is being serialized
      # @param [String] str The string the serialized content will be appended to.
      # @return [String]
      def inline_string_serialization(cell, str = '')
        str << 't="inlineStr"><is>'
        run_xml_string cell, str
        str << '</is>'
      end

      # Serializes cells that are type string
      # @param [Cell] cell The cell that is being serialized
      # @param [String] str The string the serialized content will be appended to.
      # @return [String]
      def string(cell, str='')
        if cell.is_formula?
          formula_serialization cell, str
        elsif !cell.ssti.nil?
          value_serialization 's', cell.ssti.to_s, str
        else
          inline_string_serialization cell, str
        end
      end

      private

      def numeric(cell, str = '')
        value_serialization 'n', cell.value.to_s, str
      end

      def value_serialization(serialization_type, serialization_value, str = '')
        str << ('t="' << serialization_type << '"') if serialization_type
        str << ('><v>' << serialization_value << '</v>')
      end


    end
  end
end