caxlsx 2.0.2 → 3.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (210) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +125 -30
  3. data/README.md +65 -151
  4. data/Rakefile +9 -11
  5. data/examples/{image1.jpeg → assets/image1.jpeg} +0 -0
  6. data/examples/generate.rb +15 -0
  7. data/lib/axlsx.rb +35 -17
  8. data/lib/axlsx/content_type/abstract_content_type.rb +1 -1
  9. data/lib/axlsx/content_type/content_type.rb +1 -1
  10. data/lib/axlsx/doc_props/app.rb +1 -1
  11. data/lib/axlsx/doc_props/core.rb +5 -5
  12. data/lib/axlsx/drawing/area_chart.rb +99 -0
  13. data/lib/axlsx/drawing/area_series.rb +110 -0
  14. data/lib/axlsx/drawing/axes.rb +1 -1
  15. data/lib/axlsx/drawing/axis.rb +12 -9
  16. data/lib/axlsx/drawing/bar_3D_chart.rb +13 -13
  17. data/lib/axlsx/drawing/bar_chart.rb +143 -0
  18. data/lib/axlsx/drawing/bar_series.rb +12 -14
  19. data/lib/axlsx/drawing/bubble_chart.rb +59 -0
  20. data/lib/axlsx/drawing/bubble_series.rb +63 -0
  21. data/lib/axlsx/drawing/cat_axis.rb +5 -5
  22. data/lib/axlsx/drawing/chart.rb +52 -8
  23. data/lib/axlsx/drawing/d_lbls.rb +4 -4
  24. data/lib/axlsx/drawing/drawing.rb +6 -1
  25. data/lib/axlsx/drawing/graphic_frame.rb +3 -3
  26. data/lib/axlsx/drawing/hyperlink.rb +1 -3
  27. data/lib/axlsx/drawing/line_3D_chart.rb +2 -2
  28. data/lib/axlsx/drawing/line_chart.rb +10 -10
  29. data/lib/axlsx/drawing/line_series.rb +32 -3
  30. data/lib/axlsx/drawing/marker.rb +1 -1
  31. data/lib/axlsx/drawing/num_data.rb +4 -4
  32. data/lib/axlsx/drawing/num_data_source.rb +6 -6
  33. data/lib/axlsx/drawing/num_val.rb +3 -1
  34. data/lib/axlsx/drawing/one_cell_anchor.rb +3 -2
  35. data/lib/axlsx/drawing/pic.rb +25 -19
  36. data/lib/axlsx/drawing/picture_locking.rb +1 -3
  37. data/lib/axlsx/drawing/pie_3D_chart.rb +5 -6
  38. data/lib/axlsx/drawing/pie_series.rb +6 -6
  39. data/lib/axlsx/drawing/scaling.rb +6 -6
  40. data/lib/axlsx/drawing/scatter_chart.rb +10 -10
  41. data/lib/axlsx/drawing/scatter_series.rb +40 -7
  42. data/lib/axlsx/drawing/ser_axis.rb +2 -2
  43. data/lib/axlsx/drawing/series.rb +3 -3
  44. data/lib/axlsx/drawing/series_title.rb +4 -2
  45. data/lib/axlsx/drawing/str_data.rb +3 -3
  46. data/lib/axlsx/drawing/str_val.rb +3 -1
  47. data/lib/axlsx/drawing/title.rb +23 -4
  48. data/lib/axlsx/drawing/two_cell_anchor.rb +6 -1
  49. data/lib/axlsx/drawing/val_axis.rb +1 -1
  50. data/lib/axlsx/drawing/view_3D.rb +2 -2
  51. data/lib/axlsx/drawing/vml_drawing.rb +1 -1
  52. data/lib/axlsx/package.rb +58 -47
  53. data/lib/axlsx/rels/relationship.rb +27 -26
  54. data/lib/axlsx/rels/relationships.rb +7 -4
  55. data/lib/axlsx/stylesheet/border_pr.rb +2 -2
  56. data/lib/axlsx/stylesheet/cell_alignment.rb +1 -3
  57. data/lib/axlsx/stylesheet/cell_protection.rb +1 -3
  58. data/lib/axlsx/stylesheet/cell_style.rb +1 -3
  59. data/lib/axlsx/stylesheet/color.rb +1 -3
  60. data/lib/axlsx/stylesheet/font.rb +11 -3
  61. data/lib/axlsx/stylesheet/gradient_stop.rb +1 -1
  62. data/lib/axlsx/stylesheet/num_fmt.rb +10 -3
  63. data/lib/axlsx/stylesheet/pattern_fill.rb +1 -1
  64. data/lib/axlsx/stylesheet/styles.rb +7 -7
  65. data/lib/axlsx/stylesheet/table_style_element.rb +1 -3
  66. data/lib/axlsx/util/accessors.rb +6 -6
  67. data/lib/axlsx/util/constants.rb +108 -99
  68. data/lib/axlsx/util/mime_type_utils.rb +11 -0
  69. data/lib/axlsx/util/options_parser.rb +2 -1
  70. data/lib/axlsx/util/serialized_attributes.rb +16 -6
  71. data/lib/axlsx/util/simple_typed_list.rb +28 -52
  72. data/lib/axlsx/util/storage.rb +4 -4
  73. data/lib/axlsx/util/validators.rb +31 -19
  74. data/lib/axlsx/util/zip_command.rb +73 -0
  75. data/lib/axlsx/version.rb +1 -1
  76. data/lib/axlsx/workbook/defined_name.rb +11 -12
  77. data/lib/axlsx/workbook/defined_names.rb +2 -2
  78. data/lib/axlsx/workbook/shared_strings_table.rb +5 -5
  79. data/lib/axlsx/workbook/workbook.rb +36 -20
  80. data/lib/axlsx/workbook/workbook_view.rb +80 -0
  81. data/lib/axlsx/workbook/workbook_views.rb +22 -0
  82. data/lib/axlsx/workbook/worksheet/auto_filter/auto_filter.rb +2 -2
  83. data/lib/axlsx/workbook/worksheet/auto_filter/filters.rb +1 -3
  84. data/lib/axlsx/workbook/worksheet/break.rb +1 -3
  85. data/lib/axlsx/workbook/worksheet/cell.rb +164 -75
  86. data/lib/axlsx/workbook/worksheet/cell_serializer.rb +63 -43
  87. data/lib/axlsx/workbook/worksheet/cfvo.rb +1 -3
  88. data/lib/axlsx/workbook/worksheet/cfvos.rb +4 -1
  89. data/lib/axlsx/workbook/worksheet/col.rb +14 -13
  90. data/lib/axlsx/workbook/worksheet/col_breaks.rb +2 -2
  91. data/lib/axlsx/workbook/worksheet/cols.rb +5 -2
  92. data/lib/axlsx/workbook/worksheet/comment.rb +5 -6
  93. data/lib/axlsx/workbook/worksheet/comments.rb +9 -12
  94. data/lib/axlsx/workbook/worksheet/conditional_formatting.rb +1 -1
  95. data/lib/axlsx/workbook/worksheet/conditional_formatting_rule.rb +1 -1
  96. data/lib/axlsx/workbook/worksheet/data_bar.rb +4 -6
  97. data/lib/axlsx/workbook/worksheet/data_validation.rb +8 -6
  98. data/lib/axlsx/workbook/worksheet/dimension.rb +2 -2
  99. data/lib/axlsx/workbook/worksheet/header_footer.rb +6 -8
  100. data/lib/axlsx/workbook/worksheet/icon_set.rb +3 -5
  101. data/lib/axlsx/workbook/worksheet/merged_cells.rb +4 -2
  102. data/lib/axlsx/workbook/worksheet/outline_pr.rb +33 -0
  103. data/lib/axlsx/workbook/worksheet/page_margins.rb +1 -3
  104. data/lib/axlsx/workbook/worksheet/page_set_up_pr.rb +1 -1
  105. data/lib/axlsx/workbook/worksheet/page_setup.rb +21 -23
  106. data/lib/axlsx/workbook/worksheet/pane.rb +1 -3
  107. data/lib/axlsx/workbook/worksheet/pivot_table.rb +44 -28
  108. data/lib/axlsx/workbook/worksheet/pivot_table_cache_definition.rb +4 -4
  109. data/lib/axlsx/workbook/worksheet/print_options.rb +1 -3
  110. data/lib/axlsx/workbook/worksheet/protected_range.rb +1 -3
  111. data/lib/axlsx/workbook/worksheet/protected_ranges.rb +5 -2
  112. data/lib/axlsx/workbook/worksheet/rich_text.rb +55 -0
  113. data/lib/axlsx/workbook/worksheet/rich_text_run.rb +250 -0
  114. data/lib/axlsx/workbook/worksheet/row.rb +42 -52
  115. data/lib/axlsx/workbook/worksheet/row_breaks.rb +2 -2
  116. data/lib/axlsx/workbook/worksheet/selection.rb +1 -3
  117. data/lib/axlsx/workbook/worksheet/sheet_data.rb +3 -1
  118. data/lib/axlsx/workbook/worksheet/sheet_pr.rb +21 -3
  119. data/lib/axlsx/workbook/worksheet/sheet_protection.rb +1 -3
  120. data/lib/axlsx/workbook/worksheet/table.rb +6 -6
  121. data/lib/axlsx/workbook/worksheet/table_style_info.rb +1 -3
  122. data/lib/axlsx/workbook/worksheet/tables.rb +4 -1
  123. data/lib/axlsx/workbook/worksheet/worksheet.rb +76 -81
  124. data/lib/axlsx/workbook/worksheet/worksheet_drawing.rb +10 -10
  125. data/lib/axlsx/workbook/worksheet/worksheet_hyperlinks.rb +3 -3
  126. data/lib/caxlsx.rb +2 -0
  127. data/test/drawing/tc_area_chart.rb +39 -0
  128. data/test/drawing/tc_area_series.rb +71 -0
  129. data/test/drawing/tc_axis.rb +27 -0
  130. data/test/drawing/tc_bar_chart.rb +71 -0
  131. data/test/drawing/tc_bubble_chart.rb +44 -0
  132. data/test/drawing/tc_bubble_series.rb +21 -0
  133. data/test/drawing/tc_chart.rb +23 -10
  134. data/test/drawing/tc_data_source.rb +6 -0
  135. data/test/drawing/tc_drawing.rb +4 -4
  136. data/test/drawing/tc_hyperlink.rb +1 -1
  137. data/test/drawing/tc_line_chart.rb +5 -5
  138. data/test/drawing/tc_line_series.rb +47 -6
  139. data/test/drawing/tc_one_cell_anchor.rb +1 -1
  140. data/test/drawing/tc_pic.rb +11 -15
  141. data/test/drawing/tc_pie_series.rb +2 -1
  142. data/test/drawing/tc_scatter_series.rb +36 -1
  143. data/test/drawing/tc_series_title.rb +21 -0
  144. data/test/drawing/tc_str_val.rb +9 -0
  145. data/test/drawing/tc_title.rb +21 -0
  146. data/test/fixtures/image1.gif +0 -0
  147. data/test/fixtures/image1.jpeg +0 -0
  148. data/test/fixtures/image1.jpg +0 -0
  149. data/test/fixtures/image1.png +0 -0
  150. data/test/fixtures/image1_fake.jpg +0 -0
  151. data/test/rels/tc_relationship.rb +8 -0
  152. data/test/stylesheet/tc_font.rb +14 -2
  153. data/test/stylesheet/tc_styles.rb +29 -3
  154. data/test/tc_axlsx.rb +37 -0
  155. data/test/tc_helper.rb +2 -0
  156. data/test/tc_package.rb +50 -13
  157. data/test/util/tc_mime_type_utils.rb +13 -0
  158. data/test/util/tc_simple_typed_list.rb +2 -3
  159. data/test/util/tc_validators.rb +35 -11
  160. data/test/workbook/tc_defined_name.rb +12 -4
  161. data/test/workbook/tc_shared_strings_table.rb +16 -1
  162. data/test/workbook/tc_workbook.rb +38 -3
  163. data/test/workbook/tc_workbook_view.rb +50 -0
  164. data/test/workbook/worksheet/auto_filter/tc_filters.rb +1 -1
  165. data/test/workbook/worksheet/tc_break.rb +1 -1
  166. data/test/workbook/worksheet/tc_cell.rb +143 -9
  167. data/test/workbook/worksheet/tc_col.rb +18 -3
  168. data/test/workbook/worksheet/tc_conditional_formatting.rb +2 -2
  169. data/test/workbook/worksheet/tc_data_bar.rb +1 -1
  170. data/test/workbook/worksheet/tc_data_validation.rb +11 -11
  171. data/test/workbook/worksheet/tc_header_footer.rb +2 -2
  172. data/test/workbook/worksheet/tc_icon_set.rb +1 -1
  173. data/test/workbook/worksheet/tc_outline_pr.rb +19 -0
  174. data/test/workbook/worksheet/tc_page_setup.rb +3 -3
  175. data/test/workbook/worksheet/tc_pivot_table.rb +21 -6
  176. data/test/workbook/worksheet/tc_print_options.rb +1 -1
  177. data/test/workbook/worksheet/tc_rich_text.rb +44 -0
  178. data/test/workbook/worksheet/tc_rich_text_run.rb +173 -0
  179. data/test/workbook/worksheet/tc_row.rb +24 -2
  180. data/test/workbook/worksheet/tc_sheet_calc_pr.rb +1 -1
  181. data/test/workbook/worksheet/tc_sheet_format_pr.rb +4 -4
  182. data/test/workbook/worksheet/tc_sheet_pr.rb +26 -4
  183. data/test/workbook/worksheet/tc_sheet_protection.rb +5 -5
  184. data/test/workbook/worksheet/tc_sheet_view.rb +4 -4
  185. data/test/workbook/worksheet/tc_table.rb +2 -3
  186. data/test/workbook/worksheet/tc_worksheet.rb +123 -60
  187. metadata +180 -128
  188. data/examples/2010_comments.rb +0 -17
  189. data/examples/anchor_swapping.rb +0 -28
  190. data/examples/auto_filter.rb +0 -16
  191. data/examples/basic_charts.rb +0 -58
  192. data/examples/chart_colors.rb +0 -88
  193. data/examples/colored_links.rb +0 -59
  194. data/examples/conditional_formatting/example_conditional_formatting.rb +0 -74
  195. data/examples/conditional_formatting/getting_barred.rb +0 -37
  196. data/examples/conditional_formatting/hitting_the_high_notes.rb +0 -37
  197. data/examples/conditional_formatting/scaled_colors.rb +0 -39
  198. data/examples/conditional_formatting/stop_and_go.rb +0 -37
  199. data/examples/data_validation.rb +0 -50
  200. data/examples/example.rb +0 -777
  201. data/examples/extractive.rb +0 -45
  202. data/examples/ios_preview.rb +0 -14
  203. data/examples/page_setup.rb +0 -11
  204. data/examples/pivot_table.rb +0 -39
  205. data/examples/sheet_protection.rb +0 -10
  206. data/examples/skydrive/real_example.rb +0 -63
  207. data/examples/styles.rb +0 -66
  208. data/examples/underline.rb +0 -13
  209. data/examples/wrap_text.rb +0 -21
  210. data/lib/axlsx/util/parser.rb +0 -44
@@ -14,7 +14,7 @@ module Axlsx
14
14
  # @see Break
15
15
  def add_break(options)
16
16
  # force feed the excel default
17
- @list << Break.new(options.merge(:max => 16383, :man => true))
17
+ self << Break.new(options.merge(:max => 16383, :man => true))
18
18
  last
19
19
  end
20
20
 
@@ -25,7 +25,7 @@ module Axlsx
25
25
  # </rowBreaks>
26
26
  def to_xml_string(str='')
27
27
  return if empty?
28
- str << '<rowBreaks count="' << @list.size.to_s << '" manualBreakCount="' << @list.size.to_s << '">'
28
+ str << ('<rowBreaks count="' << self.size.to_s << '" manualBreakCount="' << self.size.to_s << '">')
29
29
  each { |brk| brk.to_xml_string(str) }
30
30
  str << '</rowBreaks>'
31
31
  end
@@ -95,9 +95,7 @@ module Axlsx
95
95
  # @param [String] str
96
96
  # @return [String]
97
97
  def to_xml_string(str = '')
98
- str << '<selection '
99
- serialized_attributes str
100
- str << '/>'
98
+ serialized_tag 'selection', str
101
99
  end
102
100
  end
103
101
  end
@@ -17,7 +17,9 @@ module Axlsx
17
17
  # @return [String]
18
18
  def to_xml_string(str = '')
19
19
  str << '<sheetData>'
20
- worksheet.rows.each_with_index{ |row, index| row.to_xml_string(index, str) }
20
+ worksheet.rows.each_with_index do |row, index|
21
+ row.to_xml_string(index, str)
22
+ end
21
23
  str << '</sheetData>'
22
24
  end
23
25
 
@@ -1,6 +1,6 @@
1
1
  module Axlsx
2
2
 
3
- # The SheetPr class manages serialization fo a worksheet's sheetPr element.
3
+ # The SheetPr class manages serialization of a worksheet's sheetPr element.
4
4
  class SheetPr
5
5
  include Axlsx::OptionsParser
6
6
  include Axlsx::Accessors
@@ -8,7 +8,7 @@ module Axlsx
8
8
 
9
9
  serializable_attributes :sync_horizontal,
10
10
  :sync_vertical,
11
- :transtion_evaluation,
11
+ :transition_evaluation,
12
12
  :transition_entry,
13
13
  :published,
14
14
  :filter_mode,
@@ -20,7 +20,7 @@ module Axlsx
20
20
  # waving magic show to set up the attriubte accessors
21
21
  boolean_attr_accessor :sync_horizontal,
22
22
  :sync_vertical,
23
- :transtion_evaluation,
23
+ :transition_evaluation,
24
24
  :transition_entry,
25
25
  :published,
26
26
  :filter_mode,
@@ -33,6 +33,7 @@ module Axlsx
33
33
  def initialize(worksheet, options={})
34
34
  raise ArgumentError, "you must provide a worksheet" unless worksheet.is_a?(Worksheet)
35
35
  @worksheet = worksheet
36
+ @outline_pr = nil
36
37
  parse_options options
37
38
  end
38
39
 
@@ -40,12 +41,18 @@ module Axlsx
40
41
  # @return [Worksheet]
41
42
  attr_reader :worksheet
42
43
 
44
+ # The tab color of the sheet.
45
+ # @return [Color]
46
+ attr_reader :tab_color
47
+
43
48
  # Serialize the object
44
49
  # @param [String] str serialized output will be appended to this object if provided.
45
50
  # @return [String]
46
51
  def to_xml_string(str = '')
47
52
  update_properties
48
53
  str << "<sheetPr #{serialized_attributes}>"
54
+ tab_color.to_xml_string(str, 'tabColor') if tab_color
55
+ outline_pr.to_xml_string(str) if @outline_pr
49
56
  page_setup_pr.to_xml_string(str)
50
57
  str << "</sheetPr>"
51
58
  end
@@ -55,6 +62,17 @@ module Axlsx
55
62
  def page_setup_pr
56
63
  @page_setup_pr ||= PageSetUpPr.new
57
64
  end
65
+
66
+ # The OutlinePr for this sheet pr object
67
+ # @return [OutlinePr]
68
+ def outline_pr
69
+ @outline_pr ||= OutlinePr.new
70
+ end
71
+
72
+ # @see tab_color
73
+ def tab_color=(v)
74
+ @tab_color ||= Color.new(:rgb => v)
75
+ end
58
76
 
59
77
  private
60
78
 
@@ -76,9 +76,7 @@ module Axlsx
76
76
  # @param [String] str
77
77
  # @return [String]
78
78
  def to_xml_string(str = '')
79
- str << '<sheetProtection '
80
- serialized_attributes str
81
- str << '/>'
79
+ serialized_tag('sheetProtection', str)
82
80
  end
83
81
 
84
82
  private
@@ -58,7 +58,7 @@ module Axlsx
58
58
  # @param [String, Cell] v
59
59
  # @return [Title]
60
60
  def name=(v)
61
- DataTypeValidator.validate "#{self.class}.name", [String], v
61
+ DataTypeValidator.validate :table_name, [String], v
62
62
  if v.is_a?(String)
63
63
  @name = v
64
64
  end
@@ -75,12 +75,12 @@ module Axlsx
75
75
  # @return [String]
76
76
  def to_xml_string(str = '')
77
77
  str << '<?xml version="1.0" encoding="UTF-8"?>'
78
- str << '<table xmlns="' << XML_NS << '" id="' << (index+1).to_s << '" name="' << @name << '" displayName="' << @name.gsub(/\s/,'_') << '" '
79
- str << 'ref="' << @ref << '" totalsRowShown="0">'
80
- str << '<autoFilter ref="' << @ref << '"/>'
81
- str << '<tableColumns count="' << header_cells.length.to_s << '">'
78
+ str << ('<table xmlns="' << XML_NS << '" id="' << (index+1).to_s << '" name="' << @name << '" displayName="' << @name.gsub(/\s/,'_') << '" ')
79
+ str << ('ref="' << @ref << '" totalsRowShown="0">')
80
+ str << ('<autoFilter ref="' << @ref << '"/>')
81
+ str << ('<tableColumns count="' << header_cells.length.to_s << '">')
82
82
  header_cells.each_with_index do |cell,index|
83
- str << '<tableColumn id ="' << (index+1).to_s << '" name="' << cell.value << '"/>'
83
+ str << ('<tableColumn id ="' << (index+1).to_s << '" name="' << cell.value << '"/>')
84
84
  end
85
85
  str << '</tableColumns>'
86
86
  table_style_info.to_xml_string(str)
@@ -43,9 +43,7 @@ module Axlsx
43
43
  # seralizes this object to an xml string
44
44
  # @param [String] str the string to contact this objects serialization to.
45
45
  def to_xml_string(str = '')
46
- str << '<tableStyleInfo '
47
- serialized_attributes str
48
- str << '/>'
46
+ serialized_tag('tableStyleInfo', str)
49
47
  end
50
48
  end
51
49
  end
@@ -20,10 +20,13 @@ module Axlsx
20
20
  map{ |table| Relationship.new(table, TABLE_R, "../#{table.pn}") }
21
21
  end
22
22
 
23
+ # renders the tables xml
24
+ # @param [String] str
25
+ # @return [String]
23
26
  def to_xml_string(str = "")
24
27
  return if empty?
25
28
  str << "<tableParts count='#{size}'>"
26
- @list.each { |table| str << "<tablePart r:id='#{table.rId}'/>" }
29
+ each { |table| str << "<tablePart r:id='#{table.rId}'/>" }
27
30
  str << '</tableParts>'
28
31
  end
29
32
  end
@@ -4,14 +4,7 @@ module Axlsx
4
4
  # The Worksheet class represents a worksheet in the workbook.
5
5
  class Worksheet
6
6
  include Axlsx::OptionsParser
7
-
8
- # definition of characters which are less than the maximum width of 0-9 in the default font for use in String#count.
9
- # This is used for autowidth calculations
10
- # @return [String]
11
- def self.thin_chars
12
- # removed 'e' and 'y' from this list - as a GUESS
13
- @thin_chars ||= "^.acfijklrstxzFIJL()-"
14
- end
7
+ include Axlsx::SerializedAttributes
15
8
 
16
9
  # Creates a new worksheet.
17
10
  # @note the recommended way to manage worksheets is Workbook#add_worksheet
@@ -24,12 +17,15 @@ module Axlsx
24
17
  def initialize(wb, options={})
25
18
  self.workbook = wb
26
19
  @sheet_protection = nil
27
-
28
20
  initialize_page_options(options)
29
21
  parse_options options
30
22
  @workbook.worksheets << self
23
+ @sheet_id = index + 1
24
+ yield self if block_given?
31
25
  end
32
26
 
27
+ serializable_attributes :sheet_id, :state
28
+
33
29
  # Initalizes page margin, setup and print options
34
30
  # @param [Hash] options Options passed in from the initializer
35
31
  def initialize_page_options(options)
@@ -44,7 +40,23 @@ module Axlsx
44
40
  # The name of the worksheet
45
41
  # @return [String]
46
42
  def name
47
- @name ||= "Sheet" + (index+1).to_s
43
+ @name ||= "Sheet" + (index+1).to_s
44
+ end
45
+
46
+ # Specifies the visible state of this sheet. Allowed states are
47
+ # :visible, :hidden or :very_hidden. The default value is :visible.
48
+ #
49
+ # Worksheets in the :hidden state can be shown using the sheet formatting properties in excel.
50
+ # :very_hidden sheets should be inaccessible to end users.
51
+ # @param [Symbol] sheet_state The visible state for this sheet.
52
+ def state=(sheet_state)
53
+ RestrictionValidator.validate :worksheet_state, [:visible, :hidden, :very_hidden], sheet_state
54
+ @state = sheet_state
55
+ end
56
+
57
+ # The visibility of this sheet
58
+ def state
59
+ @state ||= :visible
48
60
  end
49
61
 
50
62
  # The sheet calculation properties
@@ -76,7 +88,7 @@ module Axlsx
76
88
  # @see [SheetFormatPr]
77
89
  def sheet_format_pr
78
90
  @sheet_format_pr ||= SheetFormatPr.new
79
- yeild @sheet_format_pr if block_given?
91
+ yield @sheet_format_pr if block_given?
80
92
  @sheet_format_pr
81
93
  end
82
94
 
@@ -129,7 +141,7 @@ module Axlsx
129
141
  # @return [SimpleTypedList]
130
142
  # @see Worksheet#add_row
131
143
  def rows
132
- @rows ||= SimpleTypedList.new Row
144
+ @rows ||= SimpleTypedList.new Row
133
145
  end
134
146
 
135
147
  # returns the sheet data as columns
@@ -137,12 +149,12 @@ module Axlsx
137
149
  # cell at a specific index. The block will be called with the row and column
138
150
  # index in the missing cell was found.
139
151
  # @example
140
- # cols { |row_index, column_index| p "warn - row #{row_index} is does not have a cell at #{column_index}
152
+ # cols { |row_index, column_index| puts "warn - row #{row_index} does not have a cell at #{column_index}" }
141
153
  def cols(&block)
142
154
  @rows.transpose(&block)
143
155
  end
144
156
 
145
- # An range that excel will apply an auto-filter to "A1:B3"
157
+ # A range that excel will apply an auto-filter to "A1:B3"
146
158
  # This will turn filtering on for the cells in the range.
147
159
  # The first row is considered the header, while subsequent rows are considered to be data.
148
160
  # @return String
@@ -249,7 +261,7 @@ module Axlsx
249
261
  @header_footer
250
262
  end
251
263
 
252
- # convinience method to access all cells in this worksheet
264
+ # convenience method to access all cells in this worksheet
253
265
  # @return [Array] cells
254
266
  def cells
255
267
  rows.flatten
@@ -290,50 +302,6 @@ module Axlsx
290
302
  @sheet_pr ||= SheetPr.new self
291
303
  end
292
304
 
293
- # Indicates if gridlines should be shown in the sheet.
294
- # This is true by default.
295
- # @return [Boolean]
296
- # @deprecated Use SheetView#show_grid_lines= instead.
297
- def show_gridlines=(v)
298
- warn('axlsx::DEPRECIATED: Worksheet#show_gridlines= has been depreciated. This value can be set over SheetView#show_grid_lines=.')
299
- Axlsx::validate_boolean v
300
- sheet_view.show_grid_lines = v
301
- end
302
-
303
- # @see selected
304
- # @return [Boolean]
305
- # @deprecated Use SheetView#tab_selected= instead.
306
- def selected=(v)
307
- warn('axlsx::DEPRECIATED: Worksheet#selected= has been depreciated. This value can be set over SheetView#tab_selected=.')
308
- Axlsx::validate_boolean v
309
- sheet_view.tab_selected = v
310
- end
311
-
312
- # Indicates if the worksheet should show gridlines or not
313
- # @return Boolean
314
- # @deprecated Use SheetView#show_grid_lines instead.
315
- def show_gridlines
316
- warn('axlsx::DEPRECIATED: Worksheet#show_gridlines has been depreciated. This value can get over SheetView#show_grid_lines.')
317
- sheet_view.show_grid_lines
318
- end
319
-
320
- # Indicates if the worksheet is selected in the workbook
321
- # It is possible to have more than one worksheet selected, however it might cause issues
322
- # in some older versions of excel when using copy and paste.
323
- # @return Boolean
324
- # @deprecated Use SheetView#tab_selected instead.
325
- def selected
326
- warn('axlsx::DEPRECIATED: Worksheet#selected has been depreciated. This value can get over SheetView#tab_selected.')
327
- sheet_view.tab_selected
328
- end
329
-
330
- # (see #fit_to_page)
331
- # @return [Boolean]
332
- def fit_to_page=(v)
333
- warn('axlsx::DEPRECIATED: Worksheet#fit_to_page has been depreciated. This value will automatically be set for you when you use PageSetup#fit_to.')
334
- fit_to_page?
335
- end
336
-
337
305
  # The name of the worksheet
338
306
  # The name of a worksheet must be unique in the workbook, and must not exceed 31 characters
339
307
  # @param [String] name
@@ -346,7 +314,7 @@ module Axlsx
346
314
  # @param [String] v
347
315
  # @see auto_filter
348
316
  def auto_filter=(v)
349
- DataTypeValidator.validate "Worksheet.auto_filter", String, v
317
+ DataTypeValidator.validate :worksheet_auto_filter, String, v
350
318
  auto_filter.range = v
351
319
  end
352
320
 
@@ -419,6 +387,12 @@ module Axlsx
419
387
  # @example - use << alias
420
388
  # ws << [3, 4, 5], :types => [nil, :float]
421
389
  #
390
+ # @example - specify whether a row should escape formulas or not
391
+ # ws.add_row ['=IF(2+2=4,4,5)', 2, 3], :escape_formulas=>true
392
+ #
393
+ # @example - specify whether a certain cells in a row should escape formulas or not
394
+ # ws.add_row ['=IF(2+2=4,4,5)', '=IF(13+13=4,4,5)'], :escape_formulas=>[true, false]
395
+ #
422
396
  # @see Worksheet#column_widths
423
397
  # @return [Row]
424
398
  # @option options [Array] values
@@ -426,11 +400,15 @@ module Axlsx
426
400
  # @option options [Array, Integer] style
427
401
  # @option options [Array] widths each member of the widths array will affect how auto_fit behavies.
428
402
  # @option options [Float] height the row's height (in points)
403
+ # @option options [Array, Boolean] escape_formulas - Whether to treat a value starting with an equal
404
+ # sign as formula (default) or as simple string.
405
+ # Allowing user generated data to be interpreted as formulas can be dangerous
406
+ # (see https://www.owasp.org/index.php/CSV_Injection for details).
429
407
  def add_row(values=[], options={})
430
- Row.new(self, values, options)
431
- update_column_info @rows.last.cells, options.delete(:widths) || []
432
- yield @rows.last if block_given?
433
- @rows.last
408
+ row = Row.new(self, values, options)
409
+ update_column_info row, options.delete(:widths)
410
+ yield row if block_given?
411
+ row
434
412
  end
435
413
 
436
414
  alias :<< :add_row
@@ -522,7 +500,7 @@ module Axlsx
522
500
  # @example
523
501
  # ws.add_page_break("A4")
524
502
  def add_page_break(cell)
525
- DataTypeValidator.validate "Worksheet#add_page_break cell", [String, Cell], cell
503
+ DataTypeValidator.validate :worksheet_page_break, [String, Cell], cell
526
504
  column_index, row_index = if cell.is_a?(String)
527
505
  Axlsx.name_to_indices(cell)
528
506
  else
@@ -535,12 +513,12 @@ module Axlsx
535
513
  end
536
514
 
537
515
  # This is a helper method that Lets you specify a fixed width for multiple columns in a worksheet in one go.
538
- # Axlsx is sparse, so if you have not set data for a column, you cannot set the width.
516
+ # Note that you must call column_widths AFTER adding data, otherwise the width will not be set successfully.
539
517
  # Setting a fixed column width to nil will revert the behaviour back to calculating the width for you on the next call to add_row.
540
518
  # @example This would set the first and third column widhts but leave the second column in autofit state.
541
519
  # ws.column_widths 7.2, nil, 3
542
520
  # @note For updating only a single column it is probably easier to just set the width of the ws.column_info[col_index].width directly
543
- # @param [Integer|Float|Fixnum|nil] widths
521
+ # @param [Integer|Float|nil] widths
544
522
  def column_widths(*widths)
545
523
  widths.each_with_index do |value, index|
546
524
  next if value == nil
@@ -559,7 +537,7 @@ module Axlsx
559
537
  # @see README.md for an example
560
538
  def col_style(index, style, options={})
561
539
  offset = options.delete(:row_offset) || 0
562
- cells = @rows[(offset..-1)].map { |row| row.cells[index] }.flatten.compact
540
+ cells = @rows[(offset..-1)].map { |row| row[index] }.flatten.compact
563
541
  cells.each { |cell| cell.style = style }
564
542
  end
565
543
 
@@ -577,18 +555,27 @@ module Axlsx
577
555
  cells.each { |cell| cell.style = style }
578
556
  end
579
557
 
558
+ # Returns a sheet node serialization for this sheet in the workbook.
559
+ def to_sheet_node_xml_string(str='')
560
+ add_autofilter_defined_name_to_workbook
561
+ str << '<sheet '
562
+ serialized_attributes str
563
+ str << ('name="' << name << '" ')
564
+ str << ('r:id="' << rId << '"></sheet>')
565
+ end
566
+
580
567
  # Serializes the worksheet object to an xml string
581
568
  # This intentionally does not use nokogiri for performance reasons
582
569
  # @return [String]
583
- def to_xml_string
570
+ def to_xml_string str=''
571
+ add_autofilter_defined_name_to_workbook
584
572
  auto_filter.apply if auto_filter.range
585
- str = '<?xml version="1.0" encoding="UTF-8"?>'
573
+ str << '<?xml version="1.0" encoding="UTF-8"?>'
586
574
  str << worksheet_node
587
575
  serializable_parts.each do |item|
588
576
  item.to_xml_string(str) if item
589
577
  end
590
578
  str << '</worksheet>'
591
- Axlsx::sanitize(str)
592
579
  end
593
580
 
594
581
  # The worksheet relationships. This is managed automatically by the worksheet
@@ -606,7 +593,7 @@ module Axlsx
606
593
  # Returns the cell or cells defined using excel style A1:B3 references.
607
594
  # @param [String|Integer] cell_def the string defining the cell or range of cells, or the rownumber
608
595
  # @return [Cell, Array]
609
- def [] (cell_def)
596
+ def [](cell_def)
610
597
  return rows[cell_def] if cell_def.is_a?(Integer)
611
598
  parts = cell_def.split(':').map{ |part| name_to_cell part }
612
599
  if parts.size == 1
@@ -622,7 +609,7 @@ module Axlsx
622
609
  def name_to_cell(name)
623
610
  col_index, row_index = *Axlsx::name_to_indices(name)
624
611
  r = rows[row_index]
625
- r.cells[col_index] if r
612
+ r[col_index] if r
626
613
  end
627
614
 
628
615
  # shortcut method to access styles direclty from the worksheet
@@ -675,8 +662,10 @@ module Axlsx
675
662
  end
676
663
 
677
664
  def validate_sheet_name(name)
678
- DataTypeValidator.validate "Worksheet.name", String, name
679
- raise ArgumentError, (ERR_SHEET_NAME_TOO_LONG % name) if name.size > 31
665
+ DataTypeValidator.validate :worksheet_name, String, name
666
+ # ignore first character (BOM) after encoding to utf16 because Excel does so, too.
667
+ character_length = name.encode("utf-16")[1..-1].encode("utf-16").bytesize / 2
668
+ raise ArgumentError, (ERR_SHEET_NAME_TOO_LONG % name) if character_length > 31
680
669
  raise ArgumentError, (ERR_SHEET_NAME_CHARACTER_FORBIDDEN % name) if '[]*/\?:'.chars.any? { |char| name.include? char }
681
670
  name = Axlsx::coder.encode(name)
682
671
  sheet_names = @workbook.worksheets.reject { |s| s == self }.map { |s| s.name }
@@ -695,8 +684,8 @@ module Axlsx
695
684
  def range(*cell_def)
696
685
  first, last = cell_def
697
686
  cells = []
698
- rows[(first.row.index..last.row.index)].each do |r|
699
- r.cells[(first.index..last.index)].each do |c|
687
+ rows[(first.row.row_index..last.row.row_index)].each do |r|
688
+ r[(first.index..last.index)].each do |c|
700
689
  cells << c
701
690
  end
702
691
  end
@@ -734,7 +723,7 @@ module Axlsx
734
723
  # Helper method for parsingout the root node for worksheet
735
724
  # @return [String]
736
725
  def worksheet_node
737
- "<worksheet xmlns=\"%s\" xmlns:r=\"%s\" xml:space=\"#{xml_space}\">" % [XML_NS, XML_NS_R]
726
+ "<worksheet xmlns=\"#{XML_NS}\" xmlns:r=\"#{XML_NS_R}\" xml:space=\"#{xml_space}\">"
738
727
  end
739
728
 
740
729
  def sheet_data
@@ -753,11 +742,12 @@ module Axlsx
753
742
 
754
743
  def workbook=(v) DataTypeValidator.validate "Worksheet.workbook", Workbook, v; @workbook = v; end
755
744
 
756
- def update_column_info(cells, widths=[])
745
+ def update_column_info(cells, widths=nil)
757
746
  cells.each_with_index do |cell, index|
747
+ width = widths ? widths[index] : nil
758
748
  col = find_or_create_column_info(index)
759
- next if widths[index] == :ignore
760
- col.update_width(cell, widths[index], workbook.use_autowidth)
749
+ next if width == :ignore
750
+ col.update_width(cell, width, workbook.use_autowidth)
761
751
  end
762
752
  end
763
753
 
@@ -765,5 +755,10 @@ module Axlsx
765
755
  column_info[index] ||= Col.new(index + 1, index + 1)
766
756
  end
767
757
 
758
+ def add_autofilter_defined_name_to_workbook
759
+ return if !auto_filter.range
760
+ workbook.add_defined_name auto_filter.defined_name, name: '_xlnm._FilterDatabase', local_sheet_id: index, hidden: 1
761
+ end
762
+
768
763
  end
769
764
  end