aboutsummaryrefslogtreecommitdiffstats
path: root/lib/roo/excelx/styles.rb
blob: 25f0bf04c4cb6067ed65bf3fbedd5706335bce57 (plain) (blame)
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
require 'roo/font'
require 'roo/excelx/extractor'

module Roo
  class Excelx
    class Styles < Excelx::Extractor
      # convert internal excelx attribute to a format
      def style_format(style)
        id = num_fmt_ids[style.to_i]
        num_fmts[id] || Excelx::Format::STANDARD_FORMATS[id.to_i]
      end

      def definitions
        @definitions ||= extract_definitions
      end

      private

      def num_fmt_ids
        @num_fmt_ids ||= extract_num_fmt_ids
      end

      def num_fmts
        @num_fmts ||= extract_num_fmts
      end

      def fonts
        @fonts ||= extract_fonts
      end

      def extract_definitions
        doc.xpath('//cellXfs').flat_map do |xfs|
          xfs.children.map do |xf|
            fonts[xf['fontId'].to_i]
          end
        end
      end

      def extract_fonts
        doc.xpath('//fonts/font').map do |font_el|
          Font.new.tap do |font|
            font.bold = !font_el.xpath('./b').empty?
            font.italic = !font_el.xpath('./i').empty?
            font.underline = !font_el.xpath('./u').empty?
          end
        end
      end

      def extract_num_fmt_ids
        doc.xpath('//cellXfs').flat_map do |xfs|
          xfs.children.map do |xf|
            xf['numFmtId']
          end
        end.compact
      end

      def extract_num_fmts
        doc.xpath('//numFmt').each_with_object({}) do |num_fmt, hash|
          hash[num_fmt['numFmtId']] = num_fmt['formatCode']
        end
      end
    end
  end
end