axlsx 1.0.17 → 1.1.0

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 (167) hide show
  1. data/CHANGELOG.md +11 -3
  2. data/README.md +159 -51
  3. data/examples/example.csv +1000 -0
  4. data/examples/example.rb +255 -150
  5. data/examples/example.xlsx +0 -0
  6. data/examples/example_streamed.xlsx +0 -0
  7. data/examples/no-use_autowidth.xlsx +0 -0
  8. data/examples/shared_strings_example.xlsx +0 -0
  9. data/lib/axlsx/content_type/content_type.rb +12 -12
  10. data/lib/axlsx/content_type/default.rb +9 -6
  11. data/lib/axlsx/content_type/override.rb +12 -8
  12. data/lib/axlsx/doc_props/app.rb +37 -40
  13. data/lib/axlsx/doc_props/core.rb +12 -17
  14. data/lib/axlsx/drawing/axis.rb +38 -19
  15. data/lib/axlsx/drawing/bar_3D_chart.rb +33 -32
  16. data/lib/axlsx/drawing/bar_series.rb +13 -14
  17. data/lib/axlsx/drawing/cat_axis.rb +15 -14
  18. data/lib/axlsx/drawing/cat_axis_data.rb +16 -18
  19. data/lib/axlsx/drawing/chart.rb +39 -40
  20. data/lib/axlsx/drawing/drawing.rb +15 -12
  21. data/lib/axlsx/drawing/graphic_frame.rb +21 -21
  22. data/lib/axlsx/drawing/hyperlink.rb +12 -11
  23. data/lib/axlsx/drawing/line_3D_chart.rb +30 -28
  24. data/lib/axlsx/drawing/line_series.rb +11 -11
  25. data/lib/axlsx/drawing/marker.rb +10 -8
  26. data/lib/axlsx/drawing/named_axis_data.rb +36 -0
  27. data/lib/axlsx/drawing/one_cell_anchor.rb +17 -16
  28. data/lib/axlsx/drawing/pic.rb +25 -37
  29. data/lib/axlsx/drawing/picture_locking.rb +21 -18
  30. data/lib/axlsx/drawing/pie_3D_chart.rb +10 -8
  31. data/lib/axlsx/drawing/pie_series.rb +15 -12
  32. data/lib/axlsx/drawing/scaling.rb +10 -10
  33. data/lib/axlsx/drawing/scatter_chart.rb +69 -0
  34. data/lib/axlsx/drawing/scatter_series.rb +39 -0
  35. data/lib/axlsx/drawing/ser_axis.rb +10 -10
  36. data/lib/axlsx/drawing/series.rb +15 -15
  37. data/lib/axlsx/drawing/series_title.rb +14 -14
  38. data/lib/axlsx/drawing/title.rb +26 -26
  39. data/lib/axlsx/drawing/two_cell_anchor.rb +18 -20
  40. data/lib/axlsx/drawing/val_axis.rb +8 -7
  41. data/lib/axlsx/drawing/val_axis_data.rb +17 -17
  42. data/lib/axlsx/drawing/view_3D.rb +22 -20
  43. data/lib/axlsx/package.rb +60 -43
  44. data/lib/axlsx/rels/relationship.rb +11 -8
  45. data/lib/axlsx/rels/relationships.rb +7 -1
  46. data/lib/axlsx/stylesheet/#num_fmt.rb# +69 -0
  47. data/lib/axlsx/stylesheet/border.rb +27 -23
  48. data/lib/axlsx/stylesheet/border_pr.rb +16 -15
  49. data/lib/axlsx/stylesheet/cell_alignment.rb +23 -21
  50. data/lib/axlsx/stylesheet/cell_protection.rb +10 -7
  51. data/lib/axlsx/stylesheet/cell_style.rb +8 -5
  52. data/lib/axlsx/stylesheet/color.rb +20 -14
  53. data/lib/axlsx/stylesheet/fill.rb +7 -5
  54. data/lib/axlsx/stylesheet/font.rb +21 -14
  55. data/lib/axlsx/stylesheet/gradient_fill.rb +19 -16
  56. data/lib/axlsx/stylesheet/gradient_stop.rb +9 -5
  57. data/lib/axlsx/stylesheet/num_fmt.rb +12 -6
  58. data/lib/axlsx/stylesheet/pattern_fill.rb +25 -10
  59. data/lib/axlsx/stylesheet/styles.rb +47 -35
  60. data/lib/axlsx/stylesheet/table_style.rb +9 -4
  61. data/lib/axlsx/stylesheet/table_style_element.rb +10 -7
  62. data/lib/axlsx/stylesheet/table_styles.rb +11 -8
  63. data/lib/axlsx/stylesheet/xf.rb +29 -25
  64. data/lib/axlsx/util/constants.rb +20 -14
  65. data/lib/axlsx/util/simple_typed_list.rb +18 -9
  66. data/lib/axlsx/util/validators.rb +13 -6
  67. data/lib/axlsx/version.rb +1 -1
  68. data/lib/axlsx/workbook/shared_strings_table.rb +19 -21
  69. data/lib/axlsx/workbook/workbook.rb +58 -34
  70. data/lib/axlsx/workbook/worksheet/cell.rb +149 -132
  71. data/lib/axlsx/workbook/worksheet/col.rb +114 -0
  72. data/lib/axlsx/workbook/worksheet/col.rb~ +0 -0
  73. data/lib/axlsx/workbook/worksheet/date_time_converter.rb +29 -0
  74. data/lib/axlsx/workbook/worksheet/page_margins.rb +97 -0
  75. data/lib/axlsx/workbook/worksheet/row.rb +40 -23
  76. data/lib/axlsx/workbook/worksheet/table.rb +96 -0
  77. data/lib/axlsx/workbook/worksheet/table.rb~ +97 -0
  78. data/lib/axlsx/workbook/worksheet/worksheet.rb +243 -127
  79. data/lib/axlsx.rb +30 -9
  80. data/lib/schema/dc.xsd +5 -5
  81. data/lib/schema/dcmitype.xsd +5 -3
  82. data/lib/schema/dcterms.xsd +15 -15
  83. data/lib/schema/opc-coreProperties.xsd +6 -2
  84. data/lib/schema/xml.xsd +7 -8
  85. data/test/#benchmark.txt# +7 -0
  86. data/test/#tc_helper.rb# +3 -0
  87. data/test/benchmark.rb +81 -0
  88. data/test/benchmark.rb~ +0 -0
  89. data/test/benchmark.txt +6 -0
  90. data/test/benchmark.txt~ +6 -0
  91. data/test/content_type/tc_content_type.rb +30 -32
  92. data/test/content_type/tc_default.rb +8 -23
  93. data/test/content_type/tc_override.rb +7 -21
  94. data/test/doc_props/tc_app.rb +2 -8
  95. data/test/doc_props/tc_core.rb +6 -7
  96. data/test/drawing/tc_axis.rb +7 -3
  97. data/test/drawing/tc_bar_3D_chart.rb +6 -7
  98. data/test/drawing/tc_bar_series.rb +4 -5
  99. data/test/drawing/tc_cat_axis.rb +2 -3
  100. data/test/drawing/tc_cat_axis_data.rb +2 -3
  101. data/test/drawing/tc_chart.rb +13 -14
  102. data/test/drawing/tc_drawing.rb +7 -8
  103. data/test/drawing/tc_graphic_frame.rb +3 -4
  104. data/test/drawing/tc_hyperlink.rb +2 -3
  105. data/test/drawing/tc_line_3d_chart.rb +5 -6
  106. data/test/drawing/tc_line_series.rb +3 -4
  107. data/test/drawing/tc_marker.rb +3 -4
  108. data/test/drawing/tc_one_cell_anchor.rb +6 -7
  109. data/test/drawing/tc_pic.rb +8 -9
  110. data/test/drawing/tc_picture_locking.rb +2 -3
  111. data/test/drawing/tc_pie_3D_chart.rb +5 -6
  112. data/test/drawing/tc_pie_series.rb +4 -5
  113. data/test/drawing/tc_scaling.rb +3 -4
  114. data/test/drawing/tc_scatter_chart.rb +43 -0
  115. data/test/drawing/tc_scatter_series.rb +20 -0
  116. data/test/drawing/tc_ser_axis.rb +2 -3
  117. data/test/drawing/tc_series.rb +4 -5
  118. data/test/drawing/tc_series_title.rb +4 -5
  119. data/test/drawing/tc_title.rb +4 -5
  120. data/test/drawing/tc_two_cell_anchor.rb +4 -5
  121. data/test/drawing/tc_val_axis.rb +2 -3
  122. data/test/drawing/tc_val_axis_data.rb +2 -3
  123. data/test/drawing/tc_view_3D.rb +6 -7
  124. data/test/example.csv +1000 -0
  125. data/test/example.xlsx +0 -0
  126. data/test/example_streamed.xlsx +0 -0
  127. data/test/profile.rb +33 -0
  128. data/test/rels/tc_relationship.rb +5 -6
  129. data/test/rels/tc_relationships.rb +4 -5
  130. data/test/stylesheet/tc_border.rb +3 -4
  131. data/test/stylesheet/tc_border_pr.rb +3 -4
  132. data/test/stylesheet/tc_cell_alignment.rb +10 -6
  133. data/test/stylesheet/tc_cell_protection.rb +2 -3
  134. data/test/stylesheet/tc_cell_style.rb +2 -3
  135. data/test/stylesheet/tc_color.rb +2 -3
  136. data/test/stylesheet/tc_fill.rb +1 -2
  137. data/test/stylesheet/tc_font.rb +12 -5
  138. data/test/stylesheet/tc_gradient_fill.rb +1 -2
  139. data/test/stylesheet/tc_gradient_stop.rb +1 -2
  140. data/test/stylesheet/tc_num_fmt.rb +1 -2
  141. data/test/stylesheet/tc_pattern_fill.rb +3 -4
  142. data/test/stylesheet/tc_styles.rb +16 -6
  143. data/test/stylesheet/tc_table_style.rb +2 -3
  144. data/test/stylesheet/tc_table_style_element.rb +2 -3
  145. data/test/stylesheet/tc_table_styles.rb +3 -4
  146. data/test/stylesheet/tc_xf.rb +16 -17
  147. data/test/tc_axlsx.rb +39 -0
  148. data/test/tc_axlsx.rb~ +0 -0
  149. data/test/tc_helper.rb +3 -0
  150. data/test/tc_helper.rb~ +3 -0
  151. data/test/tc_package.rb +13 -10
  152. data/test/util/tc_simple_typed_list.rb +8 -9
  153. data/test/util/tc_validators.rb +7 -8
  154. data/test/workbook/tc_shared_strings_table.rb +5 -6
  155. data/test/workbook/tc_workbook.rb +24 -6
  156. data/test/workbook/worksheet/table/tc_table.rb +71 -0
  157. data/test/workbook/worksheet/table/tc_table.rb~ +72 -0
  158. data/test/workbook/worksheet/tc_cell.rb +62 -18
  159. data/test/workbook/worksheet/tc_col.rb +59 -0
  160. data/test/workbook/worksheet/tc_col.rb~ +10 -0
  161. data/test/workbook/worksheet/tc_date_time_converter.rb +126 -0
  162. data/test/workbook/worksheet/tc_page_margins.rb +97 -0
  163. data/test/workbook/worksheet/tc_row.rb +54 -4
  164. data/test/workbook/worksheet/tc_worksheet.rb +177 -34
  165. metadata +69 -41
  166. data/test/drawing/tc_hyperlink.rb~ +0 -71
  167. data/test/workbook/tc_shared_strings_table.rb~ +0 -8
@@ -26,7 +26,7 @@ module Axlsx
26
26
  attr_reader :drawing
27
27
 
28
28
 
29
- # Creates a new TwoCellAnchor object and sets up a reference to the from and to markers in the
29
+ # Creates a new TwoCellAnchor object and sets up a reference to the from and to markers in the
30
30
  # graphic_frame's chart. That means that you can do stuff like
31
31
  # c = worksheet.add_chart Axlsx::Chart
32
32
  # c.start_at 5, 9
@@ -38,13 +38,13 @@ module Axlsx
38
38
  # @option options [Array] end_at the col, row to end at
39
39
  def initialize(drawing, options={})
40
40
  @drawing = drawing
41
- drawing.anchors << self
41
+ drawing.anchors << self
42
42
  @from, @to = Marker.new, Marker.new(:col => 5, :row=>10)
43
43
  end
44
44
 
45
45
  # Creates a graphic frame and chart object associated with this anchor
46
46
  # @return [Chart]
47
- def add_chart(chart_type, options)
47
+ def add_chart(chart_type, options)
48
48
  @object = GraphicFrame.new(self, chart_type, options)
49
49
  @object.chart
50
50
  end
@@ -54,24 +54,22 @@ module Axlsx
54
54
  def index
55
55
  @drawing.anchors.index(self)
56
56
  end
57
- # Serializes the two cell anchor
58
- # @param [Nokogiri::XML::Builder] xml The document builder instance this objects xml will be added to.
59
- # @return [String]
60
- def to_xml(xml)
61
- #build it for now, break it down later!
62
- xml[:xdr].twoCellAnchor {
63
- xml.from {
64
- from.to_xml(xml)
65
- }
66
- xml.to {
67
- to.to_xml(xml)
68
- }
69
- @object.to_xml(xml)
70
- xml.clientData
71
- }
72
- end
73
57
 
74
- private
58
+ # Serializes the object
59
+ # @param [String] str
60
+ # @return [String]
61
+ def to_xml_string(str = '')
62
+ str << '<xdr:twoCellAnchor>'
63
+ str << '<xdr:from>'
64
+ from.to_xml_string str
65
+ str << '</xdr:from>'
66
+ str << '<xdr:to>'
67
+ to.to_xml_string str
68
+ str << '</xdr:to>'
69
+ object.to_xml_string(str)
70
+ str << '<xdr:clientData/>'
71
+ str << '</xdr:twoCellAnchor>'
72
+ end
75
73
 
76
74
  end
77
75
  end
@@ -22,14 +22,15 @@ module Axlsx
22
22
  # @see crossBetween
23
23
  def crossBetween=(v) RestrictionValidator.validate "ValAxis.crossBetween", [:between, :midCat], v; @crossBetween = v; end
24
24
 
25
- # Serializes the value axis
26
- # @param [Nokogiri::XML::Builder] xml The document builder instance this objects xml will be added to.
25
+ # Serializes the object
26
+ # @param [String] str
27
27
  # @return [String]
28
- def to_xml(xml)
29
- xml.valAx {
30
- super(xml)
31
- xml.crossBetween :val=>@crossBetween
32
- }
28
+ def to_xml_string(str = '')
29
+ str << '<c:valAx>'
30
+ super(str)
31
+ str << '<c:crossBetween val="' << @crossBetween.to_s << '"/>'
32
+ str << '</c:valAx>'
33
33
  end
34
+
34
35
  end
35
36
  end
@@ -3,25 +3,25 @@ module Axlsx
3
3
  # The ValAxisData class manages the values for a chart value series.
4
4
  class ValAxisData < CatAxisData
5
5
 
6
- # Serializes the value axis data
7
- # @param [Nokogiri::XML::Builder] xml The document builder instance this objects xml will be added to.
6
+ # Serializes the object
7
+ # @param [String] str
8
8
  # @return [String]
9
- def to_xml(xml)
10
- xml.val {
11
- xml.numRef {
12
- xml.f Axlsx::cell_range(@list)
13
- xml.numCache {
14
- xml.formatCode 'General'
15
- xml.ptCount :val=>size
16
- each_with_index do |item, index|
17
- v = item.is_a?(Cell) ? item.value : item
18
- xml.pt(:idx=>index) { xml.v v }
19
- end
20
- }
21
- }
22
- }
9
+ def to_xml_string(str = '')
10
+ str << '<c:val>'
11
+ str << '<c:numRef>'
12
+ str << '<c:f>' << Axlsx::cell_range(@list) << '</c:f>'
13
+ str << '<c:numCache>'
14
+ str << '<c:formatCode>General</c:formatCode>'
15
+ str << '<c:ptCount val="' << size.to_s << '"/>'
16
+ each_with_index do |item, index|
17
+ v = item.is_a?(Cell) ? item.value.to_s : item
18
+ str << '<c:pt idx="' << index.to_s << '"><c:v>' << v << '</c:v></c:pt>'
19
+ end
20
+ str << '</c:numCache>'
21
+ str << '</c:numRef>'
22
+ str << '</c:val>'
23
23
  end
24
24
 
25
25
  end
26
-
26
+
27
27
  end
@@ -5,34 +5,34 @@ module Axlsx
5
5
 
6
6
  # Validation for hPercent
7
7
  H_PERCENT_REGEX = /0*(([5-9])|([1-9][0-9])|([1-4][0-9][0-9])|500)%/
8
-
8
+
9
9
  # validation for depthPercent
10
10
  DEPTH_PERCENT_REGEX = /0*(([2-9][0-9])|([1-9][0-9][0-9])|(1[0-9][0-9][0-9])|2000)%/
11
11
 
12
- # x rotation for the chart
12
+ # x rotation for the chart
13
13
  # must be between -90 and 90
14
14
  # @return [Integer]
15
15
  attr_reader :rotX
16
-
16
+
17
17
  # height of chart as % of chart
18
18
  # must be between 5% and 500%
19
19
  # @return [String]
20
20
  attr_reader :hPercent
21
-
21
+
22
22
  # y rotation for the chart
23
23
  # must be between 0 and 360
24
24
  # @return [Integer]
25
25
  attr_reader :rotY
26
-
26
+
27
27
  # depth or chart as % of chart width
28
28
  # must be between 20% and 2000%
29
29
  # @return [String]
30
30
  attr_reader :depthPercent
31
-
31
+
32
32
  # Chart axis are at right angles
33
33
  # @return [Boolean]
34
34
  attr_reader :rAngAx
35
-
35
+
36
36
  # field of view angle
37
37
  # @return [Integer]
38
38
  attr_reader :perspective
@@ -45,10 +45,10 @@ module Axlsx
45
45
  # @option options [Boolean] rAngAx
46
46
  # @option options [Integer] perspective
47
47
  def initialize(options={})
48
- @rotX, @hPercent, @rotY, @depthPercent, @rAngAx, @perspective = nil, nil, nil, nil, nil, nil
48
+ @rotX, @hPercent, @rotY, @depthPercent, @rAngAx, @perspective = nil, nil, nil, nil, nil, nil
49
49
  options.each do |o|
50
50
  self.send("#{o[0]}=", o[1]) if self.respond_to? "#{o[0]}="
51
- end
51
+ end
52
52
  end
53
53
 
54
54
  # @see rotX
@@ -69,18 +69,20 @@ module Axlsx
69
69
  # @see perspective
70
70
  def perspective=(v) DataTypeValidator.validate "#{self.class}.perspective", [Integer, Fixnum], v, lambda {|arg| arg >= 0 && arg <= 240 }; @perspective = v; end
71
71
 
72
- # Serializes the view3D properties
73
- # @param [Nokogiri::XML::Builder] xml The document builder instance this objects xml will be added to.
72
+
73
+ # Serializes the object
74
+ # @param [String] str
74
75
  # @return [String]
75
- def to_xml(xml)
76
- xml[:c].view3D {
77
- xml[:c].rotX :val=>@rotX unless @rotX.nil?
78
- xml[:c].hPercent :val=>@hPercent unless @hPercent.nil?
79
- xml[:c].rotY :val=>@rotY unless @rotY.nil?
80
- xml[:c].depthPercent :val=>@depthPercent unless @depthPercent.nil?
81
- xml[:c].rAngAx :val=>@rAngAx unless @rAngAx.nil?
82
- xml[:c].perspective :val=>@perspective unless @perspective.nil?
83
- }
76
+ def to_xml_string(str = '')
77
+ str << '<c:view3D>'
78
+ str << '<c:rotX val="' << @rotX.to_s << '"/>' unless @rotX.nil?
79
+ str << '<c:hPercent val="' << @hPercent.to_s << '"/>' unless @hPercent.nil?
80
+ str << '<c:rotY val="' << @rotY.to_s << '"/>' unless @rotY.nil?
81
+ str << '<c:depthPercent val="' << @depthPercent.to_s << '"/>' unless @depthPercent.nil?
82
+ str << '<c:rAngAx val="' << @rAngAx.to_s << '"/>' unless @rAngAx.nil?
83
+ str << '<c:perspective val="' << @perspective.to_s << '"/>' unless @perspective.nil?
84
+ str << '</c:view3D>'
84
85
  end
86
+
85
87
  end
86
88
  end
data/lib/axlsx/package.rb CHANGED
@@ -4,7 +4,7 @@ module Axlsx
4
4
  # xlsx document including valdation and serialization.
5
5
  class Package
6
6
 
7
-
7
+
8
8
  # provides access to the app doc properties for this package
9
9
  # see App
10
10
  attr_reader :app
@@ -29,10 +29,18 @@ module Axlsx
29
29
  yield self if block_given?
30
30
  end
31
31
 
32
+ # Shortcut to specify that the workbook should use autowidth
33
+ # @see Workbook#use_autowidth
34
+ def use_autowidth=(v)
35
+ Axlsx::validate_boolean(v);
36
+ workbook.use_autowidth = v
37
+ end
38
+
39
+
32
40
  # Shortcut to specify that the workbook should use shared strings
33
41
  # @see Workbook#use_shared_strings
34
- def use_shared_strings=(v)
35
- Axlsx::validate_boolean(v);
42
+ def use_shared_strings=(v)
43
+ Axlsx::validate_boolean(v);
36
44
  workbook.use_shared_strings = v
37
45
  end
38
46
 
@@ -45,7 +53,7 @@ module Axlsx
45
53
  # The workbook this package will serialize or validate.
46
54
  # @return [Workbook] If no workbook instance has been assigned with this package a new Workbook instance is returned.
47
55
  # @raise ArgumentError if workbook parameter is not a Workbook instance.
48
- # @note As there are multiple ways to instantiate a workbook for the package,
56
+ # @note As there are multiple ways to instantiate a workbook for the package,
49
57
  # here are a few examples:
50
58
  # # assign directly during package instanciation
51
59
  # wb = Package.new(:workbook => Workbook.new).workbook
@@ -59,13 +67,13 @@ module Axlsx
59
67
  yield @workbook if block_given?
60
68
  @workbook
61
69
  end
62
-
70
+
63
71
  #def self.parse(input, confirm_valid = false)
64
72
  # p = Package.new
65
73
  # z = Zip::ZipFile.open(input)
66
74
  # p.workbook = Workbook.parse z.get_entry(WORKBOOK_PN)
67
75
  # p
68
- #end
76
+ #end
69
77
 
70
78
  # @see workbook
71
79
  def workbook=(workbook) DataTypeValidator.validate "Package.workbook", Workbook, workbook; @workbook = workbook; end
@@ -77,7 +85,7 @@ module Axlsx
77
85
  # @option options stream indicates if we should be writing to a stream or a file. True for stream, nil for file
78
86
  # @return [Boolean] False if confirm_valid and validation errors exist. True if the package was serialized
79
87
  # @note A tremendous amount of effort has gone into ensuring that you cannot create invalid xlsx documents.
80
- # confirm_valid should be used in the rare case that you cannot open the serialized file.
88
+ # confirm_valid should be used in the rare case that you cannot open the serialized file.
81
89
  # @see Package#validate
82
90
  # @example
83
91
  # # This is how easy it is to create a valid xlsx file. Of course you might want to add a sheet or two, and maybe some data, styles and charts.
@@ -105,20 +113,20 @@ module Axlsx
105
113
  stream.rewind
106
114
  stream
107
115
  end
108
-
116
+
109
117
  # Encrypt the package into a CFB using the password provided
110
118
  # This is not ready yet
111
- def encrypt(file_name, password)
119
+ def encrypt(file_name, password)
112
120
  return false
113
- moc = MsOffCrypto.new(file_name, password)
114
- moc.save
121
+ # moc = MsOffCrypto.new(file_name, password)
122
+ # moc.save
115
123
  end
116
-
117
- # Validate all parts of the package against xsd schema.
124
+
125
+ # Validate all parts of the package against xsd schema.
118
126
  # @return [Array] An array of all validation errors found.
119
127
  # @note This gem includes all schema from OfficeOpenXML-XMLSchema-Transitional.zip and OpenPackagingConventions-XMLSchema.zip
120
128
  # as per ECMA-376, Third edition. opc schema require an internet connection to import remote schema from dublin core for dc,
121
- # dcterms and xml namespaces. Those remote schema are included in this gem, and the original files have been altered to
129
+ # dcterms and xml namespaces. Those remote schema are included in this gem, and the original files have been altered to
122
130
  # refer to the local versions.
123
131
  #
124
132
  # If by chance you are able to creat a package that does not validate it indicates that the internal
@@ -131,65 +139,71 @@ module Axlsx
131
139
  # p.validate.each { |error| puts error.message }
132
140
  def validate
133
141
  errors = []
134
- parts.each { |part| errors.concat validate_single_doc(part[:schema], part[:doc]) unless part[:schema].nil? }
142
+ parts.each do |part|
143
+ errors.concat validate_single_doc(part[:schema], part[:doc]) unless part[:schema].nil?
144
+ end
135
145
  errors
136
146
  end
137
147
 
138
- private
148
+ private
139
149
 
140
150
  # Writes the package parts to a zip archive.
141
151
  # @param [Zip::ZipOutputStream] zip
142
152
  # @return [Zip::ZipOutputStream]
143
153
  def write_parts(zip)
144
154
  p = parts
145
- p.each do |part|
155
+ p.each do |part|
146
156
  unless part[:doc].nil?
147
157
  zip.put_next_entry(part[:entry]);
148
158
  entry = ['1.9.2', '1.9.3'].include?(RUBY_VERSION) ? part[:doc].force_encoding('BINARY') : part[:doc]
149
159
  zip.puts(entry)
150
160
  end
151
161
  unless part[:path].nil?
152
- zip.put_next_entry(part[:entry]);
162
+ zip.put_next_entry(part[:entry]);
153
163
  # binread for 1.9.3
154
164
  zip.write IO.respond_to?(:binread) ? IO.binread(part[:path]) : IO.read(part[:path])
155
- end
165
+ end
156
166
  end
157
167
  zip
158
168
  end
159
169
 
160
170
  # The parts of a package
161
- # @return [Array] An array of hashes that define the entry, document and schema for each part of the package.
171
+ # @return [Array] An array of hashes that define the entry, document and schema for each part of the package.
162
172
  # @private
163
173
  def parts
164
174
  @parts = [
165
- {:entry => RELS_PN, :doc => relationships.to_xml, :schema => RELS_XSD},
166
- {:entry => "xl/#{STYLES_PN}", :doc => workbook.styles.to_xml, :schema => SML_XSD},
167
- {:entry => CORE_PN, :doc => @core.to_xml, :schema => CORE_XSD},
168
- {:entry => APP_PN, :doc => @app.to_xml, :schema => APP_XSD},
169
- {:entry => WORKBOOK_RELS_PN, :doc => workbook.relationships.to_xml, :schema => RELS_XSD},
170
- {:entry => CONTENT_TYPES_PN, :doc => content_types.to_xml, :schema => CONTENT_TYPES_XSD},
171
- {:entry => WORKBOOK_PN, :doc => workbook.to_xml, :schema => SML_XSD}
175
+ {:entry => RELS_PN, :doc => relationships.to_xml_string, :schema => RELS_XSD},
176
+ {:entry => "xl/#{STYLES_PN}", :doc => workbook.styles.to_xml_string, :schema => SML_XSD},
177
+ {:entry => CORE_PN, :doc => @core.to_xml_string, :schema => CORE_XSD},
178
+ {:entry => APP_PN, :doc => @app.to_xml_string, :schema => APP_XSD},
179
+ {:entry => WORKBOOK_RELS_PN, :doc => workbook.relationships.to_xml_string, :schema => RELS_XSD},
180
+ {:entry => CONTENT_TYPES_PN, :doc => content_types.to_xml_string, :schema => CONTENT_TYPES_XSD},
181
+ {:entry => WORKBOOK_PN, :doc => workbook.to_xml_string, :schema => SML_XSD}
172
182
  ]
173
183
  workbook.drawings.each do |drawing|
174
- @parts << {:entry => "xl/#{drawing.rels_pn}", :doc => drawing.relationships.to_xml, :schema => RELS_XSD}
175
- @parts << {:entry => "xl/#{drawing.pn}", :doc => drawing.to_xml, :schema => DRAWING_XSD}
184
+ @parts << {:entry => "xl/#{drawing.rels_pn}", :doc => drawing.relationships.to_xml_string, :schema => RELS_XSD}
185
+ @parts << {:entry => "xl/#{drawing.pn}", :doc => drawing.to_xml_string, :schema => DRAWING_XSD}
186
+ end
187
+
188
+ workbook.tables.each do |table|
189
+ @parts << {:entry => "xl/#{table.pn}", :doc => table.to_xml_string, :schema => SML_XSD}
190
+ end
191
+
192
+ workbook.charts.each do |chart|
193
+ @parts << {:entry => "xl/#{chart.pn}", :doc => chart.to_xml_string, :schema => DRAWING_XSD}
176
194
  end
177
-
178
- workbook.charts.each do |chart|
179
- @parts << {:entry => "xl/#{chart.pn}", :doc => chart.to_xml, :schema => DRAWING_XSD}
180
- end
181
195
 
182
196
  workbook.images.each do |image|
183
197
  @parts << {:entry => "xl/#{image.pn}", :path => image.image_src}
184
198
  end
185
199
 
186
200
  if use_shared_strings
187
- @parts << {:entry => "xl/#{SHARED_STRINGS_PN}", :doc => workbook.shared_strings.to_xml, :schema => SML_XSD}
201
+ @parts << {:entry => "xl/#{SHARED_STRINGS_PN}", :doc => workbook.shared_strings.to_xml_string, :schema => SML_XSD}
188
202
  end
189
203
 
190
- workbook.worksheets.each do |sheet|
191
- @parts << {:entry => "xl/#{sheet.rels_pn}", :doc => sheet.relationships.to_xml, :schema => RELS_XSD}
192
- @parts << {:entry => "xl/#{sheet.pn}", :doc => sheet.to_xml, :schema => SML_XSD}
204
+ workbook.worksheets.each do |sheet|
205
+ @parts << {:entry => "xl/#{sheet.rels_pn}", :doc => sheet.relationships.to_xml_string, :schema => RELS_XSD}
206
+ @parts << {:entry => "xl/#{sheet.pn}", :doc => sheet.to_xml_string, :schema => SML_XSD}
193
207
  end
194
208
  @parts
195
209
  end
@@ -203,7 +217,6 @@ module Axlsx
203
217
  def validate_single_doc(schema, doc)
204
218
  schema = Nokogiri::XML::Schema(File.open(schema))
205
219
  doc = Nokogiri::XML(doc)
206
-
207
220
  errors = []
208
221
  schema.validate(doc).each do |error|
209
222
  errors << error
@@ -217,15 +230,19 @@ module Axlsx
217
230
  def content_types
218
231
  c_types = base_content_types
219
232
  workbook.drawings.each do |drawing|
220
- c_types << Axlsx::Override.new(:PartName => "/xl/#{drawing.pn}",
233
+ c_types << Axlsx::Override.new(:PartName => "/xl/#{drawing.pn}",
221
234
  :ContentType => DRAWING_CT)
222
235
  end
223
236
  workbook.charts.each do |chart|
224
- c_types << Axlsx::Override.new(:PartName => "/xl/#{chart.pn}",
225
- :ContentType => CHART_CT)
237
+ c_types << Axlsx::Override.new(:PartName => "/xl/#{chart.pn}",
238
+ :ContentType => CHART_CT)
239
+ end
240
+ workbook.tables.each do |table|
241
+ c_types << Axlsx::Override.new(:PartName => "/xl/#{table.pn}",
242
+ :ContentType => TABLE_CT)
226
243
  end
227
244
  workbook.worksheets.each do |sheet|
228
- c_types << Axlsx::Override.new(:PartName => "/xl/#{sheet.pn}",
245
+ c_types << Axlsx::Override.new(:PartName => "/xl/#{sheet.pn}",
229
246
  :ContentType => WORKSHEET_CT)
230
247
  end
231
248
  exts = workbook.images.map { |image| image.extname }
@@ -256,7 +273,7 @@ module Axlsx
256
273
  c_types << Override.new(:PartName => "/#{APP_PN}", :ContentType => APP_CT)
257
274
  c_types << Override.new(:PartName => "/#{CORE_PN}", :ContentType => CORE_CT)
258
275
  c_types << Override.new(:PartName => "/xl/#{STYLES_PN}", :ContentType => STYLES_CT)
259
- c_types << Axlsx::Override.new(:PartName => "/#{WORKBOOK_PN}", :ContentType => WORKBOOK_CT)
276
+ c_types << Axlsx::Override.new(:PartName => "/#{WORKBOOK_PN}", :ContentType => WORKBOOK_CT)
260
277
  c_types.lock
261
278
  c_types
262
279
  end
@@ -1,7 +1,7 @@
1
1
  # encoding: UTF-8
2
2
  module Axlsx
3
3
  # A relationship defines a reference between package parts.
4
- # @note Packages automatcially manage relationships.
4
+ # @note Packages automatically manage relationships.
5
5
  class Relationship
6
6
 
7
7
  # The location of the relationship target
@@ -32,7 +32,7 @@ module Axlsx
32
32
  # creates a new relationship
33
33
  # @param [String] Type The type of the relationship
34
34
  # @param [String] Target The target for the relationship
35
- # @option [Symbol] target_mode only accepts :external.
35
+ # @option [Symbol] target_mode only accepts :external.
36
36
  def initialize(type, target, options={})
37
37
  self.Target=target
38
38
  self.Type=type
@@ -47,14 +47,17 @@ module Axlsx
47
47
  # @see TargetMode
48
48
  def TargetMode=(v) RestrictionValidator.validate 'Relationship.TargetMode', [:External, :Internal], v; @TargetMode = v; end
49
49
 
50
- # Serializes the relationship
51
- # @param [Nokogiri::XML::Builder] xml The document builder instance this objects xml will be added to.
52
- # @param [String] rId the reference id of the object.
50
+ # serialize relationship
51
+ # @param [String] str
52
+ # @param [Integer] rId the id for this relationship
53
53
  # @return [String]
54
- def to_xml(xml, rId)
54
+ def to_xml_string(rId, str = '')
55
55
  h = self.instance_values
56
- h[:Id] = rId
57
- xml.Relationship(h)
56
+ h[:Id] = 'rId' << rId.to_s
57
+ str << '<Relationship '
58
+ str << h.map { |key, value| '' << key.to_s << '="' << value.to_s << '"'}.join(' ')
59
+ str << '/>'
58
60
  end
61
+
59
62
  end
60
63
  end
@@ -11,6 +11,12 @@ require 'axlsx/rels/relationship.rb'
11
11
  super Relationship
12
12
  end
13
13
 
14
+ def to_xml_string(str = '')
15
+ str << '<?xml version="1.0" encoding="UTF-8"?>'
16
+ str << '<Relationships xmlns="' << RELS_R << '">'
17
+ each_with_index { |rel, index| rel.to_xml_string(index+1, str) }
18
+ str << '</Relationships>'
19
+ end
14
20
  # Serializes the relationships document.
15
21
  # @return [String]
16
22
  def to_xml()
@@ -21,6 +27,6 @@ require 'axlsx/rels/relationship.rb'
21
27
  end
22
28
  builder.to_xml(:save_with => 0)
23
29
  end
24
-
30
+
25
31
  end
26
32
  end
@@ -0,0 +1,69 @@
1
+ # encoding: UTF-8
2
+ module Axlsx
3
+ # A NumFmt object defines an identifier and formatting code for data in cells.
4
+ # @note The recommended way to manage styles is Styles#add_style
5
+ class NumFmt
6
+ # @return [Integer] An unsinged integer referencing a standard or custom number format.
7
+ # @note
8
+ # These are the known formats I can dig up. The constant NUM_FMT_PERCENT is 9, and uses the default % formatting. Axlsx also defines a few formats for date and time that are commonly used in asia as NUM_FMT_YYYYMMDD and NUM_FRM_YYYYMMDDHHMMSS.
9
+ # 1 0
10
+ # 2 0.00
11
+ # 3 #,##0
12
+ # 4 #,##0.00
13
+ # 5 $#,##0_);($#,##0)
14
+ # 6 $#,##0_);[Red]($#,##0)
15
+ # 7 $#,##0.00_);($#,##0.00)
16
+ # 8 $#,##0.00_);[Red]($#,##0.00)
17
+ # 9 0%
18
+ # 10 0.00%
19
+ # 11 0.00E+00
20
+ # 12 # ?/?
21
+ # 13 # ??/??
22
+ # 14 m/d/yyyy
23
+ # 15 d-mmm-yy
24
+ # 16 d-mmm
25
+ # 17 mmm-yy
26
+ # 18 h:mm AM/PM
27
+ # 19 h:mm:ss AM/PM
28
+ # 20 h:mm
29
+ # 21 h:mm:ss
30
+ # 22 m/d/yyyy h:mm
31
+ # 37 #,##0_);(#,##0)
32
+ # 38 #,##0_);[Red](#,##0)
33
+ # 39 #,##0.00_);(#,##0.00)
34
+ # 40 #,##0.00_);[Red](#,##0.00)
35
+ # 45 mm:ss
36
+ # 46 [h]:mm:ss
37
+ # 47 mm:ss.0
38
+ # 48 ##0.0E+0
39
+ # 49 @
40
+ # @see Axlsx
41
+ attr_reader :numFmtId
42
+
43
+ # @return [String] The formatting to use for this number format.
44
+ # @see http://support.microsoft.com/kb/264372
45
+ attr_reader :formatCode
46
+ def initialize(options={})
47
+ @numFmtId = 0
48
+ @formatCode = ""
49
+ options.each do |o|
50
+ self.send("#{o[0]}=", o[1]) if self.respond_to? o[0]
51
+ end
52
+ end
53
+
54
+ # @see numFmtId
55
+ def numFmtId=(v) Axlsx::validate_unsigned_int v; @numFmtId = v end
56
+ # @see formatCode
57
+ def formatCode=(v) Axlsx::validate_string v; @formatCode = v end
58
+
59
+ # Serializes the object
60
+ # @param [String] str
61
+ # @return [String]
62
+ def to_xml_string(str = '')
63
+ str << '<numFmt '
64
+ str << instance_values.map { |key, value| '' << key.to_s << '="' << value.to_s << '"' }.join(' ')
65
+ str << '/>'
66
+ end
67
+
68
+ end
69
+ end
@@ -3,38 +3,37 @@ module Axlsx
3
3
  # This class details a border used in Office Open XML spreadsheet styles.
4
4
  class Border
5
5
 
6
- # @return [Boolean] The diagonal up property for the border that indicates if the border should include a diagonal line from the bottom left to the top right of the cell.
6
+ # @return [Boolean] The diagonal up property for the border that indicates if the border should include a diagonal line from the bottom left to the top right of the cell.
7
7
  attr_reader :diagonalUp
8
-
8
+
9
9
  # @return [Boolean] The diagonal down property for the border that indicates if the border should include a diagonal line from the top left to the top right of the cell.
10
10
  attr_reader :diagonalDown
11
11
 
12
12
  # @return [Boolean] The outline property for the border indicating that top, left, right and bottom borders should only be applied to the outside border of a range of cells.
13
13
  attr_reader :outline
14
14
 
15
- # @return [SimpleTypedList] A list of BorderPr objects for this border.
15
+ # @return [SimpleTypedList] A list of BorderPr objects for this border.
16
16
  attr_reader :prs
17
17
 
18
18
  # Creates a new Border object
19
19
  # @option options [Boolean] diagonalUp
20
20
  # @option options [Boolean] diagonalDown
21
21
  # @option options [Boolean] outline
22
- # @example Making a border
23
- # p = Package.new
24
- # red_border = Border.new
25
- # [:left, :right, :top, :bottom].each do |item|
26
- # red_border.prs << BorderPr.new(:name=>item, :style=>:thin, :color=>Color.new(:rgb=>"FFFF0000")) #
27
- # end
28
- # # this sets red_border to be the index for the created border.
29
- # red_border = p.workbook.styles.@borders << red_border
30
- # #used in row creation as follows. This will add a red border to each of the cells in the row.
31
- # p.workbook.add_worksheet.rows << :values=>[1,2,3] :style=>red_border
22
+ # @example - Making a border
23
+ # p = Axlsx::Package.new
24
+ # red_border = p.workbook.styles.add_style :border => { :style => :thin, :color => "FFFF0000" }
25
+ # ws = p.workbook.add_worksheet
26
+ # ws.add_row [1,2,3], :style => red_border
27
+ # p.serialize('red_border.xlsx')
28
+ #
29
+ # @note The recommended way to manage borders is with Style#add_style
30
+ # @see Style#add_style
32
31
  def initialize(options={})
33
32
  @prs = SimpleTypedList.new BorderPr
34
33
  options.each do |o|
35
34
  self.send("#{o[0]}=", o[1]) if self.respond_to? "#{o[0]}="
36
35
  end
37
- end
36
+ end
38
37
 
39
38
  # @see diagonalUp
40
39
  def diagonalUp=(v) Axlsx::validate_boolean v; @diagonalUp = v end
@@ -43,16 +42,21 @@ module Axlsx
43
42
  # @see outline
44
43
  def outline=(v) Axlsx::validate_boolean v; @outline = v end
45
44
 
46
- # Serializes the border element
47
- # @param [Nokogiri::XML::Builder] xml The document builder instance this objects xml will be added to.
48
- def to_xml(xml)
49
- xml.border(self.instance_values.select{ |k,v| [:diagonalUp, :diagonalDown, :outline].include? k }) {
50
- [:start, :end, :left, :right, :top, :bottom, :diagonal, :vertical, :horizontal].each do |k|
51
- @prs.select { |pr| pr.name == k }.each do |part|
52
- part.to_xml(xml)
53
- end
45
+ # Serializes the object
46
+ # @param [String] str
47
+ # @return [String]
48
+ def to_xml_string(str = '')
49
+ str << '<border '
50
+ h = self.instance_values.select{ |k,v| [:diagonalUp, :diagonalDown, :outline].include? k }
51
+ str << h.map { |key, value| '' << key.to_s << '="' << value.to_s << '"' }.join(' ')
52
+ str << '>'
53
+ [:start, :end, :left, :right, :top, :bottom, :diagonal, :vertical, :horizontal].each do |k|
54
+ @prs.select { |pr| pr.name == k }.each do |part|
55
+ part.to_xml_string(str)
54
56
  end
55
- }
57
+ end
58
+ str << '</border>'
56
59
  end
60
+
57
61
  end
58
62
  end