axlsx 1.1.0 → 1.2.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 (214) hide show
  1. data/.yardopts +5 -2
  2. data/CHANGELOG.md +78 -0
  3. data/LICENSE +1 -1
  4. data/README.md +132 -331
  5. data/Rakefile +17 -5
  6. data/examples/basic_charts.rb +54 -0
  7. data/examples/chart_colors.rb +88 -0
  8. data/examples/conditional_formatting/example_conditional_formatting.rb +72 -0
  9. data/examples/conditional_formatting/getting_barred.rb +37 -0
  10. data/examples/conditional_formatting/hitting_the_high_notes.rb +37 -0
  11. data/examples/conditional_formatting/scaled_colors.rb +39 -0
  12. data/examples/conditional_formatting/stop_and_go.rb +37 -0
  13. data/examples/data_validation.rb +50 -0
  14. data/examples/example.rb +300 -152
  15. data/examples/example.xlsx +0 -0
  16. data/examples/example_streamed.xlsx +0 -0
  17. data/examples/extractive.pdf +0 -0
  18. data/examples/extractive.rb +45 -0
  19. data/examples/no-use_autowidth.xlsx +0 -0
  20. data/examples/sample.png +0 -0
  21. data/examples/scraping_html.rb +91 -0
  22. data/examples/shared_strings_example.xlsx +0 -0
  23. data/examples/sheet_protection.rb +10 -0
  24. data/examples/sheet_view.rb +34 -0
  25. data/examples/skydrive/real_example.rb +63 -0
  26. data/examples/two_cell_anchor_image.rb +11 -0
  27. data/lib/axlsx/content_type/content_type.rb +2 -0
  28. data/lib/axlsx/content_type/default.rb +30 -15
  29. data/lib/axlsx/content_type/override.rb +29 -14
  30. data/lib/axlsx/doc_props/app.rb +161 -104
  31. data/lib/axlsx/doc_props/core.rb +9 -5
  32. data/lib/axlsx/drawing/ax_data_source.rb +26 -0
  33. data/lib/axlsx/drawing/axis.rb +106 -35
  34. data/lib/axlsx/drawing/bar_3D_chart.rb +49 -45
  35. data/lib/axlsx/drawing/bar_series.rb +25 -7
  36. data/lib/axlsx/drawing/cat_axis.rb +50 -22
  37. data/lib/axlsx/drawing/chart.rb +69 -56
  38. data/lib/axlsx/drawing/d_lbls.rb +100 -0
  39. data/lib/axlsx/drawing/drawing.rb +28 -12
  40. data/lib/axlsx/drawing/graphic_frame.rb +2 -1
  41. data/lib/axlsx/drawing/line_3D_chart.rb +3 -10
  42. data/lib/axlsx/drawing/line_series.rb +20 -4
  43. data/lib/axlsx/drawing/num_data.rb +52 -0
  44. data/lib/axlsx/drawing/num_data_source.rb +61 -0
  45. data/lib/axlsx/drawing/num_val.rb +32 -0
  46. data/lib/axlsx/drawing/pic.rb +44 -4
  47. data/lib/axlsx/drawing/pie_3D_chart.rb +10 -7
  48. data/lib/axlsx/drawing/pie_series.rb +18 -4
  49. data/lib/axlsx/drawing/scatter_chart.rb +12 -18
  50. data/lib/axlsx/drawing/scatter_series.rb +28 -2
  51. data/lib/axlsx/drawing/ser_axis.rb +1 -1
  52. data/lib/axlsx/drawing/series.rb +1 -1
  53. data/lib/axlsx/drawing/str_data.rb +42 -0
  54. data/lib/axlsx/drawing/str_val.rb +33 -0
  55. data/lib/axlsx/drawing/title.rb +21 -9
  56. data/lib/axlsx/drawing/two_cell_anchor.rb +46 -9
  57. data/lib/axlsx/drawing/view_3D.rb +44 -31
  58. data/lib/axlsx/drawing/vml_drawing.rb +42 -0
  59. data/lib/axlsx/drawing/vml_shape.rb +125 -0
  60. data/lib/axlsx/package.rb +44 -16
  61. data/lib/axlsx/rels/relationship.rb +3 -3
  62. data/lib/axlsx/rels/relationships.rb +1 -11
  63. data/lib/axlsx/stylesheet/color.rb +0 -1
  64. data/lib/axlsx/stylesheet/dxf.rb +79 -0
  65. data/lib/axlsx/stylesheet/font.rb +2 -1
  66. data/lib/axlsx/stylesheet/gradient_fill.rb +1 -1
  67. data/lib/axlsx/stylesheet/styles.rb +143 -50
  68. data/lib/axlsx/stylesheet/table_style.rb +3 -3
  69. data/lib/axlsx/stylesheet/xf.rb +2 -0
  70. data/lib/axlsx/util/constants.rb +36 -0
  71. data/lib/axlsx/util/simple_typed_list.rb +15 -21
  72. data/lib/axlsx/util/validators.rb +122 -5
  73. data/lib/axlsx/version.rb +2 -7
  74. data/lib/axlsx/workbook/defined_name.rb +174 -0
  75. data/lib/axlsx/workbook/defined_names.rb +21 -0
  76. data/lib/axlsx/workbook/shared_strings_table.rb +12 -13
  77. data/lib/axlsx/workbook/workbook.rb +71 -13
  78. data/lib/axlsx/workbook/worksheet/auto_filter.rb +34 -0
  79. data/lib/axlsx/workbook/worksheet/cell.rb +45 -36
  80. data/lib/axlsx/workbook/worksheet/cfvo.rb +62 -0
  81. data/lib/axlsx/workbook/worksheet/col.rb +17 -1
  82. data/lib/axlsx/workbook/worksheet/color_scale.rb +76 -0
  83. data/lib/axlsx/workbook/worksheet/cols.rb +20 -0
  84. data/lib/axlsx/workbook/worksheet/comment.rb +101 -0
  85. data/lib/axlsx/workbook/worksheet/comments.rb +85 -0
  86. data/lib/axlsx/workbook/worksheet/conditional_formatting.rb +82 -0
  87. data/lib/axlsx/workbook/worksheet/conditional_formatting_rule.rb +216 -0
  88. data/lib/axlsx/workbook/worksheet/conditional_formattings.rb +25 -0
  89. data/lib/axlsx/workbook/worksheet/data_bar.rb +97 -0
  90. data/lib/axlsx/workbook/worksheet/data_validation.rb +245 -0
  91. data/lib/axlsx/workbook/worksheet/data_validations.rb +28 -0
  92. data/lib/axlsx/workbook/worksheet/dimension.rb +65 -0
  93. data/lib/axlsx/workbook/worksheet/icon_set.rb +83 -0
  94. data/lib/axlsx/workbook/worksheet/merged_cells.rb +35 -0
  95. data/lib/axlsx/workbook/worksheet/page_setup.rb +113 -0
  96. data/lib/axlsx/workbook/worksheet/pane.rb +144 -0
  97. data/lib/axlsx/workbook/worksheet/print_options.rb +63 -0
  98. data/lib/axlsx/workbook/worksheet/protected_range.rb +46 -0
  99. data/lib/axlsx/workbook/worksheet/protected_ranges.rb +34 -0
  100. data/lib/axlsx/workbook/worksheet/row.rb +69 -12
  101. data/lib/axlsx/workbook/worksheet/selection.rb +111 -0
  102. data/lib/axlsx/workbook/worksheet/sheet_data.rb +25 -0
  103. data/lib/axlsx/workbook/worksheet/sheet_pr.rb +24 -0
  104. data/lib/axlsx/workbook/worksheet/sheet_protection.rb +224 -0
  105. data/lib/axlsx/workbook/worksheet/sheet_view.rb +379 -0
  106. data/lib/axlsx/workbook/worksheet/table.rb +3 -3
  107. data/lib/axlsx/workbook/worksheet/tables.rb +31 -0
  108. data/lib/axlsx/workbook/worksheet/worksheet.rb +379 -233
  109. data/lib/axlsx/workbook/worksheet/worksheet_comments.rb +57 -0
  110. data/lib/axlsx/workbook/worksheet/worksheet_drawing.rb +64 -0
  111. data/lib/axlsx.rb +31 -16
  112. data/test/benchmark.rb +30 -38
  113. data/test/content_type/tc_content_type.rb +1 -6
  114. data/test/doc_props/tc_app.rb +31 -1
  115. data/test/doc_props/tc_core.rb +3 -1
  116. data/test/drawing/tc_axis.rb +46 -3
  117. data/test/drawing/tc_bar_3D_chart.rb +12 -12
  118. data/test/drawing/tc_bar_series.rb +17 -13
  119. data/test/drawing/tc_cat_axis.rb +3 -3
  120. data/test/drawing/tc_cat_axis_data.rb +23 -13
  121. data/test/drawing/tc_chart.rb +29 -11
  122. data/test/drawing/tc_d_lbls.rb +47 -0
  123. data/test/drawing/tc_data_source.rb +17 -0
  124. data/test/drawing/tc_drawing.rb +11 -5
  125. data/test/drawing/tc_hyperlink.rb +4 -5
  126. data/test/drawing/tc_line_series.rb +9 -11
  127. data/test/drawing/tc_named_axis_data.rb +27 -0
  128. data/test/drawing/tc_num_data.rb +31 -0
  129. data/test/drawing/tc_num_val.rb +29 -0
  130. data/test/drawing/tc_pic.rb +22 -2
  131. data/test/drawing/tc_pie_3D_chart.rb +4 -8
  132. data/test/drawing/tc_pie_series.rb +11 -13
  133. data/test/drawing/tc_scatter_chart.rb +6 -1
  134. data/test/drawing/tc_scatter_series.rb +6 -5
  135. data/test/drawing/tc_series.rb +1 -1
  136. data/test/drawing/tc_str_data.rb +18 -0
  137. data/test/drawing/tc_str_val.rb +21 -0
  138. data/test/drawing/tc_title.rb +16 -0
  139. data/test/drawing/tc_two_cell_anchor.rb +2 -3
  140. data/test/drawing/tc_view_3D.rb +18 -18
  141. data/test/drawing/tc_vml_drawing.rb +25 -0
  142. data/test/drawing/tc_vml_shape.rb +100 -0
  143. data/test/profile.rb +2 -1
  144. data/test/rels/tc_relationship.rb +1 -0
  145. data/test/stylesheet/tc_dxf.rb +81 -0
  146. data/test/stylesheet/tc_gradient_fill.rb +8 -0
  147. data/test/stylesheet/tc_pattern_fill.rb +7 -1
  148. data/test/stylesheet/tc_styles.rb +163 -3
  149. data/test/stylesheet/tc_table_style.rb +8 -0
  150. data/test/stylesheet/tc_table_style_element.rb +10 -1
  151. data/test/tc_helper.rb +1 -0
  152. data/test/tc_package.rb +93 -17
  153. data/test/util/tc_simple_typed_list.rb +13 -0
  154. data/test/util/tc_validators.rb +95 -9
  155. data/test/workbook/tc_defined_name.rb +41 -0
  156. data/test/workbook/tc_workbook.rb +5 -3
  157. data/test/workbook/worksheet/table/tc_table.rb +3 -11
  158. data/test/workbook/worksheet/tc_cell.rb +52 -18
  159. data/test/workbook/worksheet/tc_cfvo.rb +31 -0
  160. data/test/workbook/worksheet/tc_col.rb +9 -0
  161. data/test/workbook/worksheet/tc_color_scale.rb +29 -0
  162. data/test/workbook/worksheet/tc_comment.rb +57 -0
  163. data/test/workbook/worksheet/tc_comments.rb +57 -0
  164. data/test/workbook/worksheet/tc_conditional_formatting.rb +217 -0
  165. data/test/workbook/worksheet/tc_data_bar.rb +39 -0
  166. data/test/workbook/worksheet/tc_data_validation.rb +265 -0
  167. data/test/workbook/worksheet/tc_date_time_converter.rb +11 -5
  168. data/test/workbook/worksheet/tc_icon_set.rb +45 -0
  169. data/test/workbook/worksheet/tc_page_setup.rb +138 -0
  170. data/test/workbook/worksheet/tc_pane.rb +94 -0
  171. data/test/workbook/worksheet/tc_print_options.rb +72 -0
  172. data/test/workbook/worksheet/tc_protected_range.rb +17 -0
  173. data/test/workbook/worksheet/tc_row.rb +44 -13
  174. data/test/workbook/worksheet/tc_selection.rb +94 -0
  175. data/test/workbook/worksheet/tc_sheet_protection.rb +117 -0
  176. data/test/workbook/worksheet/tc_sheet_view.rb +214 -0
  177. data/test/workbook/worksheet/tc_worksheet.rb +147 -50
  178. metadata +216 -148
  179. data/examples/example.csv +0 -1000
  180. data/examples/example.rb~ +0 -112
  181. data/lib/axlsx/drawing/cat_axis_data.rb +0 -34
  182. data/lib/axlsx/drawing/hlink_click.rb~ +0 -0
  183. data/lib/axlsx/drawing/hyperlink.rb~ +0 -64
  184. data/lib/axlsx/drawing/named_axis_data.rb +0 -36
  185. data/lib/axlsx/drawing/picture_locking.rb~ +0 -36
  186. data/lib/axlsx/drawing/val_axis_data.rb +0 -27
  187. data/lib/axlsx/stylesheet/#num_fmt.rb# +0 -69
  188. data/lib/axlsx/util/cbf.rb +0 -333
  189. data/lib/axlsx/util/cfb.rb~ +0 -201
  190. data/lib/axlsx/util/ms_off_crypto.rb +0 -189
  191. data/lib/axlsx/util/ms_off_crypto.rb~ +0 -3
  192. data/lib/axlsx/util/ms_offcrypto.rb~ +0 -0
  193. data/lib/axlsx/util/parser.rb~ +0 -6
  194. data/lib/axlsx/util/storage.rb~ +0 -0
  195. data/lib/axlsx/workbook/shared_strings_table.rb~ +0 -69
  196. data/lib/axlsx/workbook/worksheet/col.rb~ +0 -0
  197. data/lib/axlsx/workbook/worksheet/shared_strings_table.rb~ +0 -0
  198. data/lib/axlsx/workbook/worksheet/table.rb~ +0 -97
  199. data/lib/schema/dc.xsd~ +0 -118
  200. data/lib/schema/dcterms.xsd~ +0 -331
  201. data/lib/schema/opc-coreProperties.xsd~ +0 -50
  202. data/test/#benchmark.txt# +0 -7
  203. data/test/#tc_helper.rb# +0 -3
  204. data/test/benchmark.rb~ +0 -0
  205. data/test/benchmark.txt +0 -6
  206. data/test/benchmark.txt~ +0 -6
  207. data/test/drawing/tc_val_axis_data.rb +0 -17
  208. data/test/example.csv +0 -1000
  209. data/test/example.xlsx +0 -0
  210. data/test/example_streamed.xlsx +0 -0
  211. data/test/tc_axlsx.rb~ +0 -0
  212. data/test/tc_helper.rb~ +0 -3
  213. data/test/workbook/worksheet/table/tc_table.rb~ +0 -72
  214. data/test/workbook/worksheet/tc_col.rb~ +0 -10
@@ -0,0 +1,42 @@
1
+ # -*- coding: utf-8 -*-
2
+ module Axlsx
3
+
4
+ #This specifies the last string data used for a chart. (e.g. strLit and strCache)
5
+ # This class is extended for NumData to include the formatCode attribute required for numLit and numCache
6
+ class StrData
7
+
8
+ # creates a new StrVal object
9
+ # @option options [Array] :data
10
+ # @option options [String] :tag_name
11
+ def initialize(options={})
12
+ @tag_prefix = :str
13
+ @type = StrVal
14
+ @pt = SimpleTypedList.new(@type)
15
+ options.each do |o|
16
+ self.send("#{o[0]}=", o[1]) if self.respond_to? "#{o[0]}="
17
+ end
18
+ end
19
+
20
+ # Creates the val objects for this data set. I am not overly confident this is going to play nicely with time and data types.
21
+ # @param [Array] values An array of cells or values.
22
+ def data=(values=[])
23
+ @tag_name = values.first.is_a?(Cell) ? :strCache : :strLit
24
+ values.each do |value|
25
+ v = value.is_a?(Cell) ? value.value : value
26
+ @pt << @type.new(:v => v)
27
+ end
28
+ end
29
+
30
+ # serialize the object
31
+ def to_xml_string(str = "")
32
+ str << '<c:' << @tag_name.to_s << '>'
33
+ str << '<c:ptCount val="' << @pt.size.to_s << '"/>'
34
+ @pt.each_with_index do |value, index|
35
+ value.to_xml_string index, str
36
+ end
37
+ str << '</c:' << @tag_name.to_s << '>'
38
+ end
39
+
40
+ end
41
+
42
+ end
@@ -0,0 +1,33 @@
1
+ # -*- coding: utf-8 -*-
2
+ module Axlsx
3
+
4
+ #This class specifies data for a particular data point.
5
+ class StrVal
6
+
7
+ # a string value.
8
+ # @return [String]
9
+ attr_reader :v
10
+
11
+ # creates a new StrVal object
12
+ # @option options [String] v
13
+ def initialize(options={})
14
+ @v = ""
15
+ @idx = 0
16
+ options.each do |o|
17
+ self.send("#{o[0]}=", o[1]) if self.respond_to? "#{o[0]}="
18
+ end
19
+ end
20
+ # @see v
21
+ def v=(v)
22
+ @v = v.to_s
23
+ end
24
+
25
+ # serialize the object
26
+ def to_xml_string(idx, str = "")
27
+ Axlsx::validate_unsigned_int(idx)
28
+ str << '<c:pt idx="' << idx.to_s << '"><c:v>' << v.to_s << '</c:v></c:pt>'
29
+ end
30
+
31
+ end
32
+
33
+ end
@@ -46,15 +46,27 @@ module Axlsx
46
46
  str << '<c:title>'
47
47
  unless @text.empty?
48
48
  str << '<c:tx>'
49
- str << '<c:strRef>'
50
- str << '<c:f>' << Axlsx::cell_range([@cell]) << '</c:f>'
51
- str << '<c:strCache>'
52
- str << '<c:ptCount val="1"/>'
53
- str << '<c:pt idx="0">'
54
- str << '<c:v>' << @text << '</c:v>'
55
- str << '</c:pt>'
56
- str << '</c:strCache>'
57
- str << '</c:strRef>'
49
+ if @cell.is_a?(Cell)
50
+ str << '<c:strRef>'
51
+ str << '<c:f>' << Axlsx::cell_range([@cell]) << '</c:f>'
52
+ str << '<c:strCache>'
53
+ str << '<c:ptCount val="1"/>'
54
+ str << '<c:pt idx="0">'
55
+ str << '<c:v>' << @text << '</c:v>'
56
+ str << '</c:pt>'
57
+ str << '</c:strCache>'
58
+ str << '</c:strRef>'
59
+ else
60
+ str << '<c:rich>'
61
+ str << '<a:bodyPr/>'
62
+ str << '<a:lstStyle/>'
63
+ str << '<a:p>'
64
+ str << '<a:r>'
65
+ str << '<a:t>' << @text.to_s << '</a:t>'
66
+ str << '</a:r>'
67
+ str << '</a:p>'
68
+ str << '</c:rich>'
69
+ end
58
70
  str << '</c:tx>'
59
71
  end
60
72
  str << '<c:layout/>'
@@ -25,23 +25,33 @@ module Axlsx
25
25
  # @return [Drawing]
26
26
  attr_reader :drawing
27
27
 
28
-
29
- # Creates a new TwoCellAnchor object and sets up a reference to the from and to markers in the
30
- # graphic_frame's chart. That means that you can do stuff like
31
- # c = worksheet.add_chart Axlsx::Chart
28
+ # Creates a new TwoCellAnchor object
32
29
  # c.start_at 5, 9
33
- # @note the chart_type parameter will be replaced with object in v. 2.0.0
34
30
  # @param [Drawing] drawing
35
- # @param [Class] chart_type This is passed to the graphic frame for instantiation. must be Chart or a subclass of Chart
36
- # @param object The object this anchor holds.
37
- # @option options [Array] start_at the col, row to start at
38
- # @option options [Array] end_at the col, row to end at
31
+ # @option options [Array] :start_at the col, row to start at THIS IS DOCUMENTED BUT NOT IMPLEMENTED HERE!
32
+ # @option options [Array] :end_at the col, row to end at
39
33
  def initialize(drawing, options={})
40
34
  @drawing = drawing
41
35
  drawing.anchors << self
42
36
  @from, @to = Marker.new, Marker.new(:col => 5, :row=>10)
43
37
  end
44
38
 
39
+ # sets the col, row attributes for the from marker.
40
+ # @note The recommended way to set the start position for graphical
41
+ # objects is directly thru the object.
42
+ # @see Chart#start_at
43
+ def start_at(x, y)
44
+ set_marker_coords(x, y, from)
45
+ end
46
+
47
+ # sets the col, row attributes for the to marker
48
+ # @note the recommended way to set the to position for graphical
49
+ # objects is directly thru the object
50
+ # @see Char#end_at
51
+ def end_at(x, y)
52
+ set_marker_coords(x, y, to)
53
+ end
54
+
45
55
  # Creates a graphic frame and chart object associated with this anchor
46
56
  # @return [Chart]
47
57
  def add_chart(chart_type, options)
@@ -49,6 +59,11 @@ module Axlsx
49
59
  @object.chart
50
60
  end
51
61
 
62
+ # Creates an image associated with this anchor.
63
+ def add_pic(options={})
64
+ @object = Pic.new(self, options)
65
+ end
66
+
52
67
  # The index of this anchor in the drawing
53
68
  # @return [Integer]
54
69
  def index
@@ -70,6 +85,28 @@ module Axlsx
70
85
  str << '<xdr:clientData/>'
71
86
  str << '</xdr:twoCellAnchor>'
72
87
  end
88
+ private
89
+
90
+ # parses coordinates and sets up a marker's row/col propery
91
+ def set_marker_coords(x, y, marker)
92
+ marker.col, marker.row = *parse_coord_args(x, y)
93
+ end
94
+
95
+ # handles multiple inputs for setting the position of a marker
96
+ # @see Chart#start_at
97
+ def parse_coord_args(x, y=0)
98
+ if x.is_a?(String)
99
+ x, y = *Axlsx::name_to_indices(x)
100
+ end
101
+ if x.is_a?(Cell)
102
+ x, y = *x.pos
103
+ end
104
+ if x.is_a?(Array)
105
+ x, y = *x
106
+ end
107
+ [x, y]
108
+ end
109
+
73
110
 
74
111
  end
75
112
  end
@@ -4,68 +4,81 @@ module Axlsx
4
4
  class View3D
5
5
 
6
6
  # Validation for hPercent
7
- H_PERCENT_REGEX = /0*(([5-9])|([1-9][0-9])|([1-4][0-9][0-9])|500)%/
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
- DEPTH_PERCENT_REGEX = /0*(([2-9][0-9])|([1-9][0-9][0-9])|(1[0-9][0-9][0-9])|2000)%/
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
12
  # x rotation for the chart
13
13
  # must be between -90 and 90
14
14
  # @return [Integer]
15
- attr_reader :rotX
16
-
15
+ attr_reader :rot_x
16
+ alias :rotX :rot_x
17
+
17
18
  # height of chart as % of chart
18
19
  # must be between 5% and 500%
19
20
  # @return [String]
20
- attr_reader :hPercent
21
+ attr_reader :h_percent
22
+ alias :hPercent :h_percent
21
23
 
22
24
  # y rotation for the chart
23
25
  # must be between 0 and 360
24
26
  # @return [Integer]
25
- attr_reader :rotY
26
-
27
+ attr_reader :rot_y
28
+ alias :rotY :rot_y
29
+
27
30
  # depth or chart as % of chart width
28
31
  # must be between 20% and 2000%
29
32
  # @return [String]
30
- attr_reader :depthPercent
33
+ attr_reader :depth_percent
34
+ alias :depthPercent :depth_percent
31
35
 
32
36
  # Chart axis are at right angles
33
37
  # @return [Boolean]
34
- attr_reader :rAngAx
38
+ attr_reader :r_ang_ax
39
+ alias :rAngAx :r_ang_ax
35
40
 
36
41
  # field of view angle
37
42
  # @return [Integer]
38
43
  attr_reader :perspective
39
44
 
40
45
  # Creates a new View3D for charts
41
- # @option options [Integer] rotX
42
- # @option options [String] hPercent
43
- # @option options [Integer] rotY
44
- # @option options [String] depthPercent
45
- # @option options [Boolean] rAngAx
46
+ # @option options [Integer] rot_x
47
+ # @option options [String] h_percent
48
+ # @option options [Integer] rot_y
49
+ # @option options [String] depth_percent
50
+ # @option options [Boolean] r_ang_ax
46
51
  # @option options [Integer] perspective
47
52
  def initialize(options={})
48
- @rotX, @hPercent, @rotY, @depthPercent, @rAngAx, @perspective = nil, nil, nil, nil, nil, nil
53
+ @rot_x, @h_percent, @rot_y, @depth_percent, @r_ang_ax, @perspective = nil, nil, nil, nil, nil, nil
49
54
  options.each do |o|
50
55
  self.send("#{o[0]}=", o[1]) if self.respond_to? "#{o[0]}="
51
56
  end
52
57
  end
53
58
 
54
- # @see rotX
55
- def rotX=(v) DataTypeValidator.validate "#{self.class}.rotX", [Integer, Fixnum], v, lambda {|arg| arg >= -90 && arg <= 90 }; @rotX = v; end
59
+ # @see rot_x
60
+ def rot_x=(v) DataTypeValidator.validate "#{self.class}.rot_x", [Integer, Fixnum], v, lambda {|arg| arg >= -90 && arg <= 90 }; @rot_x = v; end
61
+ alias :rotX= :rot_x=
56
62
 
57
- # @see hPercent
58
- def hPercent=(v) RegexValidator.validate "#{self.class}.rotX", H_PERCENT_REGEX, v; @hPercent = v; end
59
-
60
- # @see rotY
61
- def rotY=(v) DataTypeValidator.validate "#{self.class}.rotY", [Integer, Fixnum], v, lambda {|arg| arg >= 0 && arg <= 360 }; @rotY = v; end
63
+ # @see h_percent
64
+ def h_percent=(v)
65
+ RegexValidator.validate "#{self.class}.h_percent", H_PERCENT_REGEX, v
66
+ @h_percent = v
67
+ end
68
+ alias :hPercent= :h_percent=
62
69
 
63
- # @see depthPercent
64
- def depthPercent=(v) RegexValidator.validate "#{self.class}.depthPercent", DEPTH_PERCENT_REGEX, v; @depthPercent = v; end
70
+ # @see rot_y
71
+ def rot_y=(v) DataTypeValidator.validate "#{self.class}.rot_y", [Integer, Fixnum], v, lambda {|arg| arg >= 0 && arg <= 360 }; @rot_y = v; end
72
+ alias :rotY= :rot_y=
65
73
 
66
- # @see rAngAx
67
- def rAngAx=(v) Axlsx::validate_boolean(v); @rAngAx = v; end
74
+ # @see depth_percent
75
+ def depth_percent=(v) RegexValidator.validate "#{self.class}.depth_percent", DEPTH_PERCENT_REGEX, v; @depth_percent = v; end
76
+ alias :depthPercent= :depth_percent=
68
77
 
78
+ # @see r_ang_ax
79
+ def r_ang_ax=(v) Axlsx::validate_boolean(v); @r_ang_ax = v; end
80
+ alias :rAngAx= :r_ang_ax=
81
+
69
82
  # @see perspective
70
83
  def perspective=(v) DataTypeValidator.validate "#{self.class}.perspective", [Integer, Fixnum], v, lambda {|arg| arg >= 0 && arg <= 240 }; @perspective = v; end
71
84
 
@@ -75,11 +88,11 @@ module Axlsx
75
88
  # @return [String]
76
89
  def to_xml_string(str = '')
77
90
  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?
91
+ str << '<c:rotX val="' << @rot_x.to_s << '"/>' unless @rot_x.nil?
92
+ str << '<c:hPercent val="' << @h_percent.to_s << '"/>' unless @h_percent.nil?
93
+ str << '<c:rotY val="' << @rot_y.to_s << '"/>' unless @rot_y.nil?
94
+ str << '<c:depthPercent val="' << @depth_percent.to_s << '"/>' unless @depth_percent.nil?
95
+ str << '<c:rAngAx val="' << @r_ang_ax.to_s << '"/>' unless @r_ang_ax.nil?
83
96
  str << '<c:perspective val="' << @perspective.to_s << '"/>' unless @perspective.nil?
84
97
  str << '</c:view3D>'
85
98
  end
@@ -0,0 +1,42 @@
1
+ module Axlsx
2
+
3
+ # a vml drawing used for comments in excel.
4
+ class VmlDrawing
5
+
6
+ # creates a new Vml Drawing object.
7
+ # @param [Comments] comments the comments object this drawing is associated with
8
+ def initialize(comments)
9
+ raise ArgumentError, "you must provide a comments object" unless comments.is_a?(Comments)
10
+ @comments = comments
11
+ end
12
+
13
+ # The part name for this vml drawing
14
+ # @return [String]
15
+ def pn
16
+ "#{VML_DRAWING_PN}" % (@comments.worksheet.index + 1)
17
+ end
18
+
19
+ # serialize the vml_drawing to xml.
20
+ # @param [String] str
21
+ # @return [String]
22
+ def to_xml_string(str = '')
23
+ str = <<BAD_PROGRAMMER
24
+ <xml xmlns:v="urn:schemas-microsoft-com:vml"
25
+ xmlns:o="urn:schemas-microsoft-com:office:office"
26
+ xmlns:x="urn:schemas-microsoft-com:office:excel">
27
+ <o:shapelayout v:ext="edit">
28
+ <o:idmap v:ext="edit" data="#{@comments.worksheet.index+1}"/>
29
+ </o:shapelayout>
30
+ <v:shapetype id="_x0000_t202" coordsize="21600,21600" o:spt="202"
31
+ path="m0,0l0,21600,21600,21600,21600,0xe">
32
+ <v:stroke joinstyle="miter"/>
33
+ <v:path gradientshapeok="t" o:connecttype="rect"/>
34
+ </v:shapetype>
35
+ BAD_PROGRAMMER
36
+ @comments.each { |comment| comment.vml_shape.to_xml_string str }
37
+ str << "</xml>"
38
+
39
+ end
40
+
41
+ end
42
+ end
@@ -0,0 +1,125 @@
1
+ module Axlsx
2
+
3
+ # A VmlShape is used to position and render a comment.
4
+ class VmlShape
5
+
6
+ # The row anchor position for this shape determined by the comment's ref value
7
+ # @return [Integer]
8
+ attr_reader :row
9
+
10
+ # The column anchor position for this shape determined by the comment's ref value
11
+ # @return [Integer]
12
+ attr_reader :column
13
+
14
+ # The left column for this shape
15
+ # @return [Integer]
16
+ attr_reader :left_column
17
+
18
+ # The left offset for this shape
19
+ # @return [Integer]
20
+ attr_reader :left_offset
21
+
22
+ # The top row for this shape
23
+ # @return [Integer]
24
+ attr_reader :top_row
25
+
26
+ # The top offset for this shape
27
+ # @return [Integer]
28
+ attr_reader :top_offset
29
+
30
+ # The right column for this shape
31
+ # @return [Integer]
32
+ attr_reader :right_column
33
+
34
+ # The right offset for this shape
35
+ # @return [Integer]
36
+ attr_reader :right_offset
37
+
38
+ # The botttom row for this shape
39
+ # @return [Integer]
40
+ attr_reader :bottom_row
41
+
42
+ # The bottom offset for this shape
43
+ # @return [Integer]
44
+ attr_reader :bottom_offset
45
+
46
+ # Creates a new VmlShape
47
+ # @option options [Integer|String] left_column
48
+ # @option options [Integer|String] left_offset
49
+ # @option options [Integer|String] top_row
50
+ # @option options [Integer|String] top_offset
51
+ # @option options [Integer|String] right_column
52
+ # @option options [Integer|String] right_offset
53
+ # @option options [Integer|String] bottom_row
54
+ # @option options [Integer|String] bottom_offset
55
+ def initialize(options={})
56
+ @row = @column = @left_column = @top_row = @right_column = @bottom_row = 0
57
+ @left_offset = 15
58
+ @top_offset = 2
59
+ @right_offset = 50
60
+ @bottom_offset = 5
61
+ @id = (0...8).map{65.+(rand(25)).chr}.join
62
+ options.each do |o|
63
+ self.send("#{o[0]}=", o[1]) if self.respond_to? "#{o[0]}="
64
+ end
65
+ yield self if block_given?
66
+ end
67
+
68
+ # @see column
69
+ def column=(v); Axlsx::validate_integerish(v); @column = v.to_i end
70
+
71
+ # @see row
72
+ def row=(v); Axlsx::validate_integerish(v); @row = v.to_i end
73
+ # @see left_column
74
+ def left_column=(v); Axlsx::validate_integerish(v); @left_column = v.to_i end
75
+
76
+ # @see left_offset
77
+ def left_offset=(v); Axlsx::validate_integerish(v); @left_offset = v.to_i end
78
+
79
+ # @see top_row
80
+ def top_row=(v); Axlsx::validate_integerish(v); @top_row = v.to_i end
81
+
82
+ # @see top_offset
83
+ def top_offset=(v); Axlsx::validate_integerish(v); @top_offset = v.to_i end
84
+
85
+ # @see right_column
86
+ def right_column=(v); Axlsx::validate_integerish(v); @right_column = v.to_i end
87
+
88
+ # @see right_offset
89
+ def right_offset=(v); Axlsx::validate_integerish(v); @right_offset = v.to_i end
90
+
91
+ # @see bottom_row
92
+ def bottom_row=(v); Axlsx::validate_integerish(v); @bottom_row = v.to_i end
93
+
94
+ # @see bottom_offset
95
+ def bottom_offset=(v); Axlsx::validate_integerish(v); @bottom_offset = v.to_i end
96
+
97
+ # serialize the shape to a string
98
+ # @param [String] str
99
+ # @return [String]
100
+ def to_xml_string(str ='')
101
+ str << <<SHAME_ON_YOU
102
+
103
+ <v:shape id="#{@id}" type="#_x0000_t202" fillcolor="#ffffa1 [80]" o:insetmode="auto">
104
+ <v:fill color2="#ffffa1 [80]"/>
105
+ <v:shadow on="t" obscured="t"/>
106
+ <v:path o:connecttype="none"/>
107
+ <v:textbox style='mso-fit-text-with-word-wrap:t'>
108
+ <div style='text-align:left'></div>
109
+ </v:textbox>
110
+
111
+ <x:ClientData ObjectType="Note">
112
+ <x:MoveWithCells/>
113
+ <x:SizeWithCells/>
114
+ <x:Anchor>#{left_column}, #{left_offset}, #{top_row}, #{top_offset}, #{right_column}, #{right_offset}, #{bottom_row}, #{bottom_offset}</x:Anchor>
115
+ <x:AutoFill>False</x:AutoFill>
116
+ <x:Row>#{row}</x:Row>
117
+ <x:Column>#{column}</x:Column>
118
+ <x:Visible/>
119
+ </x:ClientData>
120
+ </v:shape>
121
+ SHAME_ON_YOU
122
+
123
+ end
124
+ end
125
+ end
data/lib/axlsx/package.rb CHANGED
@@ -80,9 +80,8 @@ module Axlsx
80
80
 
81
81
  # Serialize your workbook to disk as an xlsx document.
82
82
  #
83
- # @param [File] output The file you want to serialize your package to
83
+ # @param [String] output The name of the file you want to serialize your package to
84
84
  # @param [Boolean] confirm_valid Validate the package prior to serialization.
85
- # @option options stream indicates if we should be writing to a stream or a file. True for stream, nil for file
86
85
  # @return [Boolean] False if confirm_valid and validation errors exist. True if the package was serialized
87
86
  # @note A tremendous amount of effort has gone into ensuring that you cannot create invalid xlsx documents.
88
87
  # confirm_valid should be used in the rare case that you cannot open the serialized file.
@@ -90,10 +89,15 @@ module Axlsx
90
89
  # @example
91
90
  # # 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.
92
91
  # # Take a look at the README for an example of how to do it!
93
- # f = File.open('test.xlsx', 'w')
94
- # Package.new.serialize(f)
95
92
  #
96
- # # You will find a file called test.xlsx
93
+ # #serialize to a file
94
+ # p = Axlsx::Package.new
95
+ # # ......add cool stuff to your workbook......
96
+ # p.serialize("example.xlsx")
97
+ #
98
+ # # Serialize to a stream
99
+ # s = p.to_stream()
100
+ # File.open('example_streamed.xlsx', 'w') { |f| f.write(s.read) }
97
101
  def serialize(output, confirm_valid=false)
98
102
  return false unless !confirm_valid || self.validate.empty?
99
103
  Zip::ZipOutputStream.open(output) do |zip|
@@ -152,18 +156,18 @@ module Axlsx
152
156
  # @return [Zip::ZipOutputStream]
153
157
  def write_parts(zip)
154
158
  p = parts
155
- p.each do |part|
156
- unless part[:doc].nil?
157
- zip.put_next_entry(part[:entry]);
158
- entry = ['1.9.2', '1.9.3'].include?(RUBY_VERSION) ? part[:doc].force_encoding('BINARY') : part[:doc]
159
- zip.puts(entry)
160
- end
161
- unless part[:path].nil?
162
- zip.put_next_entry(part[:entry]);
163
- # binread for 1.9.3
164
- zip.write IO.respond_to?(:binread) ? IO.binread(part[:path]) : IO.read(part[:path])
165
- end
159
+ p.each do |part|
160
+ unless part[:doc].nil?
161
+ zip.put_next_entry(part[:entry])
162
+ entry = ['1.9.2', '1.9.3'].include?(RUBY_VERSION) ? part[:doc].force_encoding('BINARY') : part[:doc]
163
+ zip.puts(entry)
164
+ end
165
+ unless part[:path].nil?
166
+ zip.put_next_entry(part[:entry]);
167
+ # binread for 1.9.3
168
+ zip.write IO.respond_to?(:binread) ? IO.binread(part[:path]) : IO.read(part[:path])
166
169
  end
170
+ end
167
171
  zip
168
172
  end
169
173
 
@@ -180,15 +184,24 @@ module Axlsx
180
184
  {:entry => CONTENT_TYPES_PN, :doc => content_types.to_xml_string, :schema => CONTENT_TYPES_XSD},
181
185
  {:entry => WORKBOOK_PN, :doc => workbook.to_xml_string, :schema => SML_XSD}
182
186
  ]
187
+
183
188
  workbook.drawings.each do |drawing|
184
189
  @parts << {:entry => "xl/#{drawing.rels_pn}", :doc => drawing.relationships.to_xml_string, :schema => RELS_XSD}
185
190
  @parts << {:entry => "xl/#{drawing.pn}", :doc => drawing.to_xml_string, :schema => DRAWING_XSD}
186
191
  end
187
192
 
193
+
188
194
  workbook.tables.each do |table|
189
195
  @parts << {:entry => "xl/#{table.pn}", :doc => table.to_xml_string, :schema => SML_XSD}
190
196
  end
191
197
 
198
+ workbook.comments.each do|comment|
199
+ if comment.size > 0
200
+ @parts << { :entry => "xl/#{comment.pn}", :doc => comment.to_xml_string, :schema => SML_XSD }
201
+ @parts << { :entry => "xl/#{comment.vml_drawing.pn}", :doc => comment.vml_drawing.to_xml_string, :schema => nil }
202
+ end
203
+ end
204
+
192
205
  workbook.charts.each do |chart|
193
206
  @parts << {:entry => "xl/#{chart.pn}", :doc => chart.to_xml_string, :schema => DRAWING_XSD}
194
207
  end
@@ -229,18 +242,33 @@ module Axlsx
229
242
  # @private
230
243
  def content_types
231
244
  c_types = base_content_types
245
+
232
246
  workbook.drawings.each do |drawing|
233
247
  c_types << Axlsx::Override.new(:PartName => "/xl/#{drawing.pn}",
234
248
  :ContentType => DRAWING_CT)
235
249
  end
250
+
236
251
  workbook.charts.each do |chart|
237
252
  c_types << Axlsx::Override.new(:PartName => "/xl/#{chart.pn}",
238
253
  :ContentType => CHART_CT)
239
254
  end
255
+
240
256
  workbook.tables.each do |table|
241
257
  c_types << Axlsx::Override.new(:PartName => "/xl/#{table.pn}",
242
258
  :ContentType => TABLE_CT)
243
259
  end
260
+
261
+ workbook.comments.each do |comment|
262
+ if comment.size > 0
263
+ c_types << Axlsx::Override.new(:PartName => "/xl/#{comment.pn}",
264
+ :ContentType => COMMENT_CT)
265
+ end
266
+ end
267
+
268
+ if workbook.comments.size > 0
269
+ c_types << Axlsx::Default.new(:Extension => "vml", :ContentType => VML_DRAWING_CT)
270
+ end
271
+
244
272
  workbook.worksheets.each do |sheet|
245
273
  c_types << Axlsx::Override.new(:PartName => "/xl/#{sheet.pn}",
246
274
  :ContentType => WORKSHEET_CT)
@@ -30,9 +30,9 @@ module Axlsx
30
30
  attr_reader :TargetMode
31
31
 
32
32
  # creates a new relationship
33
- # @param [String] Type The type of the relationship
34
- # @param [String] Target The target for the relationship
35
- # @option [Symbol] target_mode only accepts :external.
33
+ # @param [String] type The type of the relationship
34
+ # @param [String] target The target for the relationship
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
@@ -10,23 +10,13 @@ require 'axlsx/rels/relationship.rb'
10
10
  def initialize
11
11
  super Relationship
12
12
  end
13
-
13
+
14
14
  def to_xml_string(str = '')
15
15
  str << '<?xml version="1.0" encoding="UTF-8"?>'
16
16
  str << '<Relationships xmlns="' << RELS_R << '">'
17
17
  each_with_index { |rel, index| rel.to_xml_string(index+1, str) }
18
18
  str << '</Relationships>'
19
19
  end
20
- # Serializes the relationships document.
21
- # @return [String]
22
- def to_xml()
23
- builder = Nokogiri::XML::Builder.new(:encoding => ENCODING) do |xml|
24
- xml.Relationships(:xmlns => Axlsx::RELS_R) {
25
- each_with_index { |rel, index| rel.to_xml(xml, "rId#{index+1}") }
26
- }
27
- end
28
- builder.to_xml(:save_with => 0)
29
- end
30
20
 
31
21
  end
32
22
  end
@@ -71,6 +71,5 @@ module Axlsx
71
71
  end
72
72
  str << "/>"
73
73
  end
74
-
75
74
  end
76
75
  end