axlsx 1.3.1 → 1.3.2

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 (99) hide show
  1. data/README.md +13 -5
  2. data/examples/colored_links.rb +59 -0
  3. data/examples/example.rb +421 -266
  4. data/examples/example.xlsx +0 -0
  5. data/examples/example_streamed.xlsx +0 -0
  6. data/examples/finance.rb +82 -0
  7. data/examples/finance.xlsx +0 -0
  8. data/examples/financial.xlsx +0 -0
  9. data/examples/no-use_autowidth.xlsx +0 -0
  10. data/examples/shared_strings_example.xlsx +0 -0
  11. data/examples/where_is_my_color.xlsx +0 -0
  12. data/lib/axlsx.rb +11 -4
  13. data/lib/axlsx/content_type/abstract_content_type.rb +32 -0
  14. data/lib/axlsx/content_type/content_type.rb +1 -1
  15. data/lib/axlsx/content_type/default.rb +6 -37
  16. data/lib/axlsx/content_type/override.rb +6 -38
  17. data/lib/axlsx/doc_props/app.rb +7 -4
  18. data/lib/axlsx/drawing/axis.rb +3 -3
  19. data/lib/axlsx/drawing/chart.rb +2 -3
  20. data/lib/axlsx/drawing/d_lbls.rb +21 -31
  21. data/lib/axlsx/drawing/drawing.rb +6 -0
  22. data/lib/axlsx/drawing/hyperlink.rb +40 -32
  23. data/lib/axlsx/drawing/marker.rb +13 -13
  24. data/lib/axlsx/drawing/num_data.rb +6 -6
  25. data/lib/axlsx/drawing/num_data_source.rb +17 -16
  26. data/lib/axlsx/drawing/one_cell_anchor.rb +20 -22
  27. data/lib/axlsx/drawing/pic.rb +25 -27
  28. data/lib/axlsx/drawing/picture_locking.rb +12 -44
  29. data/lib/axlsx/drawing/scaling.rb +13 -13
  30. data/lib/axlsx/drawing/scatter_chart.rb +3 -3
  31. data/lib/axlsx/drawing/series.rb +3 -6
  32. data/lib/axlsx/drawing/str_data.rb +3 -3
  33. data/lib/axlsx/drawing/str_val.rb +7 -8
  34. data/lib/axlsx/drawing/view_3D.rb +51 -37
  35. data/lib/axlsx/drawing/vml_shape.rb +23 -23
  36. data/lib/axlsx/package.rb +14 -16
  37. data/lib/axlsx/stylesheet/border.rb +29 -20
  38. data/lib/axlsx/stylesheet/border_pr.rb +5 -4
  39. data/lib/axlsx/stylesheet/cell_alignment.rb +55 -29
  40. data/lib/axlsx/stylesheet/cell_protection.rb +7 -4
  41. data/lib/axlsx/stylesheet/cell_style.rb +19 -14
  42. data/lib/axlsx/stylesheet/color.rb +19 -16
  43. data/lib/axlsx/stylesheet/dxf.rb +4 -4
  44. data/lib/axlsx/stylesheet/font.rb +22 -22
  45. data/lib/axlsx/stylesheet/gradient_fill.rb +45 -21
  46. data/lib/axlsx/stylesheet/num_fmt.rb +22 -13
  47. data/lib/axlsx/stylesheet/pattern_fill.rb +12 -21
  48. data/lib/axlsx/stylesheet/styles.rb +1 -1
  49. data/lib/axlsx/stylesheet/table_style.rb +17 -16
  50. data/lib/axlsx/stylesheet/table_style_element.rb +15 -11
  51. data/lib/axlsx/stylesheet/table_styles.rb +14 -11
  52. data/lib/axlsx/stylesheet/xf.rb +28 -26
  53. data/lib/axlsx/util/accessors.rb +49 -0
  54. data/lib/axlsx/util/options_parser.rb +15 -0
  55. data/lib/axlsx/util/serialized_attributes.rb +46 -0
  56. data/lib/axlsx/util/simple_typed_list.rb +16 -4
  57. data/lib/axlsx/version.rb +1 -1
  58. data/lib/axlsx/workbook/defined_name.rb +13 -58
  59. data/lib/axlsx/workbook/workbook.rb +27 -1
  60. data/lib/axlsx/workbook/worksheet/auto_filter/filter_column.rb +11 -19
  61. data/lib/axlsx/workbook/worksheet/auto_filter/filters.rb +20 -27
  62. data/lib/axlsx/workbook/worksheet/cell.rb +38 -39
  63. data/lib/axlsx/workbook/worksheet/cfvo.rb +15 -15
  64. data/lib/axlsx/workbook/worksheet/cfvos.rb +18 -0
  65. data/lib/axlsx/workbook/worksheet/col.rb +34 -27
  66. data/lib/axlsx/workbook/worksheet/color_scale.rb +7 -13
  67. data/lib/axlsx/workbook/worksheet/comment.rb +14 -11
  68. data/lib/axlsx/workbook/worksheet/conditional_formatting.rb +11 -11
  69. data/lib/axlsx/workbook/worksheet/conditional_formatting_rule.rb +27 -25
  70. data/lib/axlsx/workbook/worksheet/data_bar.rb +44 -34
  71. data/lib/axlsx/workbook/worksheet/data_validation.rb +61 -62
  72. data/lib/axlsx/workbook/worksheet/dimension.rb +0 -1
  73. data/lib/axlsx/workbook/worksheet/icon_set.rb +20 -20
  74. data/lib/axlsx/workbook/worksheet/page_margins.rb +21 -19
  75. data/lib/axlsx/workbook/worksheet/page_set_up_pr.rb +6 -9
  76. data/lib/axlsx/workbook/worksheet/page_setup.rb +20 -19
  77. data/lib/axlsx/workbook/worksheet/pane.rb +48 -51
  78. data/lib/axlsx/workbook/worksheet/print_options.rb +8 -30
  79. data/lib/axlsx/workbook/worksheet/protected_range.rb +16 -13
  80. data/lib/axlsx/workbook/worksheet/selection.rb +30 -38
  81. data/lib/axlsx/workbook/worksheet/sheet_calc_pr.rb +6 -26
  82. data/lib/axlsx/workbook/worksheet/sheet_pr.rb +19 -57
  83. data/lib/axlsx/workbook/worksheet/sheet_protection.rb +51 -155
  84. data/lib/axlsx/workbook/worksheet/sheet_view.rb +68 -234
  85. data/lib/axlsx/workbook/worksheet/table.rb +16 -18
  86. data/lib/axlsx/workbook/worksheet/table_style_info.rb +10 -27
  87. data/lib/axlsx/workbook/worksheet/worksheet.rb +6 -7
  88. data/lib/axlsx/workbook/worksheet/worksheet_drawing.rb +1 -1
  89. data/lib/axlsx/workbook/worksheet/worksheet_hyperlink.rb +11 -33
  90. data/test/content_type/tc_default.rb +0 -11
  91. data/test/content_type/tc_override.rb +0 -13
  92. data/test/drawing/tc_d_lbls.rb +14 -4
  93. data/test/tc_axlsx.rb +20 -2
  94. data/test/workbook/tc_defined_name.rb +2 -2
  95. data/test/workbook/tc_workbook.rb +15 -0
  96. data/test/workbook/worksheet/tc_col.rb +11 -1
  97. data/test/workbook/worksheet/tc_pane.rb +5 -45
  98. data/test/workbook/worksheet/tc_selection.rb +9 -48
  99. metadata +13 -3
Binary file
@@ -0,0 +1,82 @@
1
+ $LOAD_PATH.unshift "#{File.dirname(__FILE__)}/../lib"
2
+
3
+
4
+ require 'axlsx'
5
+
6
+ # First thing to do is setup our styles. OOXML Style management is unfortunately very different from CSS so we want to use the
7
+ # add_style helper method on the workbook styles object so we dont go insane.
8
+
9
+ # I find it easier to declare a hash and then feed that in later
10
+
11
+ class FinancialReport
12
+
13
+ def initialize(data)
14
+ create_styles
15
+ prepare
16
+ insert_data data
17
+ finalize
18
+ package
19
+ end
20
+
21
+ def style_hash
22
+
23
+ sienna = 'A0522D'
24
+ {
25
+ :search_results => { :sz => 10, :b => true },
26
+ :bold_header => { :b => true },
27
+ :grey_bg => { :bg_color => "DEDEDE" },
28
+ :transaction__header => { :fg_color => sienna, :b => true },
29
+ :transaction_currency => { :fb_color => sienna, :num_fmt => 5 },
30
+ :transactin_date => { :fg_color => sienna, :format_code => 'yyyy-mm-dd' }
31
+ }
32
+ end
33
+
34
+ def styles
35
+ @styles ||= {}
36
+ end
37
+
38
+ def package
39
+ @package ||= Axlsx::Package.new
40
+ end
41
+
42
+ # Just a place to put some defualt data for the exercise
43
+ def self.data
44
+ @data = ['baked',
45
+ "American Medical Systems Holdings, Inc.",
46
+ "Endo Pharmaceuticals Holdings, Inc.",
47
+ "4371",
48
+ Date.new,
49
+ 2757001160,
50
+ 2519495160,
51
+ 116,
52
+ 3842,
53
+ "Medical devices for urology disorders"]
54
+ end
55
+
56
+ # Populates an array of ['style_name'] = style_index
57
+ def create_styles
58
+ package.workbook.styles do |style|
59
+ style_hash.each do |key, value|
60
+ styles[key] = style.add_style(value)
61
+ end
62
+ end
63
+ end
64
+ def prepare
65
+ package.workbook.add_worksheet(:name => 'All Information') do |sheet|
66
+ sheet.add_row [nil, 'Search Results'], :style => [nil, styles['search_results']]
67
+ end
68
+ end
69
+
70
+
71
+ def insert_data(data)
72
+ package.workbook.worksheets.first do |sheet|
73
+ sheet.add_row data, style=> [styles[:
74
+ end
75
+ end
76
+
77
+ def finalize
78
+ # package.serialize 'financial.xlsx'
79
+ end
80
+ end
81
+ f = FinancialReport.new(FinancialReport.data)
82
+ f.package.serialize 'finance.xlsx'
Binary file
Binary file
@@ -5,7 +5,9 @@ require 'axlsx/version.rb'
5
5
  require 'axlsx/util/simple_typed_list.rb'
6
6
  require 'axlsx/util/constants.rb'
7
7
  require 'axlsx/util/validators.rb'
8
-
8
+ require 'axlsx/util/accessors.rb'
9
+ require 'axlsx/util/serialized_attributes'
10
+ require 'axlsx/util/options_parser'
9
11
  # to be included with parsable intitites.
10
12
  #require 'axlsx/util/parser.rb'
11
13
 
@@ -48,9 +50,14 @@ module Axlsx
48
50
  # determines the cell range for the items provided
49
51
  def self.cell_range(cells, absolute=true)
50
52
  return "" unless cells.first.is_a? Cell
51
- sort_cells(cells)
53
+ cells = sort_cells(cells)
52
54
  reference = "#{cells.first.reference(absolute)}:#{cells.last.reference(absolute)}"
53
- absolute ? "'#{cells.first.row.worksheet.name}'!#{reference}" : reference
55
+ if absolute
56
+ escaped_name = cells.first.row.worksheet.name.gsub "'", "''"
57
+ "'#{escaped_name}'!#{reference}"
58
+ else
59
+ reference
60
+ end
54
61
  end
55
62
 
56
63
  # sorts the array of cells provided to start from the minimum x,y to
@@ -66,7 +73,7 @@ module Axlsx
66
73
  def self.coder
67
74
  @@coder ||= ::HTMLEntities.new
68
75
  end
69
-
76
+
70
77
  # returns the x, y position of a cell
71
78
  def self.name_to_indices(name)
72
79
  raise ArgumentError, 'invalid cell name' unless name.size > 1
@@ -0,0 +1,32 @@
1
+ module Axlsx
2
+
3
+ # This class extracts the common parts from Default and Override
4
+ class AbstractContentType
5
+
6
+ include Axlsx::OptionsParser
7
+
8
+ # Initializes an abstract content type
9
+ # @see Default, Override
10
+ def initialize(options={})
11
+ parse_options options
12
+ end
13
+
14
+ # The type of content.
15
+ # @return [String]
16
+ attr_reader :content_type
17
+ alias :ContentType :content_type
18
+
19
+ # The content type.
20
+ # @see Axlsx#validate_content_type
21
+ def content_type=(v) Axlsx::validate_content_type v; @content_type = v end
22
+ alias :ContentType= :content_type=
23
+
24
+ # Serialize the contenty type to xml
25
+ def to_xml_string(node_name = '', str = '')
26
+ str << "<#{node_name} "
27
+ str << instance_values.map { |key, value| '' << Axlsx::camel(key) << '="' << value.to_s << '"' }.join(' ')
28
+ str << '/>'
29
+ end
30
+
31
+ end
32
+ end
@@ -1,6 +1,6 @@
1
1
  # encoding: UTF-8
2
2
  module Axlsx
3
-
3
+ require 'axlsx/content_type/abstract_content_type.rb'
4
4
  require 'axlsx/content_type/default.rb'
5
5
  require 'axlsx/content_type/override.rb'
6
6
 
@@ -2,55 +2,24 @@
2
2
  module Axlsx
3
3
 
4
4
  # An default content part. These parts are automatically created by for you based on the content of your package.
5
- class Default
5
+ class Default < AbstractContentType
6
6
 
7
- #Creates a new Default object
8
- # @option options [String] extension
9
- # @option options [String] content_type
10
- # @raise [ArgumentError] An argument error is raised if both extension and content_type are not specified.
11
- def initialize(options={})
12
- raise ArgumentError, INVALID_ARGUMENTS unless validate_options(options)
13
- options.each do |name, value|
14
- self.send("#{name}=", value) if self.respond_to? "#{name}="
15
- end
16
- end
17
-
18
- # Error string for option validation
19
- INVALID_ARGUMENTS = "extension and content_type are required"
7
+ # The serialization node name for this class
8
+ NODE_NAME = 'Default'
20
9
 
21
10
  # The extension of the content type.
22
11
  # @return [String]
23
12
  attr_reader :extension
24
13
  alias :Extension :extension
25
14
 
26
- # The type of content.
27
- # @return [String]
28
- attr_reader :content_type
29
- alias :ContentType :content_type
30
-
31
15
  # Sets the file extension for this content type.
32
16
  def extension=(v) Axlsx::validate_string v; @extension = v end
33
17
  alias :Extension= :extension=
34
18
 
35
- # Sets the content type
36
- # @see Axlsx#validate_content_type
37
- def content_type=(v) Axlsx::validate_content_type v; @content_type = v end
38
- alias :ContentType= :content_type=
39
-
40
- # Serializes the object
41
- # @param [String] str
42
- # @return [String]
43
- def to_xml_string(str = '')
44
- str << '<Default '
45
- str << instance_values.map { |key, value| '' << Axlsx::camel(key) << '="' << value.to_s << '"' }.join(' ')
46
- str << '/>'
47
- end
48
-
49
- private
50
- def validate_options(options)
51
- (options[:Extension] || options[:extension]) && (options[:content_type] || options[:ContentType])
19
+ # Serializes this object to xml
20
+ def to_xml_string(str ='')
21
+ super(NODE_NAME, str)
52
22
  end
53
-
54
23
  end
55
24
 
56
25
  end
@@ -1,27 +1,12 @@
1
+
1
2
  # encoding: UTF-8
2
3
  module Axlsx
3
4
 
4
5
  # An override content part. These parts are automatically created by for you based on the content of your package.
5
- class Override
6
-
7
- #Creates a new Override object
8
- # @option options [String] PartName
9
- # @option options [String] ContentType
10
- # @raise [ArgumentError] An argument error is raised if both PartName and ContentType are not specified.
11
- def initialize(options={})
12
- raise ArgumentError, INVALID_ARGUMENTS unless validate_options(options)
13
- options.each do |name, value|
14
- self.send("#{name}=", value) if self.respond_to? "#{name}="
15
- end
16
- end
6
+ class Override < AbstractContentType
17
7
 
18
- # Error message for invalid options
19
- INVALID_ARGUMENTS = 'part_name and content_type are required'
20
-
21
- # The type of content.
22
- # @return [String]
23
- attr_reader :content_type
24
- alias :ContentType :content_type
8
+ # Serialization node name for this object
9
+ NODE_NAME = 'Override'
25
10
 
26
11
  # The name and location of the part.
27
12
  # @return [String]
@@ -32,26 +17,9 @@ module Axlsx
32
17
  def part_name=(v) Axlsx::validate_string v; @part_name = v end
33
18
  alias :PartName= :part_name=
34
19
 
35
- # The content type.
36
- # @see Axlsx#validate_content_type
37
- def content_type=(v) Axlsx::validate_content_type v; @content_type = v end
38
- alias :ContentType= :content_type=
39
-
40
- # Serializes the object
41
- # @param [String] str
42
- # @return [String]
20
+ # Serializes this object to xml
43
21
  def to_xml_string(str = '')
44
- str << '<Override '
45
- str << instance_values.map { |key, value| '' << Axlsx::camel(key) << '="' << value.to_s << '"' }.join(' ')
46
- str << '/>'
47
- end
48
-
49
- private
50
-
51
- def validate_options(options)
52
- (options[:PartName] || options[:part_name]) && (options[:ContentType] || options[:content_type])
22
+ super(NODE_NAME, str)
53
23
  end
54
-
55
24
  end
56
-
57
25
  end
@@ -11,6 +11,8 @@ module Axlsx
11
11
  # DigSig (DigSigBlob)
12
12
  class App
13
13
 
14
+ include Axlsx::OptionsParser
15
+
14
16
  # Creates an App object
15
17
  # @option options [String] template
16
18
  # @option options [String] manager
@@ -35,9 +37,7 @@ module Axlsx
35
37
  # @option options [String] app_version
36
38
  # @option options [Integer] doc_security
37
39
  def initialize(options={})
38
- options.each do |name, value|
39
- self.send("#{name}=", value) if self.respond_to? "#{name}="
40
- end
40
+ parse_options options
41
41
  end
42
42
 
43
43
  # @return [String] The name of the document template.
@@ -223,7 +223,10 @@ module Axlsx
223
223
  def to_xml_string(str = '')
224
224
  str << '<?xml version="1.0" encoding="UTF-8"?>'
225
225
  str << '<Properties xmlns="' << APP_NS << '" xmlns:vt="' << APP_NS_VT << '">'
226
- str << instance_values.map { |key, value| '<' << Axlsx.camel(key) << '>' << value.to_s << '</' << Axlsx.camel(key) << '>' }.join
226
+ instance_values.each do |key, value|
227
+ node_name = Axlsx.camel(key)
228
+ str << "<#{node_name}>#{value}</#{node_name}>"
229
+ end
227
230
  str << '</Properties>'
228
231
  end
229
232
 
@@ -4,6 +4,8 @@ module Axlsx
4
4
  # the access class defines common properties and values for a chart axis.
5
5
  class Axis
6
6
 
7
+ include Axlsx::OptionsParser
8
+
7
9
  # Creates an Axis object
8
10
  # @param [Integer] ax_id the id of this axis
9
11
  # @param [Integer] cross_ax the id of the perpendicular axis
@@ -25,9 +27,7 @@ module Axlsx
25
27
  self.format_code = "General"
26
28
  self.crosses = :autoZero
27
29
  self.gridlines = true
28
- options.each do |name, value|
29
- self.send("#{name}=", value) if self.respond_to? "#{name}="
30
- end
30
+ parse_options options
31
31
  end
32
32
 
33
33
  # the fill color to use in the axis shape properties. This should be a 6 character long hex string
@@ -6,6 +6,7 @@ module Axlsx
6
6
  # @see README for examples
7
7
  class Chart
8
8
 
9
+ include Axlsx::OptionsParser
9
10
  # Creates a new chart object
10
11
  # @param [GraphicalFrame] frame The frame that holds this chart.
11
12
  # @option options [Cell, String] title
@@ -21,9 +22,7 @@ module Axlsx
21
22
  @show_legend = true
22
23
  @series_type = Series
23
24
  @title = Title.new
24
- options.each do |o|
25
- self.send("#{o[0]}=", o[1]) if self.respond_to? "#{o[0]}="
26
- end
25
+ parse_options options
27
26
  start_at(*options[:start_at]) if options[:start_at]
28
27
  end_at(*options[:end_at]) if options[:end_at]
29
28
  yield self if block_given?
@@ -2,33 +2,40 @@ module Axlsx
2
2
  # There are more elements in the dLbls spec that allow for
3
3
  # customizations and formatting. For now, I am just implementing the
4
4
  # basics.
5
-
6
5
  #The DLbls class manages serialization of data labels
7
6
  # showLeaderLines and leaderLines are not currently implemented
8
7
  class DLbls
9
8
 
10
- # These attributes are all boolean so I'm doing a bit of a hand
11
- # waving magic show to set up the attriubte accessors
12
- # @note
13
- # not all charts support all methods!
14
- # Bar3DChart and Line3DChart and ScatterChart do not support d_lbl_pos or show_leader_lines
15
- #
16
- BOOLEAN_ATTRIBUTES = [:show_legend_key, :show_val, :show_cat_name, :show_ser_name, :show_percent, :show_bubble_size, :show_leader_lines]
17
-
9
+ include Axlsx::Accessors
10
+ include Axlsx::OptionsParser
18
11
  # creates a new DLbls object
19
12
  def initialize(chart_type, options={})
20
13
  raise ArgumentError, 'chart_type must inherit from Chart' unless chart_type.superclass == Chart
21
14
  @chart_type = chart_type
22
15
  initialize_defaults
23
- options.each do |o|
24
- self.send("#{o[0]}=", o[1]) if self.respond_to? "#{o[0]}="
25
- end
16
+ parse_options options
26
17
  end
27
18
 
19
+ # These attributes are all boolean so I'm doing a bit of a hand
20
+ # waving magic show to set up the attriubte accessors
21
+ # @note
22
+ # not all charts support all methods!
23
+ # Bar3DChart and Line3DChart and ScatterChart do not support d_lbl_pos or show_leader_lines
24
+ #
25
+ boolean_attr_accessor :show_legend_key,
26
+ :show_val,
27
+ :show_cat_name,
28
+ :show_ser_name,
29
+ :show_percent,
30
+ :show_bubble_size,
31
+ :show_leader_lines
32
+
28
33
  # Initialize all the values to false as Excel requires them to
29
34
  # explicitly be disabled or all will show.
30
35
  def initialize_defaults
31
- BOOLEAN_ATTRIBUTES.each do |attr|
36
+ [:show_legend_key, :show_val, :show_cat_name,
37
+ :show_ser_name, :show_percent, :show_bubble_size,
38
+ :show_leader_lines].each do |attr|
32
39
  self.send("#{attr}=", false)
33
40
  end
34
41
  end
@@ -58,24 +65,7 @@ module Axlsx
58
65
  @d_lbl_pos = label_position
59
66
  end
60
67
 
61
- # Dynamically create accessors for boolean attriubtes
62
- BOOLEAN_ATTRIBUTES.each do |attr|
63
- class_eval %{
64
- # The #{attr} attribute reader
65
- # @return [Boolean]
66
- attr_reader :#{attr}
67
-
68
- # The #{attr} writer
69
- # @param [Boolean] value The value to assign to #{attr}
70
- # @return [Boolean]
71
- def #{attr}=(value)
72
- Axlsx::validate_boolean(value)
73
- @#{attr} = value
74
- end
75
- }
76
- end
77
-
78
-
68
+
79
69
  # serializes the data labels
80
70
  # @return [String]
81
71
  def to_xml_string(str = '')