caxlsx 4.0.0 → 4.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (133) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +48 -12
  3. data/README.md +18 -9
  4. data/Rakefile +2 -9
  5. data/examples/generate.rb +3 -1
  6. data/lib/axlsx/content_type/abstract_content_type.rb +6 -3
  7. data/lib/axlsx/content_type/content_type.rb +4 -4
  8. data/lib/axlsx/content_type/default.rb +4 -1
  9. data/lib/axlsx/content_type/override.rb +4 -1
  10. data/lib/axlsx/doc_props/app.rb +91 -24
  11. data/lib/axlsx/drawing/area_chart.rb +3 -3
  12. data/lib/axlsx/drawing/area_series.rb +10 -4
  13. data/lib/axlsx/drawing/ax_data_source.rb +1 -1
  14. data/lib/axlsx/drawing/axes.rb +1 -1
  15. data/lib/axlsx/drawing/axis.rb +25 -7
  16. data/lib/axlsx/drawing/bar_3D_chart.rb +14 -4
  17. data/lib/axlsx/drawing/bar_chart.rb +14 -4
  18. data/lib/axlsx/drawing/bar_series.rb +14 -5
  19. data/lib/axlsx/drawing/bubble_chart.rb +2 -2
  20. data/lib/axlsx/drawing/bubble_series.rb +2 -2
  21. data/lib/axlsx/drawing/cat_axis.rb +23 -8
  22. data/lib/axlsx/drawing/chart.rb +33 -8
  23. data/lib/axlsx/drawing/d_lbls.rb +9 -8
  24. data/lib/axlsx/drawing/drawing.rb +50 -49
  25. data/lib/axlsx/drawing/hyperlink.rb +13 -4
  26. data/lib/axlsx/drawing/line_3D_chart.rb +3 -3
  27. data/lib/axlsx/drawing/line_chart.rb +3 -3
  28. data/lib/axlsx/drawing/line_series.rb +10 -4
  29. data/lib/axlsx/drawing/marker.rb +19 -4
  30. data/lib/axlsx/drawing/num_val.rb +1 -1
  31. data/lib/axlsx/drawing/one_cell_anchor.rb +8 -2
  32. data/lib/axlsx/drawing/pic.rb +17 -8
  33. data/lib/axlsx/drawing/pie_3D_chart.rb +3 -3
  34. data/lib/axlsx/drawing/pie_chart.rb +36 -0
  35. data/lib/axlsx/drawing/pie_series.rb +18 -6
  36. data/lib/axlsx/drawing/scaling.rb +18 -4
  37. data/lib/axlsx/drawing/scatter_chart.rb +2 -2
  38. data/lib/axlsx/drawing/scatter_series.rb +2 -2
  39. data/lib/axlsx/drawing/ser_axis.rb +11 -5
  40. data/lib/axlsx/drawing/series.rb +8 -2
  41. data/lib/axlsx/drawing/two_cell_anchor.rb +1 -1
  42. data/lib/axlsx/drawing/val_axis.rb +2 -2
  43. data/lib/axlsx/drawing/view_3D.rb +8 -2
  44. data/lib/axlsx/drawing/vml_shape.rb +1 -1
  45. data/lib/axlsx/package.rb +54 -21
  46. data/lib/axlsx/rels/relationship.rb +15 -5
  47. data/lib/axlsx/rels/relationships.rb +3 -3
  48. data/lib/axlsx/stylesheet/border.rb +12 -3
  49. data/lib/axlsx/stylesheet/border_pr.rb +16 -4
  50. data/lib/axlsx/stylesheet/cell_alignment.rb +39 -10
  51. data/lib/axlsx/stylesheet/cell_protection.rb +9 -2
  52. data/lib/axlsx/stylesheet/cell_style.rb +30 -7
  53. data/lib/axlsx/stylesheet/color.rb +10 -4
  54. data/lib/axlsx/stylesheet/dxf.rb +29 -6
  55. data/lib/axlsx/stylesheet/fill.rb +4 -1
  56. data/lib/axlsx/stylesheet/font.rb +59 -13
  57. data/lib/axlsx/stylesheet/gradient_fill.rb +9 -3
  58. data/lib/axlsx/stylesheet/gradient_stop.rb +9 -2
  59. data/lib/axlsx/stylesheet/num_fmt.rb +8 -2
  60. data/lib/axlsx/stylesheet/pattern_fill.rb +15 -3
  61. data/lib/axlsx/stylesheet/styles.rb +84 -43
  62. data/lib/axlsx/stylesheet/table_style.rb +15 -4
  63. data/lib/axlsx/stylesheet/table_style_element.rb +12 -3
  64. data/lib/axlsx/stylesheet/table_styles.rb +10 -3
  65. data/lib/axlsx/stylesheet/theme.rb +163 -0
  66. data/lib/axlsx/stylesheet/xf.rb +70 -16
  67. data/lib/axlsx/util/accessors.rb +9 -7
  68. data/lib/axlsx/util/buffered_zip_output_stream.rb +6 -2
  69. data/lib/axlsx/util/constants.rb +14 -2
  70. data/lib/axlsx/util/mime_type_utils.rb +72 -13
  71. data/lib/axlsx/util/serialized_attributes.rb +2 -2
  72. data/lib/axlsx/util/simple_typed_list.rb +26 -14
  73. data/lib/axlsx/util/storage.rb +4 -4
  74. data/lib/axlsx/util/uri_utils.rb +70 -0
  75. data/lib/axlsx/util/validators.rb +6 -6
  76. data/lib/axlsx/version.rb +1 -1
  77. data/lib/axlsx/workbook/defined_name.rb +2 -1
  78. data/lib/axlsx/workbook/defined_names.rb +1 -1
  79. data/lib/axlsx/workbook/shared_strings_table.rb +3 -3
  80. data/lib/axlsx/workbook/workbook.rb +87 -67
  81. data/lib/axlsx/workbook/workbook_view.rb +1 -1
  82. data/lib/axlsx/workbook/workbook_views.rb +1 -1
  83. data/lib/axlsx/workbook/worksheet/auto_filter/auto_filter.rb +4 -4
  84. data/lib/axlsx/workbook/worksheet/auto_filter/filter_column.rb +5 -3
  85. data/lib/axlsx/workbook/worksheet/auto_filter/filters.rb +4 -4
  86. data/lib/axlsx/workbook/worksheet/auto_filter/sort_condition.rb +1 -1
  87. data/lib/axlsx/workbook/worksheet/auto_filter/sort_state.rb +2 -2
  88. data/lib/axlsx/workbook/worksheet/border_creator.rb +4 -4
  89. data/lib/axlsx/workbook/worksheet/cell.rb +40 -20
  90. data/lib/axlsx/workbook/worksheet/cell_serializer.rb +1 -1
  91. data/lib/axlsx/workbook/worksheet/cfvo.rb +8 -2
  92. data/lib/axlsx/workbook/worksheet/col.rb +23 -9
  93. data/lib/axlsx/workbook/worksheet/col_breaks.rb +1 -1
  94. data/lib/axlsx/workbook/worksheet/cols.rb +1 -1
  95. data/lib/axlsx/workbook/worksheet/comment.rb +2 -2
  96. data/lib/axlsx/workbook/worksheet/comments.rb +1 -1
  97. data/lib/axlsx/workbook/worksheet/conditional_formatting.rb +9 -3
  98. data/lib/axlsx/workbook/worksheet/conditional_formatting_rule.rb +70 -15
  99. data/lib/axlsx/workbook/worksheet/conditional_formattings.rb +3 -3
  100. data/lib/axlsx/workbook/worksheet/data_validation.rb +53 -14
  101. data/lib/axlsx/workbook/worksheet/data_validations.rb +3 -3
  102. data/lib/axlsx/workbook/worksheet/date_time_converter.rb +2 -2
  103. data/lib/axlsx/workbook/worksheet/dimension.rb +1 -1
  104. data/lib/axlsx/workbook/worksheet/header_footer.rb +1 -1
  105. data/lib/axlsx/workbook/worksheet/icon_set.rb +17 -5
  106. data/lib/axlsx/workbook/worksheet/merged_cells.rb +1 -1
  107. data/lib/axlsx/workbook/worksheet/outline_pr.rb +1 -1
  108. data/lib/axlsx/workbook/worksheet/page_margins.rb +30 -7
  109. data/lib/axlsx/workbook/worksheet/page_set_up_pr.rb +1 -2
  110. data/lib/axlsx/workbook/worksheet/page_setup.rb +32 -9
  111. data/lib/axlsx/workbook/worksheet/pane.rb +9 -2
  112. data/lib/axlsx/workbook/worksheet/pivot_table.rb +30 -6
  113. data/lib/axlsx/workbook/worksheet/pivot_tables.rb +1 -1
  114. data/lib/axlsx/workbook/worksheet/print_options.rb +1 -0
  115. data/lib/axlsx/workbook/worksheet/protected_ranges.rb +1 -1
  116. data/lib/axlsx/workbook/worksheet/rich_text_run.rb +31 -11
  117. data/lib/axlsx/workbook/worksheet/row.rb +5 -2
  118. data/lib/axlsx/workbook/worksheet/row_breaks.rb +1 -1
  119. data/lib/axlsx/workbook/worksheet/selection.rb +8 -2
  120. data/lib/axlsx/workbook/worksheet/sheet_calc_pr.rb +1 -0
  121. data/lib/axlsx/workbook/worksheet/sheet_pr.rb +1 -1
  122. data/lib/axlsx/workbook/worksheet/sheet_protection.rb +1 -1
  123. data/lib/axlsx/workbook/worksheet/sheet_view.rb +30 -9
  124. data/lib/axlsx/workbook/worksheet/table_style_info.rb +3 -2
  125. data/lib/axlsx/workbook/worksheet/tables.rb +1 -1
  126. data/lib/axlsx/workbook/worksheet/worksheet.rb +28 -14
  127. data/lib/axlsx/workbook/worksheet/worksheet_comments.rb +4 -4
  128. data/lib/axlsx/workbook/worksheet/worksheet_drawing.rb +1 -1
  129. data/lib/axlsx/workbook/worksheet/worksheet_hyperlink.rb +3 -2
  130. data/lib/axlsx/workbook/worksheet/worksheet_hyperlinks.rb +2 -2
  131. data/lib/axlsx.rb +46 -30
  132. data/lib/caxlsx.rb +1 -1
  133. metadata +13 -52
@@ -13,7 +13,7 @@ module Axlsx
13
13
  # @option options [Integer] v
14
14
  def initialize(options = {})
15
15
  @format_code = "General"
16
- super(options)
16
+ super
17
17
  end
18
18
 
19
19
  # @see format_code
@@ -60,10 +60,16 @@ module Axlsx
60
60
 
61
61
  #
62
62
  # @see height
63
- def height=(v) Axlsx.validate_unsigned_int(v); @height = v; end
63
+ def height=(v)
64
+ Axlsx.validate_unsigned_int(v)
65
+ @height = v
66
+ end
64
67
 
65
68
  # @see width
66
- def width=(v) Axlsx.validate_unsigned_int(v); @width = v; end
69
+ def width=(v)
70
+ Axlsx.validate_unsigned_int(v)
71
+ @width = v
72
+ end
67
73
 
68
74
  # The index of this anchor in the drawing
69
75
  # @return [Integer]
@@ -69,7 +69,7 @@ module Axlsx
69
69
  options[:href] = v
70
70
  if hyperlink.is_a?(Hyperlink)
71
71
  options.each do |o|
72
- hyperlink.send("#{o[0]}=", o[1]) if hyperlink.respond_to? "#{o[0]}="
72
+ hyperlink.send(:"#{o[0]}=", o[1]) if hyperlink.respond_to? :"#{o[0]}="
73
73
  end
74
74
  else
75
75
  @hyperlink = Hyperlink.new(self, options)
@@ -80,7 +80,7 @@ module Axlsx
80
80
  def image_src=(v)
81
81
  Axlsx.validate_string(v)
82
82
  if remote?
83
- RegexValidator.validate('Pic.image_src', /\A#{URI::DEFAULT_PARSER.make_regexp}\z/, v)
83
+ RegexValidator.validate('Pic.image_src', /\A#{Axlsx.uri_parser.make_regexp}\z/, v)
84
84
  RestrictionValidator.validate 'Pic.image_src', ALLOWED_MIME_TYPES, MimeTypeUtils.get_mime_type_from_uri(v)
85
85
  else
86
86
  RestrictionValidator.validate 'Pic.image_src', ALLOWED_MIME_TYPES, MimeTypeUtils.get_mime_type(v)
@@ -91,13 +91,22 @@ module Axlsx
91
91
  end
92
92
 
93
93
  # @see name
94
- def name=(v) Axlsx.validate_string(v); @name = v; end
94
+ def name=(v)
95
+ Axlsx.validate_string(v)
96
+ @name = v
97
+ end
95
98
 
96
99
  # @see descr
97
- def descr=(v) Axlsx.validate_string(v); @descr = v; end
100
+ def descr=(v)
101
+ Axlsx.validate_string(v)
102
+ @descr = v
103
+ end
98
104
 
99
105
  # @see remote
100
- def remote=(v) Axlsx.validate_boolean(v); @remote = v; end
106
+ def remote=(v)
107
+ Axlsx.validate_boolean(v)
108
+ @remote = v
109
+ end
101
110
 
102
111
  def remote?
103
112
  remote == 1 || remote.to_s == 'true'
@@ -109,7 +118,7 @@ module Axlsx
109
118
  File.basename(image_src) unless remote? || image_src.nil?
110
119
  end
111
120
 
112
- # returns the extension of image_src without the preceeding '.'
121
+ # returns the extension of image_src without the preceding '.'
113
122
  # @return [String]
114
123
  def extname
115
124
  File.extname(image_src).delete('.') unless image_src.nil?
@@ -213,9 +222,9 @@ module Axlsx
213
222
  # Return correct xml relationship string portion
214
223
  def relationship_xml_portion
215
224
  if remote?
216
- (+'<a:blip xmlns:r ="' << XML_NS_R << '" r:link="' << relationship.Id << '">')
225
+ (+'<a:blip xmlns:r="' << XML_NS_R << '" r:link="' << relationship.Id << '">')
217
226
  else
218
- (+'<a:blip xmlns:r ="' << XML_NS_R << '" r:embed="' << relationship.Id << '">')
227
+ (+'<a:blip xmlns:r="' << XML_NS_R << '" r:embed="' << relationship.Id << '">')
219
228
  end
220
229
  end
221
230
 
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Axlsx
4
- # The Pie3DChart is a three dimentional piechart (who would have guessed?) that you can add to your worksheet.
4
+ # The Pie3DChart is a three dimensional pie chart (who would have guessed?) that you can add to your worksheet.
5
5
  # @see Worksheet#add_chart
6
6
  # @see Chart#add_series
7
7
  # @see README for an example
@@ -22,7 +22,7 @@ module Axlsx
22
22
  # @see View3D
23
23
  def initialize(frame, options = {})
24
24
  @vary_colors = true
25
- super(frame, options)
25
+ super
26
26
  @series_type = PieSeries
27
27
  @view_3D = View3D.new({ rot_x: 30, perspective: 30 }.merge(options))
28
28
  @d_lbls = nil
@@ -32,7 +32,7 @@ module Axlsx
32
32
  # @param [String] str
33
33
  # @return [String]
34
34
  def to_xml_string(str = +'')
35
- super(str) do
35
+ super do
36
36
  str << '<c:pie3DChart>'
37
37
  str << '<c:varyColors val="' << vary_colors.to_s << '"/>'
38
38
  @series.each { |ser| ser.to_xml_string(str) }
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Axlsx
4
+ # The PieChart is a pie chart that you can add to your worksheet.
5
+ # @see Worksheet#add_chart
6
+ # @see Chart#add_series
7
+ # @see README for an example
8
+ class PieChart < Chart
9
+ # Creates a new pie chart object
10
+ # @param [GraphicFrame] frame The workbook that owns this chart.
11
+ # @option options [Cell, String] title
12
+ # @option options [Boolean] show_legend
13
+ # @option options [Symbol] grouping
14
+ # @option options [String] gap_depth
15
+ # @see Chart
16
+ def initialize(frame, options = {})
17
+ @vary_colors = true
18
+ super
19
+ @series_type = PieSeries
20
+ @d_lbls = nil
21
+ end
22
+
23
+ # Serializes the object
24
+ # @param [String] str
25
+ # @return [String]
26
+ def to_xml_string(str = +'')
27
+ super do
28
+ str << '<c:pieChart>'
29
+ str << '<c:varyColors val="' << vary_colors.to_s << '"/>'
30
+ @series.each { |ser| ser.to_xml_string(str) }
31
+ d_lbls.to_xml_string(str) if @d_lbls
32
+ str << '</c:pieChart>'
33
+ end
34
+ end
35
+ end
36
+ end
@@ -30,22 +30,28 @@ module Axlsx
30
30
  def initialize(chart, options = {})
31
31
  @explosion = nil
32
32
  @colors = []
33
- super(chart, options)
33
+ super
34
34
  self.labels = AxDataSource.new(data: options[:labels]) unless options[:labels].nil?
35
35
  self.data = NumDataSource.new(options) unless options[:data].nil?
36
36
  end
37
37
 
38
38
  # @see colors
39
- def colors=(v) DataTypeValidator.validate "BarSeries.colors", [Array], v; @colors = v end
39
+ def colors=(v)
40
+ DataTypeValidator.validate "BarSeries.colors", [Array], v
41
+ @colors = v
42
+ end
40
43
 
41
44
  # @see explosion
42
- def explosion=(v) Axlsx.validate_unsigned_int(v); @explosion = v; end
45
+ def explosion=(v)
46
+ Axlsx.validate_unsigned_int(v)
47
+ @explosion = v
48
+ end
43
49
 
44
50
  # Serializes the object
45
51
  # @param [String] str
46
52
  # @return [String]
47
53
  def to_xml_string(str = +'')
48
- super(str) do
54
+ super do
49
55
  str << '<c:explosion val="' << @explosion.to_s << '"/>' unless @explosion.nil?
50
56
  colors.each_with_index do |c, index|
51
57
  str << '<c:dPt>'
@@ -63,9 +69,15 @@ module Axlsx
63
69
  private
64
70
 
65
71
  # assigns the data for this series
66
- def data=(v) DataTypeValidator.validate "Series.data", [NumDataSource], v; @data = v; end
72
+ def data=(v)
73
+ DataTypeValidator.validate "Series.data", [NumDataSource], v
74
+ @data = v
75
+ end
67
76
 
68
77
  # assigns the labels for this series
69
- def labels=(v) DataTypeValidator.validate "Series.labels", [AxDataSource], v; @labels = v; end
78
+ def labels=(v)
79
+ DataTypeValidator.validate "Series.labels", [AxDataSource], v
80
+ @labels = v
81
+ end
70
82
  end
71
83
  end
@@ -35,14 +35,28 @@ module Axlsx
35
35
  attr_reader :min
36
36
 
37
37
  # @see logBase
38
- def logBase=(v) DataTypeValidator.validate "Scaling.logBase", [Integer], v, ->(arg) { arg >= 2 && arg <= 1000 }; @logBase = v; end
38
+ def logBase=(v)
39
+ DataTypeValidator.validate "Scaling.logBase", [Integer], v, ->(arg) { arg >= 2 && arg <= 1000 }
40
+ @logBase = v
41
+ end
42
+
39
43
  # @see orientation
40
- def orientation=(v) RestrictionValidator.validate "Scaling.orientation", [:minMax, :maxMin], v; @orientation = v; end
44
+ def orientation=(v)
45
+ RestrictionValidator.validate "Scaling.orientation", [:minMax, :maxMin], v
46
+ @orientation = v
47
+ end
48
+
41
49
  # @see max
42
- def max=(v) DataTypeValidator.validate "Scaling.max", Float, v; @max = v; end
50
+ def max=(v)
51
+ DataTypeValidator.validate "Scaling.max", Float, v
52
+ @max = v
53
+ end
43
54
 
44
55
  # @see min
45
- def min=(v) DataTypeValidator.validate "Scaling.min", Float, v; @min = v; end
56
+ def min=(v)
57
+ DataTypeValidator.validate "Scaling.min", Float, v
58
+ @min = v
59
+ end
46
60
 
47
61
  # Serializes the object
48
62
  # @param [String] str
@@ -33,7 +33,7 @@ module Axlsx
33
33
  @vary_colors = 0
34
34
  @scatter_style = :lineMarker
35
35
 
36
- super(frame, options)
36
+ super
37
37
  @series_type = ScatterSeries
38
38
  @d_lbls = nil
39
39
  parse_options options
@@ -50,7 +50,7 @@ module Axlsx
50
50
  # @param [String] str
51
51
  # @return [String]
52
52
  def to_xml_string(str = +'')
53
- super(str) do
53
+ super do
54
54
  str << '<c:scatterChart>'
55
55
  str << '<c:scatterStyle val="' << scatter_style.to_s << '"/>'
56
56
  str << '<c:varyColors val="' << vary_colors.to_s << '"/>'
@@ -50,7 +50,7 @@ module Axlsx
50
50
  @show_marker = [:lineMarker, :marker, :smoothMarker].include?(chart.scatter_style)
51
51
  @marker_symbol = :default
52
52
 
53
- super(chart, options)
53
+ super
54
54
  @xData = AxDataSource.new(tag_name: :xVal, data: options[:xData]) unless options[:xData].nil?
55
55
  @yData = NumDataSource.new({ tag_name: :yVal, data: options[:yData] }) unless options[:yData].nil?
56
56
  end
@@ -81,7 +81,7 @@ module Axlsx
81
81
  # @param [String] str
82
82
  # @return [String]
83
83
  def to_xml_string(str = +'')
84
- super(str) do
84
+ super do
85
85
  # needs to override the super color here to push in ln/and something else!
86
86
  if color
87
87
  str << '<c:spPr><a:solidFill>'
@@ -3,7 +3,7 @@
3
3
  module Axlsx
4
4
  # A SerAxis object defines a series axis
5
5
  class SerAxis < Axis
6
- # The number of tick lables to skip between labels
6
+ # The number of tick labels to skip between labels
7
7
  # @return [Integer]
8
8
  attr_reader :tick_lbl_skip
9
9
  alias :tickLblSkip :tick_lbl_skip
@@ -18,15 +18,21 @@ module Axlsx
18
18
  # @option options [Integer] tick_mark_skip
19
19
  def initialize(options = {})
20
20
  @tick_lbl_skip, @tick_mark_skip = 1, 1
21
- super(options)
21
+ super
22
22
  end
23
23
 
24
24
  # @see tickLblSkip
25
- def tick_lbl_skip=(v) Axlsx.validate_unsigned_int(v); @tick_lbl_skip = v; end
25
+ def tick_lbl_skip=(v)
26
+ Axlsx.validate_unsigned_int(v)
27
+ @tick_lbl_skip = v
28
+ end
26
29
  alias :tickLblSkip= :tick_lbl_skip=
27
30
 
28
31
  # @see tickMarkSkip
29
- def tick_mark_skip=(v) Axlsx.validate_unsigned_int(v); @tick_mark_skip = v; end
32
+ def tick_mark_skip=(v)
33
+ Axlsx.validate_unsigned_int(v)
34
+ @tick_mark_skip = v
35
+ end
30
36
  alias :tickMarkSkip= :tick_mark_skip=
31
37
 
32
38
  # Serializes the object
@@ -34,7 +40,7 @@ module Axlsx
34
40
  # @return [String]
35
41
  def to_xml_string(str = +'')
36
42
  str << '<c:serAx>'
37
- super(str)
43
+ super
38
44
  str << '<c:tickLblSkip val="' << @tick_lbl_skip.to_s << '"/>' unless @tick_lbl_skip.nil?
39
45
  str << '<c:tickMarkSkip val="' << @tick_mark_skip.to_s << '"/>' unless @tick_mark_skip.nil?
40
46
  str << '</c:serAx>'
@@ -40,7 +40,10 @@ module Axlsx
40
40
  end
41
41
 
42
42
  # @see order
43
- def order=(v) Axlsx.validate_unsigned_int(v); @order = v; end
43
+ def order=(v)
44
+ Axlsx.validate_unsigned_int(v)
45
+ @order = v
46
+ end
44
47
 
45
48
  # @see title
46
49
  def title=(v)
@@ -52,7 +55,10 @@ module Axlsx
52
55
  private
53
56
 
54
57
  # assigns the chart for this series
55
- def chart=(v) DataTypeValidator.validate "Series.chart", Chart, v; @chart = v; end
58
+ def chart=(v)
59
+ DataTypeValidator.validate "Series.chart", Chart, v
60
+ @chart = v
61
+ end
56
62
 
57
63
  # Serializes the object
58
64
  # @param [String] str
@@ -39,7 +39,7 @@ module Axlsx
39
39
  parse_options options
40
40
 
41
41
  # bit of a hack to work around the fact that the coords for start at and end at
42
- # are passed in as an array when specified in intialization options - however
42
+ # are passed in as an array when specified in initialization options - however
43
43
  start_at(*options[:start_at]) if options[:start_at]
44
44
  end_at(*options[:end_at]) if options[:end_at]
45
45
  end
@@ -13,7 +13,7 @@ module Axlsx
13
13
  # @option options [Symbol] crosses_between
14
14
  def initialize(options = {})
15
15
  self.cross_between = :between
16
- super(options)
16
+ super
17
17
  end
18
18
 
19
19
  # @see cross_between
@@ -28,7 +28,7 @@ module Axlsx
28
28
  # @return [String]
29
29
  def to_xml_string(str = +'')
30
30
  str << '<c:valAx>'
31
- super(str)
31
+ super
32
32
  str << '<c:crossBetween val="' << @cross_between.to_s << '"/>'
33
33
  str << '</c:valAx>'
34
34
  end
@@ -78,11 +78,17 @@ module Axlsx
78
78
  alias :rotY= :rot_y=
79
79
 
80
80
  # @see depth_percent
81
- def depth_percent=(v) RegexValidator.validate "#{self.class}.depth_percent", DEPTH_PERCENT_REGEX, v; @depth_percent = v; end
81
+ def depth_percent=(v)
82
+ RegexValidator.validate "#{self.class}.depth_percent", DEPTH_PERCENT_REGEX, v
83
+ @depth_percent = v
84
+ end
82
85
  alias :depthPercent= :depth_percent=
83
86
 
84
87
  # @see r_ang_ax
85
- def r_ang_ax=(v) Axlsx.validate_boolean(v); @r_ang_ax = v; end
88
+ def r_ang_ax=(v)
89
+ Axlsx.validate_boolean(v)
90
+ @r_ang_ax = v
91
+ end
86
92
  alias :rAngAx= :r_ang_ax=
87
93
 
88
94
  # @see perspective
@@ -56,7 +56,7 @@ module Axlsx
56
56
  <x:AutoFill>False</x:AutoFill>
57
57
  <x:Row>#{row}</x:Row>
58
58
  <x:Column>#{column}</x:Column>
59
- #{@visible ? '<x:Visible/>' : ''}
59
+ #{'<x:Visible/>' if @visible}
60
60
  </x:ClientData>
61
61
  </v:shape>
62
62
  XML
data/lib/axlsx/package.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Axlsx
4
- # Package is responsible for managing all the bits and peices that Open Office XML requires to make a valid
4
+ # Package is responsible for managing all the bits and pieces that Open Office XML requires to make a valid
5
5
  # xlsx document including validation and serialization.
6
6
  class Package
7
7
  include Axlsx::OptionsParser
@@ -55,11 +55,11 @@ module Axlsx
55
55
  # @raise ArgumentError if workbook parameter is not a Workbook instance.
56
56
  # @note As there are multiple ways to instantiate a workbook for the package,
57
57
  # here are a few examples:
58
- # # assign directly during package instanciation
58
+ # # assign directly during package instantiation
59
59
  # wb = Package.new(:workbook => Workbook.new).workbook
60
60
  #
61
61
  # # get a fresh workbook automatically from the package
62
- # wb = Pacakge.new().workbook
62
+ # wb = Package.new().workbook
63
63
  # # # set the workbook after creating the package
64
64
  # wb = Package.new().workbook = Workbook.new
65
65
  def workbook
@@ -69,7 +69,10 @@ module Axlsx
69
69
  end
70
70
 
71
71
  # @see workbook
72
- def workbook=(workbook) DataTypeValidator.validate :Package_workbook, Workbook, workbook; @workbook = workbook; end
72
+ def workbook=(workbook)
73
+ DataTypeValidator.validate :Package_workbook, Workbook, workbook
74
+ @workbook = workbook
75
+ end
73
76
 
74
77
  # Serialize your workbook to disk as an xlsx document.
75
78
  #
@@ -79,6 +82,8 @@ module Axlsx
79
82
  # @option options [String] :zip_command When `nil`, `#serialize` with RubyZip to
80
83
  # zip the XLSX file contents. When a String, the provided zip command (e.g.,
81
84
  # "zip") is used to zip the file contents (may be faster for large files)
85
+ # @option options [String] :password When specified, the serialized packaged will be
86
+ # encrypted with the password. Requires ooxml_crypt gem.
82
87
  # @return [Boolean] False if confirm_valid and validation errors exist. True if the package was serialized
83
88
  # @note A tremendous amount of effort has gone into ensuring that you cannot create invalid xlsx documents.
84
89
  # options[:confirm_valid] should be used in the rare case that you cannot open the serialized file.
@@ -105,7 +110,7 @@ module Axlsx
105
110
  workbook.apply_styles
106
111
  end
107
112
 
108
- confirm_valid, zip_command = parse_serialize_options(options, secondary_options)
113
+ confirm_valid, zip_command, password = parse_serialize_options(options, secondary_options)
109
114
  return false unless !confirm_valid || validate.empty?
110
115
 
111
116
  zip_provider = if zip_command
@@ -117,15 +122,31 @@ module Axlsx
117
122
  zip_provider.open(output) do |zip|
118
123
  write_parts(zip)
119
124
  end
125
+
126
+ if password && !password.empty?
127
+ require_ooxml_crypt!
128
+ OoxmlCrypt.encrypt_file(output, password, output)
129
+ end
130
+
120
131
  true
121
132
  ensure
122
133
  Relationship.clear_ids_cache
123
134
  end
124
135
 
125
136
  # Serialize your workbook to a StringIO instance
126
- # @param [Boolean] confirm_valid Validate the package prior to serialization.
127
- # @return [StringIO|Boolean] False if confirm_valid and validation errors exist. rewound string IO if not.
128
- def to_stream(confirm_valid = false)
137
+ # @param [Boolean] old_confirm_valid (Deprecated) Validate the package prior to serialization.
138
+ # Use :confirm_valid keyword arg instead.
139
+ # @option kwargs [Boolean] :confirm_valid Validate the package prior to serialization.
140
+ # @option kwargs [String] :password When specified, the serialized packaged will be
141
+ # encrypted with the password. Requires ooxml_crypt gem.
142
+ # @return [StringIO|Boolean] False if confirm_valid and validation errors exist. Rewound string IO if not.
143
+ def to_stream(old_confirm_valid = nil, confirm_valid: false, password: nil)
144
+ unless old_confirm_valid.nil?
145
+ warn "[DEPRECATION] Axlsx::Package#to_stream with confirm_valid as a non-keyword arg is deprecated. " \
146
+ "Use keyword arg instead e.g., package.to_stream(confirm_valid: false)"
147
+ confirm_valid ||= old_confirm_valid
148
+ end
149
+
129
150
  unless workbook.styles_applied
130
151
  workbook.apply_styles
131
152
  end
@@ -137,6 +158,12 @@ module Axlsx
137
158
  write_parts(zip)
138
159
  end
139
160
  stream.rewind
161
+
162
+ if password && !password.empty?
163
+ require_ooxml_crypt!
164
+ stream = StringIO.new(OoxmlCrypt.encrypt(stream.read, password))
165
+ end
166
+
140
167
  stream
141
168
  ensure
142
169
  Relationship.clear_ids_cache
@@ -144,7 +171,7 @@ module Axlsx
144
171
 
145
172
  # Encrypt the package into a CFB using the password provided
146
173
  # This is not ready yet
147
- def encrypt(file_name, password)
174
+ def encrypt(file_name, password) # rubocop:disable Naming/PredicateMethod
148
175
  false
149
176
  # moc = MsOffCrypto.new(file_name, password)
150
177
  # moc.save
@@ -204,11 +231,12 @@ module Axlsx
204
231
  # Note: {Core#created} also defaults to the current time – so to generate identical axlsx packages you have
205
232
  # to set this explicitly, too (eg. with `Package.new(created_at: Time.local(2013, 1, 1))`).
206
233
  #
207
- # @param part A hash describing a part of this pacakge (see {#parts})
234
+ # @param part A hash describing a part of this package (see {#parts})
208
235
  # @return [Zip::Entry]
209
236
  def zip_entry_for_part(part)
210
237
  timestamp = Zip::DOSTime.at(@core.created.to_i)
211
- Zip::Entry.new("", part[:entry], "", "", 0, 0, Zip::Entry::DEFLATED, 0, timestamp)
238
+
239
+ Zip::Entry.new("", part[:entry], time: timestamp)
212
240
  end
213
241
 
214
242
  # The parts of a package
@@ -217,6 +245,7 @@ module Axlsx
217
245
  def parts
218
246
  parts = [
219
247
  { entry: "xl/#{STYLES_PN}", doc: workbook.styles, schema: SML_XSD },
248
+ { entry: "xl/#{THEME_PN}", doc: workbook.theme, schema: THEME_XSD },
220
249
  { entry: CORE_PN, doc: @core, schema: CORE_XSD },
221
250
  { entry: APP_PN, doc: @app, schema: APP_XSD },
222
251
  { entry: WORKBOOK_RELS_PN, doc: workbook.relationships, schema: RELS_XSD },
@@ -270,7 +299,7 @@ module Axlsx
270
299
  ]
271
300
  end
272
301
 
273
- # Performs xsd validation for a signle document
302
+ # Performs xsd validation for a single document
274
303
  #
275
304
  # @param [String] schema path to the xsd schema to be used in validation.
276
305
  # @param [String] doc The xml text to be validated
@@ -279,11 +308,8 @@ module Axlsx
279
308
  def validate_single_doc(schema, doc)
280
309
  schema = Nokogiri::XML::Schema(File.open(schema))
281
310
  doc = Nokogiri::XML(doc)
282
- errors = []
283
- schema.validate(doc).each do |error|
284
- errors << error
285
- end
286
- errors
311
+
312
+ schema.validate(doc)
287
313
  end
288
314
 
289
315
  # Appends override objects for drawings, charts, and sheets as they exist in your workbook to the default content types.
@@ -356,6 +382,7 @@ module Axlsx
356
382
  c_types << Override.new(PartName: "/#{APP_PN}", ContentType: APP_CT)
357
383
  c_types << Override.new(PartName: "/#{CORE_PN}", ContentType: CORE_CT)
358
384
  c_types << Override.new(PartName: "/xl/#{STYLES_PN}", ContentType: STYLES_CT)
385
+ c_types << Override.new(PartName: "/xl/#{THEME_PN}", ContentType: THEME_CT)
359
386
  c_types << Axlsx::Override.new(PartName: "/#{WORKBOOK_PN}", ContentType: WORKBOOK_CT)
360
387
  c_types.lock
361
388
  c_types
@@ -374,8 +401,8 @@ module Axlsx
374
401
  end
375
402
 
376
403
  # Parse the arguments of `#serialize`
377
- # @return [Boolean, (String or nil)] Returns an array where the first value is
378
- # `confirm_valid` and the second is the `zip_command`.
404
+ # @return [Boolean, (String or nil), (String or nil)] Returns a 3-tuple where values are
405
+ # `confirm_valid`, `zip_command`, and `password`.
379
406
  # @private
380
407
  def parse_serialize_options(options, secondary_options)
381
408
  if secondary_options
@@ -384,17 +411,23 @@ module Axlsx
384
411
  end
385
412
  if options.is_a?(Hash)
386
413
  options.merge!(secondary_options || {})
387
- invalid_keys = options.keys - [:confirm_valid, :zip_command]
414
+ invalid_keys = options.keys - [:confirm_valid, :zip_command, :password]
388
415
  if invalid_keys.any?
389
416
  raise ArgumentError, "Invalid keyword arguments: #{invalid_keys}"
390
417
  end
391
418
 
392
- [options.fetch(:confirm_valid, false), options.fetch(:zip_command, nil)]
419
+ [options.fetch(:confirm_valid, false), options.fetch(:zip_command, nil), options.fetch(:password, nil)]
393
420
  else
394
421
  warn "[DEPRECATION] Axlsx::Package#serialize with confirm_valid as a boolean is deprecated. " \
395
422
  "Use keyword args instead e.g., package.serialize(output, confirm_valid: false)"
396
423
  parse_serialize_options((secondary_options || {}).merge(confirm_valid: options), nil)
397
424
  end
398
425
  end
426
+
427
+ def require_ooxml_crypt!
428
+ return if defined?(OoxmlCrypt)
429
+
430
+ raise 'Axlsx encryption requires ooxml_crypt gem'
431
+ end
399
432
  end
400
433
  end
@@ -15,7 +15,7 @@ module Axlsx
15
15
  #
16
16
  # This should be called before serializing a package (see {Package#serialize} and
17
17
  # {Package#to_stream}) to make sure that serialization is idempotent (i.e.
18
- # Relationship instances are generated with the same IDs everytime the package
18
+ # Relationship instances are generated with the same IDs every time the package
19
19
  # is serialized).
20
20
  def initialize_ids_cache
21
21
  Thread.current[:axlsx_relationship_ids_cache] = {}
@@ -92,12 +92,22 @@ module Axlsx
92
92
  end
93
93
 
94
94
  # @see Target
95
- def Target=(v) Axlsx.validate_string v; @Target = v end
95
+ def Target=(v)
96
+ Axlsx.validate_string v
97
+ @Target = v
98
+ end
99
+
96
100
  # @see Type
97
- def Type=(v) Axlsx.validate_relationship_type v; @Type = v end
101
+ def Type=(v)
102
+ Axlsx.validate_relationship_type v
103
+ @Type = v
104
+ end
98
105
 
99
106
  # @see TargetMode
100
- def TargetMode=(v) RestrictionValidator.validate 'Relationship.TargetMode', [:External, :Internal], v; @TargetMode = v; end
107
+ def TargetMode=(v)
108
+ RestrictionValidator.validate 'Relationship.TargetMode', [:External, :Internal], v
109
+ @TargetMode = v
110
+ end
101
111
 
102
112
  # serialize relationship
103
113
  # @param [String] str
@@ -106,7 +116,7 @@ module Axlsx
106
116
  h = Axlsx.instance_values_for(self).reject { |k, _| k == "source_obj" }
107
117
  str << '<Relationship '
108
118
  h.each_with_index do |key_value, index|
109
- str << ' ' unless index.zero?
119
+ str << ' ' unless index == 0
110
120
  str << key_value.first.to_s << '="' << Axlsx.coder.encode(key_value.last.to_s) << '"'
111
121
  end
112
122
  str << '/>'
@@ -1,14 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Axlsx
4
- require 'axlsx/rels/relationship'
4
+ require_relative 'relationship'
5
5
 
6
6
  # Relationships are a collection of Relations that define how package parts are related.
7
- # @note The package automatically manages releationships.
7
+ # @note The package automatically manages relationships.
8
8
  class Relationships < SimpleTypedList
9
9
  # Creates a new Relationships collection based on SimpleTypedList
10
10
  def initialize
11
- super Relationship
11
+ super(Relationship)
12
12
  end
13
13
 
14
14
  # The relationship instance for the given source object, or nil if none exists.