caxlsx 3.4.1 → 4.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (153) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +24 -1
  3. data/README.md +9 -11
  4. data/Rakefile +7 -5
  5. data/examples/generate.rb +3 -1
  6. data/lib/axlsx/content_type/abstract_content_type.rb +12 -4
  7. data/lib/axlsx/content_type/content_type.rb +8 -6
  8. data/lib/axlsx/content_type/default.rb +7 -2
  9. data/lib/axlsx/content_type/override.rb +7 -2
  10. data/lib/axlsx/doc_props/app.rb +95 -26
  11. data/lib/axlsx/doc_props/core.rb +8 -6
  12. data/lib/axlsx/drawing/area_chart.rb +10 -8
  13. data/lib/axlsx/drawing/area_series.rb +20 -12
  14. data/lib/axlsx/drawing/ax_data_source.rb +2 -0
  15. data/lib/axlsx/drawing/axes.rb +6 -4
  16. data/lib/axlsx/drawing/axis.rb +42 -22
  17. data/lib/axlsx/drawing/bar_3D_chart.rb +14 -12
  18. data/lib/axlsx/drawing/bar_chart.rb +13 -11
  19. data/lib/axlsx/drawing/bar_series.rb +20 -9
  20. data/lib/axlsx/drawing/bubble_chart.rb +6 -4
  21. data/lib/axlsx/drawing/bubble_series.rb +8 -6
  22. data/lib/axlsx/drawing/cat_axis.rb +29 -12
  23. data/lib/axlsx/drawing/chart.rb +46 -20
  24. data/lib/axlsx/drawing/d_lbls.rb +10 -8
  25. data/lib/axlsx/drawing/drawing.rb +59 -56
  26. data/lib/axlsx/drawing/graphic_frame.rb +6 -4
  27. data/lib/axlsx/drawing/hyperlink.rb +19 -8
  28. data/lib/axlsx/drawing/line_3D_chart.rb +7 -5
  29. data/lib/axlsx/drawing/line_chart.rb +10 -8
  30. data/lib/axlsx/drawing/line_series.rb +20 -12
  31. data/lib/axlsx/drawing/marker.rb +24 -7
  32. data/lib/axlsx/drawing/num_data.rb +9 -7
  33. data/lib/axlsx/drawing/num_data_source.rb +9 -7
  34. data/lib/axlsx/drawing/num_val.rb +7 -5
  35. data/lib/axlsx/drawing/one_cell_anchor.rb +13 -5
  36. data/lib/axlsx/drawing/pic.rb +26 -15
  37. data/lib/axlsx/drawing/picture_locking.rb +3 -1
  38. data/lib/axlsx/drawing/pie_3D_chart.rb +6 -4
  39. data/lib/axlsx/drawing/pie_chart.rb +36 -0
  40. data/lib/axlsx/drawing/pie_series.rb +23 -9
  41. data/lib/axlsx/drawing/scaling.rb +25 -9
  42. data/lib/axlsx/drawing/scatter_chart.rb +7 -5
  43. data/lib/axlsx/drawing/scatter_series.rb +14 -12
  44. data/lib/axlsx/drawing/ser_axis.rb +13 -5
  45. data/lib/axlsx/drawing/series.rb +13 -5
  46. data/lib/axlsx/drawing/series_title.rb +6 -4
  47. data/lib/axlsx/drawing/str_data.rb +7 -5
  48. data/lib/axlsx/drawing/str_val.rb +6 -4
  49. data/lib/axlsx/drawing/title.rb +13 -14
  50. data/lib/axlsx/drawing/two_cell_anchor.rb +4 -2
  51. data/lib/axlsx/drawing/val_axis.rb +4 -2
  52. data/lib/axlsx/drawing/view_3D.rb +16 -8
  53. data/lib/axlsx/drawing/vml_drawing.rb +18 -16
  54. data/lib/axlsx/drawing/vml_shape.rb +24 -22
  55. data/lib/axlsx/package.rb +73 -67
  56. data/lib/axlsx/rels/relationship.rb +21 -6
  57. data/lib/axlsx/rels/relationships.rb +6 -4
  58. data/lib/axlsx/stylesheet/border.rb +15 -4
  59. data/lib/axlsx/stylesheet/border_pr.rb +19 -6
  60. data/lib/axlsx/stylesheet/cell_alignment.rb +41 -10
  61. data/lib/axlsx/stylesheet/cell_protection.rb +12 -3
  62. data/lib/axlsx/stylesheet/cell_style.rb +33 -8
  63. data/lib/axlsx/stylesheet/color.rb +15 -7
  64. data/lib/axlsx/stylesheet/dxf.rb +34 -9
  65. data/lib/axlsx/stylesheet/fill.rb +7 -2
  66. data/lib/axlsx/stylesheet/font.rb +65 -17
  67. data/lib/axlsx/stylesheet/gradient_fill.rb +12 -4
  68. data/lib/axlsx/stylesheet/gradient_stop.rb +14 -5
  69. data/lib/axlsx/stylesheet/num_fmt.rb +14 -10
  70. data/lib/axlsx/stylesheet/pattern_fill.rb +18 -5
  71. data/lib/axlsx/stylesheet/styles.rb +124 -82
  72. data/lib/axlsx/stylesheet/table_style.rb +19 -6
  73. data/lib/axlsx/stylesheet/table_style_element.rb +15 -4
  74. data/lib/axlsx/stylesheet/table_styles.rb +14 -5
  75. data/lib/axlsx/stylesheet/xf.rb +73 -18
  76. data/lib/axlsx/util/accessors.rb +10 -6
  77. data/lib/axlsx/util/buffered_zip_output_stream.rb +60 -0
  78. data/lib/axlsx/util/constants.rb +117 -104
  79. data/lib/axlsx/util/mime_type_utils.rb +3 -5
  80. data/lib/axlsx/util/options_parser.rb +3 -1
  81. data/lib/axlsx/util/serialized_attributes.rb +42 -17
  82. data/lib/axlsx/util/simple_typed_list.rb +47 -47
  83. data/lib/axlsx/util/storage.rb +11 -10
  84. data/lib/axlsx/util/validators.rb +101 -41
  85. data/lib/axlsx/util/zip_command.rb +10 -10
  86. data/lib/axlsx/version.rb +3 -1
  87. data/lib/axlsx/workbook/defined_name.rb +6 -4
  88. data/lib/axlsx/workbook/defined_names.rb +4 -2
  89. data/lib/axlsx/workbook/shared_strings_table.rb +8 -6
  90. data/lib/axlsx/workbook/workbook.rb +94 -79
  91. data/lib/axlsx/workbook/workbook_view.rb +3 -1
  92. data/lib/axlsx/workbook/workbook_views.rb +4 -2
  93. data/lib/axlsx/workbook/worksheet/auto_filter/auto_filter.rb +65 -8
  94. data/lib/axlsx/workbook/worksheet/auto_filter/filter_column.rb +11 -5
  95. data/lib/axlsx/workbook/worksheet/auto_filter/filters.rb +11 -7
  96. data/lib/axlsx/workbook/worksheet/auto_filter/sort_condition.rb +51 -0
  97. data/lib/axlsx/workbook/worksheet/auto_filter/sort_state.rb +56 -0
  98. data/lib/axlsx/workbook/worksheet/border_creator.rb +5 -3
  99. data/lib/axlsx/workbook/worksheet/break.rb +3 -1
  100. data/lib/axlsx/workbook/worksheet/cell.rb +83 -64
  101. data/lib/axlsx/workbook/worksheet/cell_serializer.rb +31 -27
  102. data/lib/axlsx/workbook/worksheet/cfvo.rb +11 -3
  103. data/lib/axlsx/workbook/worksheet/cfvos.rb +3 -1
  104. data/lib/axlsx/workbook/worksheet/col.rb +5 -3
  105. data/lib/axlsx/workbook/worksheet/col_breaks.rb +6 -4
  106. data/lib/axlsx/workbook/worksheet/color_scale.rb +12 -10
  107. data/lib/axlsx/workbook/worksheet/cols.rb +4 -2
  108. data/lib/axlsx/workbook/worksheet/comment.rb +8 -6
  109. data/lib/axlsx/workbook/worksheet/comments.rb +6 -4
  110. data/lib/axlsx/workbook/worksheet/conditional_formatting.rb +16 -5
  111. data/lib/axlsx/workbook/worksheet/conditional_formatting_rule.rb +73 -16
  112. data/lib/axlsx/workbook/worksheet/conditional_formattings.rb +4 -2
  113. data/lib/axlsx/workbook/worksheet/data_bar.rb +14 -13
  114. data/lib/axlsx/workbook/worksheet/data_validation.rb +69 -28
  115. data/lib/axlsx/workbook/worksheet/data_validations.rb +4 -2
  116. data/lib/axlsx/workbook/worksheet/date_time_converter.rb +7 -5
  117. data/lib/axlsx/workbook/worksheet/dimension.rb +4 -2
  118. data/lib/axlsx/workbook/worksheet/header_footer.rb +4 -2
  119. data/lib/axlsx/workbook/worksheet/icon_set.rb +38 -9
  120. data/lib/axlsx/workbook/worksheet/merged_cells.rb +6 -6
  121. data/lib/axlsx/workbook/worksheet/outline_pr.rb +6 -2
  122. data/lib/axlsx/workbook/worksheet/page_margins.rb +39 -11
  123. data/lib/axlsx/workbook/worksheet/page_set_up_pr.rb +7 -4
  124. data/lib/axlsx/workbook/worksheet/page_setup.rb +34 -9
  125. data/lib/axlsx/workbook/worksheet/pane.rb +17 -9
  126. data/lib/axlsx/workbook/worksheet/pivot_table.rb +20 -19
  127. data/lib/axlsx/workbook/worksheet/pivot_table_cache_definition.rb +8 -6
  128. data/lib/axlsx/workbook/worksheet/pivot_tables.rb +3 -1
  129. data/lib/axlsx/workbook/worksheet/print_options.rb +3 -1
  130. data/lib/axlsx/workbook/worksheet/protected_range.rb +3 -1
  131. data/lib/axlsx/workbook/worksheet/protected_ranges.rb +6 -4
  132. data/lib/axlsx/workbook/worksheet/rich_text.rb +3 -1
  133. data/lib/axlsx/workbook/worksheet/rich_text_run.rb +46 -24
  134. data/lib/axlsx/workbook/worksheet/row.rb +11 -9
  135. data/lib/axlsx/workbook/worksheet/row_breaks.rb +7 -5
  136. data/lib/axlsx/workbook/worksheet/selection.rb +15 -7
  137. data/lib/axlsx/workbook/worksheet/sheet_calc_pr.rb +6 -2
  138. data/lib/axlsx/workbook/worksheet/sheet_data.rb +3 -1
  139. data/lib/axlsx/workbook/worksheet/sheet_format_pr.rb +6 -2
  140. data/lib/axlsx/workbook/worksheet/sheet_pr.rb +8 -4
  141. data/lib/axlsx/workbook/worksheet/sheet_protection.rb +11 -9
  142. data/lib/axlsx/workbook/worksheet/sheet_view.rb +38 -15
  143. data/lib/axlsx/workbook/worksheet/table.rb +9 -7
  144. data/lib/axlsx/workbook/worksheet/table_style_info.rb +4 -2
  145. data/lib/axlsx/workbook/worksheet/tables.rb +4 -2
  146. data/lib/axlsx/workbook/worksheet/worksheet.rb +56 -39
  147. data/lib/axlsx/workbook/worksheet/worksheet_comments.rb +4 -2
  148. data/lib/axlsx/workbook/worksheet/worksheet_drawing.rb +8 -2
  149. data/lib/axlsx/workbook/worksheet/worksheet_hyperlink.rb +7 -5
  150. data/lib/axlsx/workbook/worksheet/worksheet_hyperlinks.rb +5 -3
  151. data/lib/axlsx.rb +56 -42
  152. data/lib/caxlsx.rb +3 -1
  153. metadata +39 -71
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Axlsx
2
4
  # This class specifies data for a particular data point.
3
5
  class StrVal
@@ -21,10 +23,10 @@ module Axlsx
21
23
  end
22
24
 
23
25
  # serialize the object
24
- def to_xml_string(idx, str = "")
25
- Axlsx::validate_unsigned_int(idx)
26
- if !v.to_s.empty?
27
- str << ('<c:pt idx="' << idx.to_s << '"><c:v>' << ::CGI.escapeHTML(v.to_s) << '</c:v></c:pt>')
26
+ def to_xml_string(idx, str = +'')
27
+ Axlsx.validate_unsigned_int(idx)
28
+ unless v.to_s.empty?
29
+ str << '<c:pt idx="' << idx.to_s << '"><c:v>' << ::CGI.escapeHTML(v.to_s) << '</c:v></c:pt>'
28
30
  end
29
31
  end
30
32
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Axlsx
2
4
  # A Title stores information about the title of a chart
3
5
  class Title
@@ -18,11 +20,11 @@ module Axlsx
18
20
  def initialize(title = "", title_size = "")
19
21
  self.cell = title if title.is_a?(Cell)
20
22
  self.text = title.to_s unless title.is_a?(Cell)
21
- if title_size.to_s.empty?
22
- self.text_size = "1600"
23
- else
24
- self.text_size = title_size.to_s
25
- end
23
+ self.text_size = if title_size.to_s.empty?
24
+ "1600"
25
+ else
26
+ title_size.to_s
27
+ end
26
28
  end
27
29
 
28
30
  # @see text
@@ -30,7 +32,6 @@ module Axlsx
30
32
  DataTypeValidator.validate 'Title.text', String, v
31
33
  @text = v
32
34
  @cell = nil
33
- v
34
35
  end
35
36
 
36
37
  # @see text_size
@@ -38,7 +39,6 @@ module Axlsx
38
39
  DataTypeValidator.validate 'Title.text_size', String, v
39
40
  @text_size = v
40
41
  @cell = nil
41
- v
42
42
  end
43
43
 
44
44
  # @see cell
@@ -46,7 +46,6 @@ module Axlsx
46
46
  DataTypeValidator.validate 'Title.text', Cell, v
47
47
  @cell = v
48
48
  @text = v.value.to_s
49
- v
50
49
  end
51
50
 
52
51
  # Check if the title is empty.
@@ -67,18 +66,18 @@ module Axlsx
67
66
  # Serializes the object
68
67
  # @param [String] str
69
68
  # @return [String]
70
- def to_xml_string(str = '')
69
+ def to_xml_string(str = +'')
71
70
  str << '<c:title>'
72
71
  unless empty?
73
- clean_value = Axlsx::trust_input ? @text.to_s : ::CGI.escapeHTML(Axlsx::sanitize(@text.to_s))
72
+ clean_value = Axlsx.trust_input ? @text.to_s : ::CGI.escapeHTML(Axlsx.sanitize(@text.to_s))
74
73
  str << '<c:tx>'
75
74
  if @cell.is_a?(Cell)
76
75
  str << '<c:strRef>'
77
- str << ('<c:f>' << Axlsx::cell_range([@cell]) << '</c:f>')
76
+ str << '<c:f>' << Axlsx.cell_range([@cell]) << '</c:f>'
78
77
  str << '<c:strCache>'
79
78
  str << '<c:ptCount val="1"/>'
80
79
  str << '<c:pt idx="0">'
81
- str << ('<c:v>' << clean_value << '</c:v>')
80
+ str << '<c:v>' << clean_value << '</c:v>'
82
81
  str << '</c:pt>'
83
82
  str << '</c:strCache>'
84
83
  str << '</c:strRef>'
@@ -88,8 +87,8 @@ module Axlsx
88
87
  str << '<a:lstStyle/>'
89
88
  str << '<a:p>'
90
89
  str << '<a:r>'
91
- str << ('<a:rPr sz="' << @text_size.to_s << '"/>')
92
- str << ('<a:t>' << clean_value << '</a:t>')
90
+ str << '<a:rPr sz="' << @text_size.to_s << '"/>'
91
+ str << '<a:t>' << clean_value << '</a:t>'
93
92
  str << '</a:r>'
94
93
  str << '</a:p>'
95
94
  str << '</c:rich>'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Axlsx
2
4
  # This class details the anchor points for drawings.
3
5
  # @note The recommended way to manage drawings and charts is Worksheet#add_chart. Anchors are specified by the :start_at and :end_at options to that method.
@@ -33,7 +35,7 @@ module Axlsx
33
35
  def initialize(drawing, options = {})
34
36
  @drawing = drawing
35
37
  drawing.anchors << self
36
- @from, @to = Marker.new, Marker.new(:col => 5, :row => 10)
38
+ @from, @to = Marker.new, Marker.new(col: 5, row: 10)
37
39
  parse_options options
38
40
 
39
41
  # bit of a hack to work around the fact that the coords for start at and end at
@@ -79,7 +81,7 @@ module Axlsx
79
81
  # Serializes the object
80
82
  # @param [String] str
81
83
  # @return [String]
82
- def to_xml_string(str = '')
84
+ def to_xml_string(str = +'')
83
85
  str << '<xdr:twoCellAnchor>'
84
86
  str << '<xdr:from>'
85
87
  from.to_xml_string str
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Axlsx
2
4
  # the ValAxis class defines a chart value axis.
3
5
  class ValAxis < Axis
@@ -24,10 +26,10 @@ module Axlsx
24
26
  # Serializes the object
25
27
  # @param [String] str
26
28
  # @return [String]
27
- def to_xml_string(str = '')
29
+ def to_xml_string(str = +'')
28
30
  str << '<c:valAx>'
29
31
  super(str)
30
- str << ('<c:crossBetween val="' << @cross_between.to_s << '"/>')
32
+ str << '<c:crossBetween val="' << @cross_between.to_s << '"/>'
31
33
  str << '</c:valAx>'
32
34
  end
33
35
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Axlsx
2
4
  # 3D attributes for a chart.
3
5
  class View3D
@@ -16,10 +18,10 @@ module Axlsx
16
18
  end
17
19
 
18
20
  # Validation for hPercent
19
- H_PERCENT_REGEX = /0*(([5-9])|([1-9][0-9])|([1-4][0-9][0-9])|500)/
21
+ H_PERCENT_REGEX = /0*(([5-9])|([1-9][0-9])|([1-4][0-9][0-9])|500)/.freeze
20
22
 
21
23
  # validation for depthPercent
22
- DEPTH_PERCENT_REGEX = /0*(([2-9][0-9])|([1-9][0-9][0-9])|(1[0-9][0-9][0-9])|2000)/
24
+ DEPTH_PERCENT_REGEX = /0*(([2-9][0-9])|([1-9][0-9][0-9])|(1[0-9][0-9][0-9])|2000)/.freeze
23
25
 
24
26
  # x rotation for the chart
25
27
  # must be between -90 and 90
@@ -76,11 +78,17 @@ module Axlsx
76
78
  alias :rotY= :rot_y=
77
79
 
78
80
  # @see depth_percent
79
- 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
80
85
  alias :depthPercent= :depth_percent=
81
86
 
82
87
  # @see r_ang_ax
83
- 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
84
92
  alias :rAngAx= :r_ang_ax=
85
93
 
86
94
  # @see perspective
@@ -94,7 +102,7 @@ module Axlsx
94
102
  # Serializes the object
95
103
  # @param [String] str
96
104
  # @return [String]
97
- def to_xml_string(str = '')
105
+ def to_xml_string(str = +'')
98
106
  str << '<c:view3D>'
99
107
  %w(rot_x h_percent rot_y depth_percent r_ang_ax perspective).each do |key|
100
108
  str << element_for_attribute(key, 'c')
@@ -104,12 +112,12 @@ module Axlsx
104
112
 
105
113
  private
106
114
 
107
- # Note: move this to Axlsx module if we find the smae pattern elsewhere.
115
+ # NOTE: move this to Axlsx module if we find the same pattern elsewhere.
108
116
  def element_for_attribute(name, namespace = '')
109
117
  val = Axlsx.instance_values_for(self)[name]
110
- return "" if val == nil
118
+ return "" if val.nil?
111
119
 
112
- "<%s:%s val='%s'/>" % [namespace, Axlsx::camel(name, false), val]
120
+ format("<%s:%s val='%s'/>", namespace, Axlsx.camel(name, false), val)
113
121
  end
114
122
  end
115
123
  end
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Axlsx
2
- # a vml drawing used for comments in excel.
4
+ # a vml drawing used for comments in Excel.
3
5
  class VmlDrawing
4
6
  # creates a new Vml Drawing object.
5
7
  # @param [Comments] comments the comments object this drawing is associated with
@@ -12,26 +14,26 @@ module Axlsx
12
14
  # The part name for this vml drawing
13
15
  # @return [String]
14
16
  def pn
15
- "#{VML_DRAWING_PN}" % (@comments.worksheet.index + 1)
17
+ format(VML_DRAWING_PN, @comments.worksheet.index + 1)
16
18
  end
17
19
 
18
20
  # serialize the vml_drawing to xml.
19
21
  # @param [String] str
20
22
  # @return [String]
21
- def to_xml_string(str = '')
22
- str << <<BAD_PROGRAMMER
23
- <xml xmlns:v="urn:schemas-microsoft-com:vml"
24
- xmlns:o="urn:schemas-microsoft-com:office:office"
25
- xmlns:x="urn:schemas-microsoft-com:office:excel">
26
- <o:shapelayout v:ext="edit">
27
- <o:idmap v:ext="edit" data="#{@comments.worksheet.index + 1}"/>
28
- </o:shapelayout>
29
- <v:shapetype id="_x0000_t202" coordsize="21600,21600" o:spt="202"
30
- path="m0,0l0,21600,21600,21600,21600,0xe">
31
- <v:stroke joinstyle="miter"/>
32
- <v:path gradientshapeok="t" o:connecttype="rect"/>
33
- </v:shapetype>
34
- BAD_PROGRAMMER
23
+ def to_xml_string(str = +'')
24
+ str << <<~XML
25
+ <xml xmlns:v="urn:schemas-microsoft-com:vml"
26
+ xmlns:o="urn:schemas-microsoft-com:office:office"
27
+ xmlns:x="urn:schemas-microsoft-com:office:excel">
28
+ <o:shapelayout v:ext="edit">
29
+ <o:idmap v:ext="edit" data="#{@comments.worksheet.index + 1}"/>
30
+ </o:shapelayout>
31
+ <v:shapetype id="_x0000_t202" coordsize="21600,21600" o:spt="202"
32
+ path="m0,0l0,21600,21600,21600,21600,0xe">
33
+ <v:stroke joinstyle="miter"/>
34
+ <v:path gradientshapeok="t" o:connecttype="rect"/>
35
+ </v:shapetype>
36
+ XML
35
37
  @comments.each { |comment| comment.vml_shape.to_xml_string str }
36
38
  str << "</xml>"
37
39
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Axlsx
2
4
  # A VmlShape is used to position and render a comment.
3
5
  class VmlShape
@@ -22,7 +24,7 @@ module Axlsx
22
24
  @right_offset = 50
23
25
  @bottom_offset = 5
24
26
  @visible = true
25
- @id = (0...8).map { 65.+(rand(25)).chr }.join
27
+ @id = Array.new(8) { rand(65..89).chr }.join
26
28
  parse_options options
27
29
  yield self if block_given?
28
30
  end
@@ -35,29 +37,29 @@ module Axlsx
35
37
  # serialize the shape to a string
36
38
  # @param [String] str
37
39
  # @return [String]
38
- def to_xml_string(str = '')
39
- str << <<SHAME_ON_YOU
40
+ def to_xml_string(str = +'')
41
+ str << <<~XML
40
42
 
41
- <v:shape id="#{@id}" type="#_x0000_t202" fillcolor="#ffffa1 [80]" o:insetmode="auto"
42
- style="visibility:#{@visible ? 'visible' : 'hidden'}">
43
- <v:fill color2="#ffffa1 [80]"/>
44
- <v:shadow on="t" obscured="t"/>
45
- <v:path o:connecttype="none"/>
46
- <v:textbox style='mso-fit-text-with-word-wrap:t'>
47
- <div style='text-align:left'></div>
48
- </v:textbox>
43
+ <v:shape id="#{@id}" type="#_x0000_t202" fillcolor="#ffffa1 [80]" o:insetmode="auto"
44
+ style="visibility:#{@visible ? 'visible' : 'hidden'}">
45
+ <v:fill color2="#ffffa1 [80]"/>
46
+ <v:shadow on="t" obscured="t"/>
47
+ <v:path o:connecttype="none"/>
48
+ <v:textbox style='mso-fit-text-with-word-wrap:t'>
49
+ <div style='text-align:left'></div>
50
+ </v:textbox>
49
51
 
50
- <x:ClientData ObjectType="Note">
51
- <x:MoveWithCells/>
52
- <x:SizeWithCells/>
53
- <x:Anchor>#{left_column}, #{left_offset}, #{top_row}, #{top_offset}, #{right_column}, #{right_offset}, #{bottom_row}, #{bottom_offset}</x:Anchor>
54
- <x:AutoFill>False</x:AutoFill>
55
- <x:Row>#{row}</x:Row>
56
- <x:Column>#{column}</x:Column>
57
- #{@visible ? '<x:Visible/>' : ''}
58
- </x:ClientData>
59
- </v:shape>
60
- SHAME_ON_YOU
52
+ <x:ClientData ObjectType="Note">
53
+ <x:MoveWithCells/>
54
+ <x:SizeWithCells/>
55
+ <x:Anchor>#{left_column}, #{left_offset}, #{top_row}, #{top_offset}, #{right_column}, #{right_offset}, #{bottom_row}, #{bottom_offset}</x:Anchor>
56
+ <x:AutoFill>False</x:AutoFill>
57
+ <x:Row>#{row}</x:Row>
58
+ <x:Column>#{column}</x:Column>
59
+ #{@visible ? '<x:Visible/>' : ''}
60
+ </x:ClientData>
61
+ </v:shape>
62
+ XML
61
63
  end
62
64
  end
63
65
  end
data/lib/axlsx/package.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Axlsx
2
4
  # Package is responsible for managing all the bits and peices that Open Office XML requires to make a valid
3
5
  # xlsx document including validation and serialization.
@@ -31,7 +33,7 @@ module Axlsx
31
33
  # Shortcut to specify that the workbook should use autowidth
32
34
  # @see Workbook#use_autowidth
33
35
  def use_autowidth=(v)
34
- Axlsx::validate_boolean(v);
36
+ Axlsx.validate_boolean(v)
35
37
  workbook.use_autowidth = v
36
38
  end
37
39
 
@@ -44,7 +46,7 @@ module Axlsx
44
46
  # Shortcut to specify that the workbook should use shared strings
45
47
  # @see Workbook#use_shared_strings
46
48
  def use_shared_strings=(v)
47
- Axlsx::validate_boolean(v);
49
+ Axlsx.validate_boolean(v)
48
50
  workbook.use_shared_strings = v
49
51
  end
50
52
 
@@ -67,7 +69,10 @@ module Axlsx
67
69
  end
68
70
 
69
71
  # @see workbook
70
- 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
71
76
 
72
77
  # Serialize your workbook to disk as an xlsx document.
73
78
  #
@@ -99,17 +104,17 @@ module Axlsx
99
104
  # s = p.to_stream()
100
105
  # File.open('example_streamed.xlsx', 'wb') { |f| f.write(s.read) }
101
106
  def serialize(output, options = {}, secondary_options = nil)
102
- if !workbook.styles_applied
107
+ unless workbook.styles_applied
103
108
  workbook.apply_styles
104
109
  end
105
110
 
106
111
  confirm_valid, zip_command = parse_serialize_options(options, secondary_options)
107
- return false unless !confirm_valid || self.validate.empty?
112
+ return false unless !confirm_valid || validate.empty?
108
113
 
109
114
  zip_provider = if zip_command
110
115
  ZipCommand.new(zip_command)
111
116
  else
112
- Zip::OutputStream
117
+ BufferedZipOutputStream
113
118
  end
114
119
  Relationship.initialize_ids_cache
115
120
  zip_provider.open(output) do |zip|
@@ -124,15 +129,16 @@ module Axlsx
124
129
  # @param [Boolean] confirm_valid Validate the package prior to serialization.
125
130
  # @return [StringIO|Boolean] False if confirm_valid and validation errors exist. rewound string IO if not.
126
131
  def to_stream(confirm_valid = false)
127
- if !workbook.styles_applied
132
+ unless workbook.styles_applied
128
133
  workbook.apply_styles
129
134
  end
130
135
 
131
- return false unless !confirm_valid || self.validate.empty?
136
+ return false unless !confirm_valid || validate.empty?
132
137
 
133
138
  Relationship.initialize_ids_cache
134
- zip = write_parts(Zip::OutputStream.new(StringIO.new.binmode, true))
135
- stream = zip.close_buffer
139
+ stream = BufferedZipOutputStream.write_buffer do |zip|
140
+ write_parts(zip)
141
+ end
136
142
  stream.rewind
137
143
  stream
138
144
  ensure
@@ -142,7 +148,7 @@ module Axlsx
142
148
  # Encrypt the package into a CFB using the password provided
143
149
  # This is not ready yet
144
150
  def encrypt(file_name, password)
145
- return false
151
+ false
146
152
  # moc = MsOffCrypto.new(file_name, password)
147
153
  # moc.save
148
154
  end
@@ -156,7 +162,7 @@ module Axlsx
156
162
  #
157
163
  # If by chance you are able to create a package that does not validate it indicates that the internal
158
164
  # validation is not robust enough and needs to be improved. Please report your errors to the gem author.
159
- # @see http://www.ecma-international.org/publications/standards/Ecma-376.htm
165
+ # @see https://www.ecma-international.org/publications-and-standards/standards/ecma-376/
160
166
  # @example
161
167
  # # The following will output any error messages found in serialization.
162
168
  # p = Axlsx::Package.new
@@ -213,57 +219,57 @@ module Axlsx
213
219
  # @private
214
220
  def parts
215
221
  parts = [
216
- { :entry => "xl/#{STYLES_PN}", :doc => workbook.styles, :schema => SML_XSD },
217
- { :entry => CORE_PN, :doc => @core, :schema => CORE_XSD },
218
- { :entry => APP_PN, :doc => @app, :schema => APP_XSD },
219
- { :entry => WORKBOOK_RELS_PN, :doc => workbook.relationships, :schema => RELS_XSD },
220
- { :entry => WORKBOOK_PN, :doc => workbook, :schema => SML_XSD }
222
+ { entry: "xl/#{STYLES_PN}", doc: workbook.styles, schema: SML_XSD },
223
+ { entry: CORE_PN, doc: @core, schema: CORE_XSD },
224
+ { entry: APP_PN, doc: @app, schema: APP_XSD },
225
+ { entry: WORKBOOK_RELS_PN, doc: workbook.relationships, schema: RELS_XSD },
226
+ { entry: WORKBOOK_PN, doc: workbook, schema: SML_XSD }
221
227
  ]
222
228
 
223
229
  workbook.drawings.each do |drawing|
224
- parts << { :entry => "xl/#{drawing.rels_pn}", :doc => drawing.relationships, :schema => RELS_XSD }
225
- parts << { :entry => "xl/#{drawing.pn}", :doc => drawing, :schema => DRAWING_XSD }
230
+ parts << { entry: "xl/#{drawing.rels_pn}", doc: drawing.relationships, schema: RELS_XSD }
231
+ parts << { entry: "xl/#{drawing.pn}", doc: drawing, schema: DRAWING_XSD }
226
232
  end
227
233
 
228
234
  workbook.tables.each do |table|
229
- parts << { :entry => "xl/#{table.pn}", :doc => table, :schema => SML_XSD }
235
+ parts << { entry: "xl/#{table.pn}", doc: table, schema: SML_XSD }
230
236
  end
231
237
  workbook.pivot_tables.each do |pivot_table|
232
238
  cache_definition = pivot_table.cache_definition
233
- parts << { :entry => "xl/#{pivot_table.rels_pn}", :doc => pivot_table.relationships, :schema => RELS_XSD }
234
- parts << { :entry => "xl/#{pivot_table.pn}", :doc => pivot_table } # , :schema => SML_XSD}
235
- parts << { :entry => "xl/#{cache_definition.pn}", :doc => cache_definition } # , :schema => SML_XSD}
239
+ parts << { entry: "xl/#{pivot_table.rels_pn}", doc: pivot_table.relationships, schema: RELS_XSD }
240
+ parts << { entry: "xl/#{pivot_table.pn}", doc: pivot_table } # , :schema => SML_XSD}
241
+ parts << { entry: "xl/#{cache_definition.pn}", doc: cache_definition } # , :schema => SML_XSD}
236
242
  end
237
243
 
238
244
  workbook.comments.each do |comment|
239
- if comment.size > 0
240
- parts << { :entry => "xl/#{comment.pn}", :doc => comment, :schema => SML_XSD }
241
- parts << { :entry => "xl/#{comment.vml_drawing.pn}", :doc => comment.vml_drawing, :schema => nil }
245
+ unless comment.empty?
246
+ parts << { entry: "xl/#{comment.pn}", doc: comment, schema: SML_XSD }
247
+ parts << { entry: "xl/#{comment.vml_drawing.pn}", doc: comment.vml_drawing, schema: nil }
242
248
  end
243
249
  end
244
250
 
245
251
  workbook.charts.each do |chart|
246
- parts << { :entry => "xl/#{chart.pn}", :doc => chart, :schema => DRAWING_XSD }
252
+ parts << { entry: "xl/#{chart.pn}", doc: chart, schema: DRAWING_XSD }
247
253
  end
248
254
 
249
255
  workbook.images.each do |image|
250
- parts << { :entry => "xl/#{image.pn}", :path => image.image_src } unless image.remote?
256
+ parts << { entry: "xl/#{image.pn}", path: image.image_src } unless image.remote?
251
257
  end
252
258
 
253
259
  if use_shared_strings
254
- parts << { :entry => "xl/#{SHARED_STRINGS_PN}", :doc => workbook.shared_strings, :schema => SML_XSD }
260
+ parts << { entry: "xl/#{SHARED_STRINGS_PN}", doc: workbook.shared_strings, schema: SML_XSD }
255
261
  end
256
262
 
257
263
  workbook.worksheets.each do |sheet|
258
- parts << { :entry => "xl/#{sheet.rels_pn}", :doc => sheet.relationships, :schema => RELS_XSD }
259
- parts << { :entry => "xl/#{sheet.pn}", :doc => sheet, :schema => SML_XSD }
264
+ parts << { entry: "xl/#{sheet.rels_pn}", doc: sheet.relationships, schema: RELS_XSD }
265
+ parts << { entry: "xl/#{sheet.pn}", doc: sheet, schema: SML_XSD }
260
266
  end
261
267
 
262
268
  # Sort parts for correct MIME detection
263
269
  [
264
- { :entry => CONTENT_TYPES_PN, :doc => content_types, :schema => CONTENT_TYPES_XSD },
265
- { :entry => RELS_PN, :doc => relationships, :schema => RELS_XSD },
266
- *(parts.sort_by { |part| part[:entry] }.reverse)
270
+ { entry: CONTENT_TYPES_PN, doc: content_types, schema: CONTENT_TYPES_XSD },
271
+ { entry: RELS_PN, doc: relationships, schema: RELS_XSD },
272
+ *parts.sort_by { |part| part[:entry] }.reverse
267
273
  ]
268
274
  end
269
275
 
@@ -289,56 +295,56 @@ module Axlsx
289
295
  def content_types
290
296
  c_types = base_content_types
291
297
  workbook.drawings.each do |drawing|
292
- c_types << Axlsx::Override.new(:PartName => "/xl/#{drawing.pn}",
293
- :ContentType => DRAWING_CT)
298
+ c_types << Axlsx::Override.new(PartName: "/xl/#{drawing.pn}",
299
+ ContentType: DRAWING_CT)
294
300
  end
295
301
 
296
302
  workbook.charts.each do |chart|
297
- c_types << Axlsx::Override.new(:PartName => "/xl/#{chart.pn}",
298
- :ContentType => CHART_CT)
303
+ c_types << Axlsx::Override.new(PartName: "/xl/#{chart.pn}",
304
+ ContentType: CHART_CT)
299
305
  end
300
306
 
301
307
  workbook.tables.each do |table|
302
- c_types << Axlsx::Override.new(:PartName => "/xl/#{table.pn}",
303
- :ContentType => TABLE_CT)
308
+ c_types << Axlsx::Override.new(PartName: "/xl/#{table.pn}",
309
+ ContentType: TABLE_CT)
304
310
  end
305
311
 
306
312
  workbook.pivot_tables.each do |pivot_table|
307
- c_types << Axlsx::Override.new(:PartName => "/xl/#{pivot_table.pn}",
308
- :ContentType => PIVOT_TABLE_CT)
309
- c_types << Axlsx::Override.new(:PartName => "/xl/#{pivot_table.cache_definition.pn}",
310
- :ContentType => PIVOT_TABLE_CACHE_DEFINITION_CT)
313
+ c_types << Axlsx::Override.new(PartName: "/xl/#{pivot_table.pn}",
314
+ ContentType: PIVOT_TABLE_CT)
315
+ c_types << Axlsx::Override.new(PartName: "/xl/#{pivot_table.cache_definition.pn}",
316
+ ContentType: PIVOT_TABLE_CACHE_DEFINITION_CT)
311
317
  end
312
318
 
313
319
  workbook.comments.each do |comment|
314
- if comment.size > 0
315
- c_types << Axlsx::Override.new(:PartName => "/xl/#{comment.pn}",
316
- :ContentType => COMMENT_CT)
320
+ unless comment.empty?
321
+ c_types << Axlsx::Override.new(PartName: "/xl/#{comment.pn}",
322
+ ContentType: COMMENT_CT)
317
323
  end
318
324
  end
319
325
 
320
- if workbook.comments.size > 0
321
- c_types << Axlsx::Default.new(:Extension => "vml", :ContentType => VML_DRAWING_CT)
326
+ unless workbook.comments.empty?
327
+ c_types << Axlsx::Default.new(Extension: "vml", ContentType: VML_DRAWING_CT)
322
328
  end
323
329
 
324
330
  workbook.worksheets.each do |sheet|
325
- c_types << Axlsx::Override.new(:PartName => "/xl/#{sheet.pn}",
326
- :ContentType => WORKSHEET_CT)
331
+ c_types << Axlsx::Override.new(PartName: "/xl/#{sheet.pn}",
332
+ ContentType: WORKSHEET_CT)
327
333
  end
328
334
  exts = workbook.images.map { |image| image.extname.downcase }
329
335
  exts.uniq.each do |ext|
330
- ct = if ['jpeg', 'jpg'].include?(ext)
336
+ ct = if JPEG_EXS.include?(ext)
331
337
  JPEG_CT
332
- elsif ext == 'gif'
338
+ elsif ext == GIF_EX
333
339
  GIF_CT
334
- elsif ext == 'png'
340
+ elsif ext == PNG_EX
335
341
  PNG_CT
336
342
  end
337
- c_types << Axlsx::Default.new(:ContentType => ct, :Extension => ext)
343
+ c_types << Axlsx::Default.new(ContentType: ct, Extension: ext)
338
344
  end
339
345
  if use_shared_strings
340
- c_types << Axlsx::Override.new(:PartName => "/xl/#{SHARED_STRINGS_PN}",
341
- :ContentType => SHARED_STRINGS_CT)
346
+ c_types << Axlsx::Override.new(PartName: "/xl/#{SHARED_STRINGS_PN}",
347
+ ContentType: SHARED_STRINGS_CT)
342
348
  end
343
349
  c_types
344
350
  end
@@ -347,13 +353,13 @@ module Axlsx
347
353
  # @return [ContentType]
348
354
  # @private
349
355
  def base_content_types
350
- c_types = ContentType.new()
351
- c_types << Default.new(:ContentType => RELS_CT, :Extension => RELS_EX)
352
- c_types << Default.new(:Extension => XML_EX, :ContentType => XML_CT)
353
- c_types << Override.new(:PartName => "/#{APP_PN}", :ContentType => APP_CT)
354
- c_types << Override.new(:PartName => "/#{CORE_PN}", :ContentType => CORE_CT)
355
- c_types << Override.new(:PartName => "/xl/#{STYLES_PN}", :ContentType => STYLES_CT)
356
- c_types << Axlsx::Override.new(:PartName => "/#{WORKBOOK_PN}", :ContentType => WORKBOOK_CT)
356
+ c_types = ContentType.new
357
+ c_types << Default.new(ContentType: RELS_CT, Extension: RELS_EX)
358
+ c_types << Default.new(Extension: XML_EX, ContentType: XML_CT)
359
+ c_types << Override.new(PartName: "/#{APP_PN}", ContentType: APP_CT)
360
+ c_types << Override.new(PartName: "/#{CORE_PN}", ContentType: CORE_CT)
361
+ c_types << Override.new(PartName: "/xl/#{STYLES_PN}", ContentType: STYLES_CT)
362
+ c_types << Axlsx::Override.new(PartName: "/#{WORKBOOK_PN}", ContentType: WORKBOOK_CT)
357
363
  c_types.lock
358
364
  c_types
359
365
  end
@@ -376,19 +382,19 @@ module Axlsx
376
382
  # @private
377
383
  def parse_serialize_options(options, secondary_options)
378
384
  if secondary_options
379
- warn "[DEPRECATION] Axlsx::Package#serialize with 3 arguments is deprecated. " +
385
+ warn "[DEPRECATION] Axlsx::Package#serialize with 3 arguments is deprecated. " \
380
386
  "Use keyword args instead e.g., package.serialize(output, confirm_valid: false, zip_command: 'zip')"
381
387
  end
382
388
  if options.is_a?(Hash)
383
389
  options.merge!(secondary_options || {})
384
390
  invalid_keys = options.keys - [:confirm_valid, :zip_command]
385
391
  if invalid_keys.any?
386
- raise ArgumentError.new("Invalid keyword arguments: #{invalid_keys}")
392
+ raise ArgumentError, "Invalid keyword arguments: #{invalid_keys}"
387
393
  end
388
394
 
389
395
  [options.fetch(:confirm_valid, false), options.fetch(:zip_command, nil)]
390
396
  else
391
- warn "[DEPRECATION] Axlsx::Package#serialize with confirm_valid as a boolean is deprecated. " +
397
+ warn "[DEPRECATION] Axlsx::Package#serialize with confirm_valid as a boolean is deprecated. " \
392
398
  "Use keyword args instead e.g., package.serialize(output, confirm_valid: false)"
393
399
  parse_serialize_options((secondary_options || {}).merge(confirm_valid: options), nil)
394
400
  end