workbook 0.8.1 → 0.8.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +21 -0
  3. data/.gitignore +4 -1
  4. data/.ruby-version +1 -1
  5. data/.travis.yml +4 -4
  6. data/CHANGELOG.md +7 -0
  7. data/Gemfile +2 -2
  8. data/README.md +9 -7
  9. data/Rakefile +6 -6
  10. data/lib/workbook/book.rb +73 -62
  11. data/lib/workbook/cell.rb +58 -13
  12. data/lib/workbook/column.rb +31 -28
  13. data/lib/workbook/format.rb +23 -24
  14. data/lib/workbook/generatetypes.rb +4 -4
  15. data/lib/workbook/modules/cache.rb +6 -7
  16. data/lib/workbook/modules/cell.rb +77 -100
  17. data/lib/workbook/modules/diff_sort.rb +92 -83
  18. data/lib/workbook/modules/raw_objects_storage.rb +6 -8
  19. data/lib/workbook/modules/type_parser.rb +30 -22
  20. data/lib/workbook/nil_value.rb +4 -9
  21. data/lib/workbook/readers/csv_reader.rb +7 -10
  22. data/lib/workbook/readers/ods_reader.rb +48 -50
  23. data/lib/workbook/readers/txt_reader.rb +6 -8
  24. data/lib/workbook/readers/xls_reader.rb +21 -33
  25. data/lib/workbook/readers/xls_shared.rb +106 -117
  26. data/lib/workbook/readers/xlsx_reader.rb +45 -46
  27. data/lib/workbook/row.rb +99 -84
  28. data/lib/workbook/sheet.rb +47 -38
  29. data/lib/workbook/table.rb +96 -72
  30. data/lib/workbook/template.rb +12 -15
  31. data/lib/workbook/types/false.rb +0 -1
  32. data/lib/workbook/types/nil.rb +0 -1
  33. data/lib/workbook/types/nil_class.rb +1 -1
  34. data/lib/workbook/types/numeric.rb +1 -1
  35. data/lib/workbook/types/string.rb +1 -1
  36. data/lib/workbook/types/time.rb +1 -1
  37. data/lib/workbook/types/true.rb +0 -1
  38. data/lib/workbook/types/true_class.rb +1 -1
  39. data/lib/workbook/version.rb +2 -3
  40. data/lib/workbook/writers/csv_table_writer.rb +10 -13
  41. data/lib/workbook/writers/html_writer.rb +34 -38
  42. data/lib/workbook/writers/json_table_writer.rb +8 -11
  43. data/lib/workbook/writers/xls_writer.rb +30 -36
  44. data/lib/workbook/writers/xlsx_writer.rb +45 -29
  45. data/lib/workbook.rb +16 -15
  46. data/test/helper.rb +6 -5
  47. data/test/test_book.rb +41 -38
  48. data/test/test_column.rb +26 -24
  49. data/test/test_format.rb +51 -55
  50. data/test/test_functional.rb +7 -8
  51. data/test/test_modules_cache.rb +18 -17
  52. data/test/test_modules_cell.rb +47 -46
  53. data/test/test_modules_table_diff_sort.rb +55 -64
  54. data/test/test_modules_type_parser.rb +61 -31
  55. data/test/test_readers_csv_reader.rb +48 -42
  56. data/test/test_readers_ods_reader.rb +28 -31
  57. data/test/test_readers_txt_reader.rb +21 -23
  58. data/test/test_readers_xls_reader.rb +20 -23
  59. data/test/test_readers_xls_shared.rb +2 -3
  60. data/test/test_readers_xlsx_reader.rb +44 -37
  61. data/test/test_row.rb +105 -109
  62. data/test/test_sheet.rb +41 -35
  63. data/test/test_table.rb +82 -60
  64. data/test/test_template.rb +16 -15
  65. data/test/test_types_date.rb +4 -6
  66. data/test/test_writers_csv_writer.rb +24 -0
  67. data/test/test_writers_html_writer.rb +42 -41
  68. data/test/test_writers_json_writer.rb +9 -9
  69. data/test/test_writers_xls_writer.rb +50 -35
  70. data/test/test_writers_xlsx_writer.rb +62 -34
  71. data/workbook.gemspec +26 -27
  72. metadata +92 -27
@@ -1,34 +1,36 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # -*- encoding : utf-8 -*-
4
- # frozen_string_literal: true
5
3
  module Workbook
6
4
  module Readers
7
5
  module OdsReader
8
6
  # reads self with and ods-type content.xml
9
7
  # @param [String,File] file_obj a file or file reference
10
8
  # @return [Workbook::Book] self
11
- def load_ods file_obj, options={}
9
+ def load_ods file_obj, options = {}
12
10
  file_obj = file_obj.path if file_obj.is_a? File
13
11
  content = ""
14
12
  styles = ""
13
+
15
14
  Zip::File.open(file_obj) do |zipfile|
16
15
  zipfile.entries.each do |file|
17
16
  styles = zipfile.read(file.name) if file.name == "styles.xml"
18
17
  content = zipfile.read(file.name) if file.name == "content.xml"
19
18
  end
20
19
  end
20
+
21
21
  content = Nokogiri.XML(content)
22
22
  styles = Nokogiri.XML(styles)
23
+
23
24
  template.add_raw content
24
25
  parse_ods_style styles
25
26
  parse_ods content, options
26
- return self
27
+
28
+ self
27
29
  end
28
30
 
29
31
  def set_format_property format, property, value
30
32
  value.strip!
31
- format[property] = value if value and value != ""
33
+ format[property] = value if value && (value != "")
32
34
  end
33
35
 
34
36
  def parse_ods_style parse_ods_style
@@ -37,14 +39,14 @@ module Workbook
37
39
  if style_family == "table-cell"
38
40
  format = Workbook::Format.new
39
41
  format.name = style.xpath("@style:name").to_s
40
- format.parent = self.template.formats[style.xpath("@style:parent-style-name").to_s]
42
+ format.parent = template.formats[style.xpath("@style:parent-style-name").to_s]
41
43
  set_format_property format, :border, style.xpath("style:table-cell-properties/@fo:border").to_s
42
- set_format_property format, :vertical_align, style.xpath("style:table-cell-properties/@style:vertical-align").to_s.gsub("automatic","auto")
43
- set_format_property format, :padding, style.xpath("style:table-cell-properties/@fo:padding").to_s.gsub("automatic","auto")
44
+ set_format_property format, :vertical_align, style.xpath("style:table-cell-properties/@style:vertical-align").to_s.gsub("automatic", "auto")
45
+ set_format_property format, :padding, style.xpath("style:table-cell-properties/@fo:padding").to_s.gsub("automatic", "auto")
44
46
  set_format_property format, :font, style.xpath("style:text-properties/style:font-name").to_s + " " + style.xpath("style:text-properties/fo:font-size").to_s + " " + style.xpath("style:text-properties/fo:font-weight").to_s
45
47
  set_format_property format, :color, style.xpath("style:text-properties/@fo:color").to_s
46
48
  set_format_property format, :background_color, style.xpath("style:table-cell-properties/@fo:background-color").to_s
47
- self.template.add_format(format)
49
+ template.add_format(format)
48
50
  end
49
51
  end
50
52
  end
@@ -52,105 +54,101 @@ module Workbook
52
54
  # updates self with and ods-type content.xml
53
55
  # @param [Nokogiri::XML::Document] ods_spreadsheet nokogirified content.xml
54
56
  # @return [Workbook::Book] self
55
- def parse_ods ods_spreadsheet=template.raws[Nokogiri::XML::Document], options={}
56
- require 'cgi'
57
+ def parse_ods ods_spreadsheet = template.raws[Nokogiri::XML::Document], options = {}
58
+ require "cgi"
57
59
 
58
- options = {:additional_type_parsing=>false}.merge options
59
- # styles
60
- #puts ods_spreadsheet
61
60
  parse_ods_style ods_spreadsheet
62
61
 
63
- # data
64
- ods_spreadsheet.xpath("//office:body/office:spreadsheet").each_with_index do |sheet,sheetindex|
65
- workbook_sheet = self.create_or_open_sheet_at(sheetindex)
66
- sheet.xpath("table:table").each_with_index do |table,tableindex|
67
- parse_local_table(workbook_sheet,table,tableindex)
62
+ ods_spreadsheet.xpath("//office:body/office:spreadsheet").each_with_index do |sheet, sheetindex|
63
+ workbook_sheet = create_or_open_sheet_at(sheetindex)
64
+ sheet.xpath("table:table").each_with_index do |table, tableindex|
65
+ parse_local_table(workbook_sheet, table, tableindex)
68
66
  end
69
67
  end
70
- return self
68
+ self
71
69
  end
72
70
 
73
- #parse the contents of an entire table by parsing every row in it and adding it to the table
74
- def parse_local_table(sheet,table,tableindex)
75
- local_table = sheet.create_or_open_table_at(tableindex)
71
+ # parse the contents of an entire table by parsing every row in it and adding it to the table
72
+ def parse_local_table(sheet, table, tableindex)
73
+ local_table = sheet[tableindex]
76
74
  local_table.name = table.xpath("@table:name").to_s
77
- #column_count = get_column_count(table)
75
+
78
76
  table.xpath("table:table-row").each do |row|
79
77
  local_table << parse_local_row(row)
80
78
  end
79
+
81
80
  local_table.trim!
82
81
  end
83
82
 
84
- #set column count
83
+ # set column count
85
84
  def get_column_count(table)
86
85
  first_row = table.xpath("table:table-row").first
87
86
  cells = first_row.xpath("table:table-cell|table:covered-table-cell")
88
87
  column_count = 0
89
88
  cells.each do |cell|
90
- if cell.xpath('@table:number-columns-spanned').children.size>0
91
- column_count +=cell.xpath('@table:number-columns-spanned').children[0].inner_text.to_i
89
+ column_count += if cell.xpath("@table:number-columns-spanned").children.size > 0
90
+ cell.xpath("@table:number-columns-spanned").children[0].inner_text.to_i
92
91
  else
93
- column_count +=1
92
+ 1
94
93
  end
95
94
  end
96
95
  column_count
97
96
  end
98
97
 
99
- #parse the contents of an entire row by parsing every cell in it and adding it to the row
98
+ # parse the contents of an entire row by parsing every cell in it and adding it to the row
100
99
  def parse_local_row(row)
101
100
  cells = row.xpath("table:table-cell|table:covered-table-cell")
102
101
  workbook_row = Workbook::Row.new
103
102
  cells.each do |cell|
104
103
  @cell = cell
105
- repeat = get_repeat
106
- workbook_cell = Workbook::Cell.new()
104
+ repeat = cell_repeat
105
+ workbook_cell = Workbook::Cell.new
107
106
  workbook_cell.value = @cell.nil? ? nil : parse_local_cell(workbook_cell)
108
107
  repeat.times do
109
108
  workbook_row << workbook_cell
110
109
  end
111
110
  end
112
- return workbook_row
111
+ workbook_row
113
112
  end
114
113
 
115
- def get_repeat
116
- pre_set = @cell.xpath('@table:number-columns-repeated').to_s
117
- return 1 if (pre_set.nil? || pre_set=="") # if not present, don't repeat.
118
- return 1 unless "#{pre_set.to_i}"=="#{pre_set}" # return 1 if it's not a valid integer
114
+ def cell_repeat
115
+ pre_set = @cell.xpath("@table:number-columns-repeated").to_s
116
+ return 1 if pre_set.nil? || pre_set == "" # if not present, don't repeat.
117
+ return 1 unless pre_set.to_i.to_s == pre_set.to_s # return 1 if it's not a valid integer
119
118
  return 1 if pre_set.to_i < 1 # return 1, negative repeats make no sense
120
- return pre_set.to_i
119
+ pre_set.to_i
121
120
  end
122
121
 
123
- #parse the contents of a single cell
122
+ # parse the contents of a single cell
124
123
  def parse_local_cell(workbook_cell)
125
124
  return Workbook::NilValue.new(:covered) if @cell.name == "covered-table-cell"
126
- set_cell_attributes(workbook_cell)
127
- valuetype = @cell.xpath('@office:value-type').to_s
125
+ configure_cell_attributes(workbook_cell)
126
+ valuetype = @cell.xpath("@office:value-type").to_s
128
127
  parse_local_value(valuetype)
129
128
  end
130
129
 
131
130
  # Sets cell attributes for rowspan, colspan and format
132
- def set_cell_attributes(workbook_cell)
133
- workbook_cell.format = self.template.formats[@cell.xpath('@table:style-name').to_s]
134
- workbook_cell.colspan= @cell.xpath('@table:number-columns-spanned').to_s
135
- workbook_cell.rowspan= @cell.xpath('@table:number-rows-spanned').to_s
131
+ def configure_cell_attributes(workbook_cell)
132
+ workbook_cell.format = template.formats[@cell.xpath("@table:style-name").to_s]
133
+ workbook_cell.colspan = @cell.xpath("@table:number-columns-spanned").to_s
134
+ workbook_cell.rowspan = @cell.xpath("@table:number-rows-spanned").to_s
136
135
  end
137
136
 
138
137
  # Sets value in right context type
139
138
  def parse_local_value(valuetype)
140
139
  value = CGI.unescapeHTML(@cell.xpath("text:p//text()").to_s)
141
- value = (value=="") ? nil : value
140
+ value = value == "" ? nil : value
142
141
  case valuetype
143
- when 'integer'
142
+ when "integer"
144
143
  value = @cell.xpath("@office:value").to_s.to_i
145
- when 'float'
144
+ when "float"
146
145
  value = @cell.xpath("@office:value").to_s.to_f
147
- value = value.to_i unless @cell.xpath("@office:value").to_s.match(/\./) #sadly most integers are typed as floats...
148
- when 'date'
146
+ value = value.to_i unless /\./.match?(@cell.xpath("@office:value").to_s) # sadly most integers are typed as floats...
147
+ when "date"
149
148
  value = DateTime.parse(@cell.xpath("@office:date-value").to_s)
150
149
  end
151
150
  value
152
151
  end
153
-
154
152
  end
155
153
  end
156
154
  end
@@ -1,19 +1,17 @@
1
1
  # frozen_string_literal: true
2
-
3
- # -*- encoding : utf-8 -*-
4
2
  # frozen_string_literal: true
3
+
5
4
  module Workbook
6
5
  module Readers
7
6
  module TxtReader
8
- def load_txt text, options={}
7
+ def load_txt text, options = {}
9
8
  csv = text
10
- parse_txt csv, options
9
+ parse_txt(csv, options)
11
10
  end
12
11
 
13
- def parse_txt csv_raw, options={}
14
- csv = []
15
- csv_raw.split("\n").each {|l| csv << CSV.parse_line(l,{:col_sep=>"\t"});nil}
16
- self[0]=Workbook::Sheet.new(csv,self,{:parse_cells_on_batch_creation=>true, :cell_parse_options=>{:detect_date=>true}}) unless sheet.has_contents?
12
+ def parse_txt(csv_raw, options = {})
13
+ csv = csv_raw.split("\n").collect { |l| CSV.parse_line(l, col_sep: "\t") }
14
+ self[0] = Workbook::Sheet.new(csv, self, parse_cells_on_batch_creation: true, cell_parse_options: {detect_date: true}) unless sheet.has_contents?
17
15
  end
18
16
  end
19
17
  end
@@ -1,9 +1,8 @@
1
1
  # frozen_string_literal: true
2
-
3
- # -*- encoding : utf-8 -*-
4
2
  # frozen_string_literal: true
5
- require 'spreadsheet'
6
- require 'workbook/readers/xls_shared'
3
+
4
+ require "spreadsheet"
5
+ require "workbook/readers/xls_shared"
7
6
 
8
7
  module Workbook
9
8
  module Readers
@@ -11,20 +10,11 @@ module Workbook
11
10
  include Workbook::Readers::XlsShared
12
11
 
13
12
  def load_xls file_obj, options
14
- begin
15
- sp = Spreadsheet.open(file_obj, 'rb')
16
- template.add_raw sp
17
- parse_xls sp, options
18
- rescue Ole::Storage::FormatError
19
- begin
20
- # Assuming it is a tab separated txt inside .xls
21
- import(file_obj.path, 'txt')
22
- rescue Exception => ef
23
-
24
- raise ef
25
- end
26
- end
27
-
13
+ sp = Spreadsheet.open(file_obj, "rb")
14
+ template.add_raw sp
15
+ parse_xls sp, options
16
+ rescue Ole::Storage::FormatError
17
+ import(file_obj.path, "txt")
28
18
  end
29
19
 
30
20
  def parse_xls_cell xls_cell, xls_row, ci
@@ -33,9 +23,9 @@ module Workbook
33
23
  rv = Workbook::Cell.new xls_cell
34
24
  rv.parse!
35
25
  rescue ArgumentError => e
36
- if e.message.match('not a Spreadsheet::Formula')
26
+ if e.message.match?("not a Spreadsheet::Formula")
37
27
  v = xls_cell.value
38
- if v.class == Float and xls_row.format(ci).date?
28
+ if v.instance_of?(Float) && xls_row.format(ci).date?
39
29
  xls_row[ci] = v
40
30
  v = xls_row.datetime(ci)
41
31
  end
@@ -43,14 +33,12 @@ module Workbook
43
33
  v = "----!"
44
34
  end
45
35
  rv = Workbook::Cell.new v
46
- elsif e.message.match('not a Spreadsheet::Link')
36
+ elsif e.message.match?("not a Spreadsheet::Link")
47
37
  rv = Workbook::Cell.new xls_cell.to_s
48
- elsif e.message.match('not a Spreadsheet::Link')
49
- rv = Workbook::Cell.new xls_cell.to_s
50
- elsif e.message.match('not a Spreadsheet::Excel::Error')
38
+ elsif e.message.match?("not a Spreadsheet::Excel::Error")
51
39
  rv = "._."
52
40
  else
53
- rv = "._." # raise e (we're going to be silent for now)
41
+ rv = "._." # raise e (we're going to be silent for now)
54
42
  end
55
43
  end
56
44
  rv
@@ -64,8 +52,8 @@ module Workbook
64
52
  col_width = col_widths[ci]
65
53
  end
66
54
 
67
- f = template.create_or_find_format_by "object_id_#{xls_format.object_id}",col_width
68
- f[:width]= col_width
55
+ f = template.create_or_find_format_by "object_id_#{xls_format.object_id}", col_width
56
+ f[:width] = col_width
69
57
  f[:rotation] = xls_format.rotation if xls_format.rotation
70
58
  f[:background_color] = xls_color_to_html_hex(xls_format.pattern_fg_color)
71
59
  f[:number_format] = ms_formatting_to_strftime(xls_format.number_format)
@@ -81,15 +69,14 @@ module Workbook
81
69
  def parse_xls_row ri, s, xls_sheet
82
70
  xls_row = xls_sheet.row(ri)
83
71
  r = s.table.create_or_open_row_at(ri)
84
- col_widths = xls_sheet.columns.collect{|c| c.width if c}
85
- xls_row.each_with_index do |xls_cell,ci|
72
+ col_widths = xls_sheet.columns.collect { |c| c&.width }
73
+ xls_row.each_with_index do |xls_cell, ci|
86
74
  r[ci] = parse_xls_cell xls_cell, xls_row, ci
87
75
  r[ci].format = parse_xls_format xls_row, ci, ri, col_widths
88
76
  end
89
77
  end
90
78
 
91
- def parse_xls xls_spreadsheet=template.raws[Spreadsheet::Excel::Workbook], options={}
92
- options = {:additional_type_parsing=>true}.merge options
79
+ def parse_xls xls_spreadsheet = template.raws[Spreadsheet::Excel::Workbook], options = {}
93
80
  number_of_worksheets = xls_spreadsheet.worksheets.count
94
81
  number_of_worksheets.times do |si|
95
82
  xls_sheet = xls_spreadsheet.worksheets[si]
@@ -103,15 +90,16 @@ module Workbook
103
90
  end
104
91
  rescue TypeError
105
92
  puts "WARNING: Failed at worksheet (#{si})... ignored"
106
- #ignore SpreadsheetGem can be buggy...
93
+ # ignore SpreadsheetGem can be buggy...
107
94
  end
108
95
  end
109
96
  end
110
97
  end
111
98
 
112
99
  private
100
+
113
101
  def xls_color_to_html_hex color_sym
114
- Workbook::Book::XLS_COLORS[color_sym] ? Workbook::Book::XLS_COLORS[color_sym] : "#000000"
102
+ Workbook::Book::XLS_COLORS[color_sym] || "#000000"
115
103
  end
116
104
  end
117
105
  end
@@ -1,13 +1,11 @@
1
1
  # frozen_string_literal: true
2
-
3
- # -*- encoding : utf-8 -*-
4
2
  # frozen_string_literal: true
5
- require 'date'
3
+
4
+ require "date"
6
5
 
7
6
  module Workbook
8
7
  module Readers
9
8
  module XlsShared
10
-
11
9
  # Converts standard (ruby/C++/unix/...) strftime formatting to MS's formatting
12
10
  #
13
11
  # @param [String, nil] ms_nr_format (nil returns nil)
@@ -16,26 +14,26 @@ module Workbook
16
14
  ms_nr_format = num_fmt_id_to_ms_formatting(ms_nr_format) if ms_nr_format.is_a? Integer
17
15
  if ms_nr_format
18
16
  ms_nr_format = ms_nr_format.to_s.downcase
19
- return nil if ms_nr_format == 'general' or ms_nr_format == ""
17
+ return nil if (ms_nr_format == "general") || (ms_nr_format == "")
20
18
  translation_table = {
21
- 'yyyy'=>'%Y',
22
- 'dddd'=>'%A',
23
- 'mmmm'=>'%B',
24
- 'ddd'=>'%a',
25
- 'mmm'=>'%b',
26
- 'yy'=>'%y',
27
- 'dd'=>'%d',
28
- 'mm'=>'%m',
29
- 'y'=>'%y',
30
- '%%y'=>'%y',
31
- 'd'=>'%e',
32
- '%%e'=>'%d',
33
- 'm'=>'%m',
34
- '%%m'=>'%m',
35
- ';@'=>'',
36
- '\\'=>''
19
+ "yyyy" => "%Y",
20
+ "dddd" => "%A",
21
+ "mmmm" => "%B",
22
+ "ddd" => "%a",
23
+ "mmm" => "%b",
24
+ "yy" => "%y",
25
+ "dd" => "%d",
26
+ "mm" => "%m",
27
+ "y" => "%y",
28
+ "%%y" => "%y",
29
+ "d" => "%e",
30
+ "%%e" => "%d",
31
+ "m" => "%m",
32
+ "%%m" => "%m",
33
+ ";@" => "",
34
+ "\\" => ""
37
35
  }
38
- translation_table.each{|k,v| ms_nr_format.gsub!(k,v) }
36
+ translation_table.each { |k, v| ms_nr_format.gsub!(k, v) }
39
37
  ms_nr_format
40
38
  end
41
39
  end
@@ -45,37 +43,30 @@ module Workbook
45
43
  # @return [String] number format (excel markup)
46
44
  def num_fmt_id_to_ms_formatting num_fmt_id
47
45
  # from: https://stackoverflow.com/questions/4730152/what-indicates-an-office-open-xml-cell-contains-a-date-time-value
48
- {'0'=>nil, '1'=>'0', '2'=>'0.00', '3'=>'#,##0', '4'=>'#,##0.00',
49
- '9'=>'0%', '10'=>'0.00%', '11'=>'0.00E+00', '12'=>'# ?/?',
50
- '13'=>'# ??/??', '14'=>'mm-dd-yy', '15'=>'d-mmm-yy', '16'=>'d-mmm',
51
- '17'=>'mmm-yy', '18'=>'h:mm AM/PM', '19'=>'h:mm:ss AM/PM',
52
- '20'=>'h:mm', '21'=>'h:mm:ss', '22'=>'m/d/yy h:mm',
53
- '37'=>'#,##0 ;(#,##0)', '38'=>'#,##0 ;[Red](#,##0)',
54
- '39'=>'#,##0.00;(#,##0.00)', '40'=>'#,##0.00;[Red](#,##0.00)',
55
- '44'=>'_("$"* #,##0.00_);_("$"* \(#,##0.00\);_("$"* "-"??_);_(@_)',
56
- '45'=>'mm:ss', '46'=>'[h]:mm:ss', '47'=>'mmss.0', '48'=>'##0.0E+0',
57
- '49'=>'@', '27'=>'[$-404]e/m/d', '30'=>'m/d/yy', '36'=>'[$-404]e/m/d',
58
- '50'=>'[$-404]e/m/d', '57'=>'[$-404]e/m/d', '59'=>'t0', '60'=>'t0.00',
59
- '61'=>'t#,##0', '62'=>'t#,##0.00', '67'=>'t0%', '68'=>'t0.00%',
60
- '69'=>'t# ?/?', '70' => 't# ??/??'}[num_fmt_id.to_s]
46
+ {"0" => nil, "1" => "0", "2" => "0.00", "3" => "#,##0", "4" => "#,##0.00",
47
+ "9" => "0%", "10" => "0.00%", "11" => "0.00E+00", "12" => "# ?/?",
48
+ "13" => "# ??/??", "14" => "mm-dd-yy", "15" => "d-mmm-yy", "16" => "d-mmm",
49
+ "17" => "mmm-yy", "18" => "h:mm AM/PM", "19" => "h:mm:ss AM/PM",
50
+ "20" => "h:mm", "21" => "h:mm:ss", "22" => "m/d/yy h:mm",
51
+ "37" => "#,##0 ;(#,##0)", "38" => "#,##0 ;[Red](#,##0)",
52
+ "39" => "#,##0.00;(#,##0.00)", "40" => "#,##0.00;[Red](#,##0.00)",
53
+ "44" => '_("$"* #,##0.00_);_("$"* \(#,##0.00\);_("$"* "-"??_);_(@_)',
54
+ "45" => "mm:ss", "46" => "[h]:mm:ss", "47" => "mmss.0", "48" => "##0.0E+0",
55
+ "49" => "@", "27" => "[$-404]e/m/d", "30" => "m/d/yy", "36" => "[$-404]e/m/d",
56
+ "50" => "[$-404]e/m/d", "57" => "[$-404]e/m/d", "59" => "t0", "60" => "t0.00",
57
+ "61" => "t#,##0", "62" => "t#,##0.00", "67" => "t0%", "68" => "t0.00%",
58
+ "69" => "t# ?/?", "70" => "t# ??/??"}[num_fmt_id.to_s]
61
59
  end
62
60
 
63
-
64
-
65
-
66
-
67
-
68
-
69
-
70
61
  # Attempt to convert html-hex color value to xls color number
71
62
  #
72
63
  # @param [String] hex color
73
64
  # @return [String] xls color
74
65
  def html_color_to_xls_color hex
75
- Workbook::Readers::XlsShared::XLS_COLORS.each do |k,v|
76
- return k if (v == hex or (hex and hex != "" and k == hex.to_sym))
66
+ Workbook::Readers::XlsShared::XLS_COLORS.each do |k, v|
67
+ return k if (v == hex) || (hex && (hex != "") && (k == hex.to_sym))
77
68
  end
78
- return nil
69
+ nil
79
70
  end
80
71
 
81
72
  # Converts standard (ruby/C++/unix/...) strftime formatting to MS's formatting
@@ -84,86 +75,84 @@ module Workbook
84
75
  # @return [String, nil]
85
76
  def strftime_to_ms_format numberformat
86
77
  return nil if numberformat.nil?
87
- return numberformat.gsub('%Y','yyyy').gsub('%A','dddd').gsub('%B','mmmm').gsub('%a','ddd').gsub('%b','mmm').gsub('%y','yy').gsub('%d','dd').gsub('%m','mm').gsub('%y','y').gsub('%y','%%y').gsub('%e','d')
78
+ numberformat.gsub("%Y", "yyyy").gsub("%A", "dddd").gsub("%B", "mmmm").gsub("%a", "ddd").gsub("%b", "mmm").gsub("%y", "yy").gsub("%d", "dd").gsub("%m", "mm").gsub("%y", "y").gsub("%y", "%%y").gsub("%e", "d")
88
79
  end
89
80
 
90
- def xls_number_to_time number, base_date = DateTime.new(1899,12,30)
81
+ def xls_number_to_time number, base_date = DateTime.new(1899, 12, 30)
91
82
  base_date + number.to_f
92
83
  end
93
84
 
94
- def xls_number_to_date number, base_date = Date.new(1899,12,30)
85
+ def xls_number_to_date number, base_date = Date.new(1899, 12, 30)
95
86
  base_date + number.to_i
96
87
  end
97
88
 
98
- XLS_COLORS = {:xls_color_1=>'#000000',
99
- :xls_color_2=>'#FFFFFF',
100
- :xls_color_3=>'#FF0000',
101
- :xls_color_4=>'#00FF00',
102
- :xls_color_5=>'#0000FF',
103
- :xls_color_6=>'#FFFF00',
104
- :xls_color_7=>'#FF00FF',
105
- :xls_color_8=>'#00FFFF',
106
- :xls_color_9=>'#800000',
107
- :xls_color_10=>'#008000',
108
- :xls_color_11=>'#000080',
109
- :xls_color_12=>'#808000',
110
- :xls_color_13=>'#800080',
111
- :xls_color_14=>'#008080',
112
- :xls_color_15=>'#C0C0C0',
113
- :xls_color_16=>'#808080',
114
- :xls_color_17=>'#9999FF',
115
- :xls_color_18=>'#993366',
116
- :xls_color_19=>'#FFFFCC',
117
- :xls_color_20=>'#CCFFFF',
118
- :xls_color_21=>'#660066',
119
- :xls_color_22=>'#FF8080',
120
- :xls_color_23=>'#0066CC',
121
- :xls_color_24=>'#CCCCFF',
122
- :xls_color_25=>'#000080',
123
- :xls_color_26=>'#FF00FF',
124
- :xls_color_27=>'#FFFF00',
125
- :xls_color_28=>'#00FFFF',
126
- :xls_color_29=>'#800080',
127
- :xls_color_30=>'#800000',
128
- :xls_color_31=>'#008080',
129
- :xls_color_32=>'#0000FF',
130
- :xls_color_33=>'#00CCFF',
131
- :xls_color_34=>'#CCFFFF',
132
- :xls_color_35=>'#CCFFCC',
133
- :xls_color_36=>'#FFFF99',
134
- :xls_color_37=>'#99CCFF',
135
- :xls_color_38=>'#FF99CC',
136
- :xls_color_39=>'#CC99FF',
137
- :xls_color_40=>'#FFCC99',
138
- :xls_color_41=>'#3366FF',
139
- :xls_color_42=>'#33CCCC',
140
- :xls_color_43=>'#99CC00',
141
- :xls_color_44=>'#FFCC00',
142
- :xls_color_45=>'#FF9900',
143
- :xls_color_46=>'#FF6600',
144
- :xls_color_47=>'#666699',
145
- :xls_color_48=>'#969696',
146
- :xls_color_49=>'#003366',
147
- :xls_color_50=>'#339966',
148
- :xls_color_51=>'#003300',
149
- :xls_color_52=>'#333300',
150
- :xls_color_53=>'#993300',
151
- :xls_color_54=>'#993366',
152
- :xls_color_55=>'#333399',
153
- :xls_color_56=>'#333333',
154
- :black=>'#000000',
155
- :white=>'#FFFFFF',
156
- :red=>'#FF0000',
157
- :green=>'#00FF00',
158
- :blue=>'#0000FF',
159
- :yellow=>'#FFFF00',
160
- :magenta=>'#FF00FF',
161
- :cyan=>'#00FFFF',
162
- :border=>'#FFFFFF',
163
- :text=>'#000000',
164
- :lime=>'#00f94c'
165
- }
89
+ XLS_COLORS = {xls_color_1: "#000000",
90
+ xls_color_2: "#FFFFFF",
91
+ xls_color_3: "#FF0000",
92
+ xls_color_4: "#00FF00",
93
+ xls_color_5: "#0000FF",
94
+ xls_color_6: "#FFFF00",
95
+ xls_color_7: "#FF00FF",
96
+ xls_color_8: "#00FFFF",
97
+ xls_color_9: "#800000",
98
+ xls_color_10: "#008000",
99
+ xls_color_11: "#000080",
100
+ xls_color_12: "#808000",
101
+ xls_color_13: "#800080",
102
+ xls_color_14: "#008080",
103
+ xls_color_15: "#C0C0C0",
104
+ xls_color_16: "#808080",
105
+ xls_color_17: "#9999FF",
106
+ xls_color_18: "#993366",
107
+ xls_color_19: "#FFFFCC",
108
+ xls_color_20: "#CCFFFF",
109
+ xls_color_21: "#660066",
110
+ xls_color_22: "#FF8080",
111
+ xls_color_23: "#0066CC",
112
+ xls_color_24: "#CCCCFF",
113
+ xls_color_25: "#000080",
114
+ xls_color_26: "#FF00FF",
115
+ xls_color_27: "#FFFF00",
116
+ xls_color_28: "#00FFFF",
117
+ xls_color_29: "#800080",
118
+ xls_color_30: "#800000",
119
+ xls_color_31: "#008080",
120
+ xls_color_32: "#0000FF",
121
+ xls_color_33: "#00CCFF",
122
+ xls_color_34: "#CCFFFF",
123
+ xls_color_35: "#CCFFCC",
124
+ xls_color_36: "#FFFF99",
125
+ xls_color_37: "#99CCFF",
126
+ xls_color_38: "#FF99CC",
127
+ xls_color_39: "#CC99FF",
128
+ xls_color_40: "#FFCC99",
129
+ xls_color_41: "#3366FF",
130
+ xls_color_42: "#33CCCC",
131
+ xls_color_43: "#99CC00",
132
+ xls_color_44: "#FFCC00",
133
+ xls_color_45: "#FF9900",
134
+ xls_color_46: "#FF6600",
135
+ xls_color_47: "#666699",
136
+ xls_color_48: "#969696",
137
+ xls_color_49: "#003366",
138
+ xls_color_50: "#339966",
139
+ xls_color_51: "#003300",
140
+ xls_color_52: "#333300",
141
+ xls_color_53: "#993300",
142
+ xls_color_54: "#993366",
143
+ xls_color_55: "#333399",
144
+ xls_color_56: "#333333",
145
+ black: "#000000",
146
+ white: "#FFFFFF",
147
+ red: "#FF0000",
148
+ green: "#00FF00",
149
+ blue: "#0000FF",
150
+ yellow: "#FFFF00",
151
+ magenta: "#FF00FF",
152
+ cyan: "#00FFFF",
153
+ border: "#FFFFFF",
154
+ text: "#000000",
155
+ lime: "#00f94c"}
166
156
  end
167
157
  end
168
158
  end
169
-