caxlsx 2.0.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 (305) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +9 -0
  3. data/.yardopts_guide +19 -0
  4. data/CHANGELOG.md +239 -0
  5. data/LICENSE +22 -0
  6. data/README.md +256 -0
  7. data/Rakefile +31 -0
  8. data/examples/2010_comments.rb +17 -0
  9. data/examples/anchor_swapping.rb +28 -0
  10. data/examples/auto_filter.rb +16 -0
  11. data/examples/basic_charts.rb +58 -0
  12. data/examples/chart_colors.rb +88 -0
  13. data/examples/colored_links.rb +59 -0
  14. data/examples/conditional_formatting/example_conditional_formatting.rb +74 -0
  15. data/examples/conditional_formatting/getting_barred.rb +37 -0
  16. data/examples/conditional_formatting/hitting_the_high_notes.rb +37 -0
  17. data/examples/conditional_formatting/scaled_colors.rb +39 -0
  18. data/examples/conditional_formatting/stop_and_go.rb +37 -0
  19. data/examples/data_validation.rb +50 -0
  20. data/examples/example.rb +777 -0
  21. data/examples/extractive.rb +45 -0
  22. data/examples/image1.jpeg +0 -0
  23. data/examples/ios_preview.rb +14 -0
  24. data/examples/page_setup.rb +11 -0
  25. data/examples/pivot_table.rb +39 -0
  26. data/examples/sheet_protection.rb +10 -0
  27. data/examples/skydrive/real_example.rb +63 -0
  28. data/examples/styles.rb +66 -0
  29. data/examples/underline.rb +13 -0
  30. data/examples/wrap_text.rb +21 -0
  31. data/lib/axlsx.rb +152 -0
  32. data/lib/axlsx/content_type/abstract_content_type.rb +32 -0
  33. data/lib/axlsx/content_type/content_type.rb +26 -0
  34. data/lib/axlsx/content_type/default.rb +25 -0
  35. data/lib/axlsx/content_type/override.rb +25 -0
  36. data/lib/axlsx/doc_props/app.rb +235 -0
  37. data/lib/axlsx/doc_props/core.rb +39 -0
  38. data/lib/axlsx/drawing/ax_data_source.rb +26 -0
  39. data/lib/axlsx/drawing/axes.rb +61 -0
  40. data/lib/axlsx/drawing/axis.rb +187 -0
  41. data/lib/axlsx/drawing/bar_3D_chart.rb +151 -0
  42. data/lib/axlsx/drawing/bar_series.rb +82 -0
  43. data/lib/axlsx/drawing/cat_axis.rb +85 -0
  44. data/lib/axlsx/drawing/chart.rb +232 -0
  45. data/lib/axlsx/drawing/d_lbls.rb +90 -0
  46. data/lib/axlsx/drawing/drawing.rb +162 -0
  47. data/lib/axlsx/drawing/graphic_frame.rb +54 -0
  48. data/lib/axlsx/drawing/hyperlink.rb +102 -0
  49. data/lib/axlsx/drawing/line_3D_chart.rb +68 -0
  50. data/lib/axlsx/drawing/line_chart.rb +99 -0
  51. data/lib/axlsx/drawing/line_series.rb +81 -0
  52. data/lib/axlsx/drawing/marker.rb +84 -0
  53. data/lib/axlsx/drawing/num_data.rb +52 -0
  54. data/lib/axlsx/drawing/num_data_source.rb +62 -0
  55. data/lib/axlsx/drawing/num_val.rb +32 -0
  56. data/lib/axlsx/drawing/one_cell_anchor.rb +98 -0
  57. data/lib/axlsx/drawing/pic.rb +205 -0
  58. data/lib/axlsx/drawing/picture_locking.rb +44 -0
  59. data/lib/axlsx/drawing/pie_3D_chart.rb +48 -0
  60. data/lib/axlsx/drawing/pie_series.rb +74 -0
  61. data/lib/axlsx/drawing/scaling.rb +60 -0
  62. data/lib/axlsx/drawing/scatter_chart.rb +74 -0
  63. data/lib/axlsx/drawing/scatter_series.rb +65 -0
  64. data/lib/axlsx/drawing/ser_axis.rb +45 -0
  65. data/lib/axlsx/drawing/series.rb +69 -0
  66. data/lib/axlsx/drawing/series_title.rb +23 -0
  67. data/lib/axlsx/drawing/str_data.rb +42 -0
  68. data/lib/axlsx/drawing/str_val.rb +32 -0
  69. data/lib/axlsx/drawing/title.rb +78 -0
  70. data/lib/axlsx/drawing/two_cell_anchor.rb +92 -0
  71. data/lib/axlsx/drawing/val_axis.rb +37 -0
  72. data/lib/axlsx/drawing/view_3D.rb +115 -0
  73. data/lib/axlsx/drawing/vml_drawing.rb +42 -0
  74. data/lib/axlsx/drawing/vml_shape.rb +66 -0
  75. data/lib/axlsx/package.rb +352 -0
  76. data/lib/axlsx/rels/relationship.rb +129 -0
  77. data/lib/axlsx/rels/relationships.rb +29 -0
  78. data/lib/axlsx/stylesheet/border.rb +71 -0
  79. data/lib/axlsx/stylesheet/border_pr.rb +71 -0
  80. data/lib/axlsx/stylesheet/cell_alignment.rb +134 -0
  81. data/lib/axlsx/stylesheet/cell_protection.rb +43 -0
  82. data/lib/axlsx/stylesheet/cell_style.rb +74 -0
  83. data/lib/axlsx/stylesheet/color.rb +78 -0
  84. data/lib/axlsx/stylesheet/dxf.rb +79 -0
  85. data/lib/axlsx/stylesheet/fill.rb +35 -0
  86. data/lib/axlsx/stylesheet/font.rb +148 -0
  87. data/lib/axlsx/stylesheet/gradient_fill.rb +103 -0
  88. data/lib/axlsx/stylesheet/gradient_stop.rb +37 -0
  89. data/lib/axlsx/stylesheet/num_fmt.rb +79 -0
  90. data/lib/axlsx/stylesheet/pattern_fill.rb +73 -0
  91. data/lib/axlsx/stylesheet/styles.rb +420 -0
  92. data/lib/axlsx/stylesheet/table_style.rb +54 -0
  93. data/lib/axlsx/stylesheet/table_style_element.rb +79 -0
  94. data/lib/axlsx/stylesheet/table_styles.rb +46 -0
  95. data/lib/axlsx/stylesheet/xf.rb +147 -0
  96. data/lib/axlsx/util/accessors.rb +64 -0
  97. data/lib/axlsx/util/constants.rb +392 -0
  98. data/lib/axlsx/util/options_parser.rb +15 -0
  99. data/lib/axlsx/util/parser.rb +44 -0
  100. data/lib/axlsx/util/serialized_attributes.rb +79 -0
  101. data/lib/axlsx/util/simple_typed_list.rb +203 -0
  102. data/lib/axlsx/util/storage.rb +146 -0
  103. data/lib/axlsx/util/validators.rb +300 -0
  104. data/lib/axlsx/version.rb +5 -0
  105. data/lib/axlsx/workbook/defined_name.rb +129 -0
  106. data/lib/axlsx/workbook/defined_names.rb +21 -0
  107. data/lib/axlsx/workbook/shared_strings_table.rb +77 -0
  108. data/lib/axlsx/workbook/workbook.rb +354 -0
  109. data/lib/axlsx/workbook/worksheet/auto_filter/auto_filter.rb +77 -0
  110. data/lib/axlsx/workbook/worksheet/auto_filter/filter_column.rb +94 -0
  111. data/lib/axlsx/workbook/worksheet/auto_filter/filters.rb +246 -0
  112. data/lib/axlsx/workbook/worksheet/break.rb +37 -0
  113. data/lib/axlsx/workbook/worksheet/cell.rb +416 -0
  114. data/lib/axlsx/workbook/worksheet/cell_serializer.rb +144 -0
  115. data/lib/axlsx/workbook/worksheet/cfvo.rb +62 -0
  116. data/lib/axlsx/workbook/worksheet/cfvos.rb +15 -0
  117. data/lib/axlsx/workbook/worksheet/col.rb +144 -0
  118. data/lib/axlsx/workbook/worksheet/col_breaks.rb +35 -0
  119. data/lib/axlsx/workbook/worksheet/color_scale.rb +110 -0
  120. data/lib/axlsx/workbook/worksheet/cols.rb +20 -0
  121. data/lib/axlsx/workbook/worksheet/comment.rb +92 -0
  122. data/lib/axlsx/workbook/worksheet/comments.rb +85 -0
  123. data/lib/axlsx/workbook/worksheet/conditional_formatting.rb +82 -0
  124. data/lib/axlsx/workbook/worksheet/conditional_formatting_rule.rb +220 -0
  125. data/lib/axlsx/workbook/worksheet/conditional_formattings.rb +25 -0
  126. data/lib/axlsx/workbook/worksheet/data_bar.rb +131 -0
  127. data/lib/axlsx/workbook/worksheet/data_validation.rb +244 -0
  128. data/lib/axlsx/workbook/worksheet/data_validations.rb +28 -0
  129. data/lib/axlsx/workbook/worksheet/date_time_converter.rb +30 -0
  130. data/lib/axlsx/workbook/worksheet/dimension.rb +64 -0
  131. data/lib/axlsx/workbook/worksheet/header_footer.rb +54 -0
  132. data/lib/axlsx/workbook/worksheet/icon_set.rb +83 -0
  133. data/lib/axlsx/workbook/worksheet/merged_cells.rb +35 -0
  134. data/lib/axlsx/workbook/worksheet/page_margins.rb +99 -0
  135. data/lib/axlsx/workbook/worksheet/page_set_up_pr.rb +44 -0
  136. data/lib/axlsx/workbook/worksheet/page_setup.rb +242 -0
  137. data/lib/axlsx/workbook/worksheet/pane.rb +141 -0
  138. data/lib/axlsx/workbook/worksheet/pivot_table.rb +273 -0
  139. data/lib/axlsx/workbook/worksheet/pivot_table_cache_definition.rb +66 -0
  140. data/lib/axlsx/workbook/worksheet/pivot_tables.rb +24 -0
  141. data/lib/axlsx/workbook/worksheet/print_options.rb +41 -0
  142. data/lib/axlsx/workbook/worksheet/protected_range.rb +49 -0
  143. data/lib/axlsx/workbook/worksheet/protected_ranges.rb +34 -0
  144. data/lib/axlsx/workbook/worksheet/row.rb +172 -0
  145. data/lib/axlsx/workbook/worksheet/row_breaks.rb +33 -0
  146. data/lib/axlsx/workbook/worksheet/selection.rb +103 -0
  147. data/lib/axlsx/workbook/worksheet/sheet_calc_pr.rb +29 -0
  148. data/lib/axlsx/workbook/worksheet/sheet_data.rb +25 -0
  149. data/lib/axlsx/workbook/worksheet/sheet_format_pr.rb +60 -0
  150. data/lib/axlsx/workbook/worksheet/sheet_pr.rb +69 -0
  151. data/lib/axlsx/workbook/worksheet/sheet_protection.rb +120 -0
  152. data/lib/axlsx/workbook/worksheet/sheet_view.rb +213 -0
  153. data/lib/axlsx/workbook/worksheet/table.rb +102 -0
  154. data/lib/axlsx/workbook/worksheet/table_style_info.rb +51 -0
  155. data/lib/axlsx/workbook/worksheet/tables.rb +31 -0
  156. data/lib/axlsx/workbook/worksheet/worksheet.rb +769 -0
  157. data/lib/axlsx/workbook/worksheet/worksheet_comments.rb +58 -0
  158. data/lib/axlsx/workbook/worksheet/worksheet_drawing.rb +58 -0
  159. data/lib/axlsx/workbook/worksheet/worksheet_hyperlink.rb +74 -0
  160. data/lib/axlsx/workbook/worksheet/worksheet_hyperlinks.rb +38 -0
  161. data/lib/schema/dc.xsd +118 -0
  162. data/lib/schema/dcmitype.xsd +52 -0
  163. data/lib/schema/dcterms.xsd +331 -0
  164. data/lib/schema/dml-chart.xsd +1499 -0
  165. data/lib/schema/dml-chartDrawing.xsd +146 -0
  166. data/lib/schema/dml-compatibility.xsd +14 -0
  167. data/lib/schema/dml-diagram.xsd +1091 -0
  168. data/lib/schema/dml-lockedCanvas.xsd +11 -0
  169. data/lib/schema/dml-main.xsd +3048 -0
  170. data/lib/schema/dml-picture.xsd +23 -0
  171. data/lib/schema/dml-spreadsheetDrawing.xsd +185 -0
  172. data/lib/schema/dml-wordprocessingDrawing.xsd +185 -0
  173. data/lib/schema/opc-contentTypes.xsd +42 -0
  174. data/lib/schema/opc-coreProperties.xsd +54 -0
  175. data/lib/schema/opc-digSig.xsd +49 -0
  176. data/lib/schema/opc-relationships.xsd +33 -0
  177. data/lib/schema/pml.xsd +1676 -0
  178. data/lib/schema/shared-additionalCharacteristics.xsd +28 -0
  179. data/lib/schema/shared-bibliography.xsd +144 -0
  180. data/lib/schema/shared-commonSimpleTypes.xsd +166 -0
  181. data/lib/schema/shared-customXmlDataProperties.xsd +25 -0
  182. data/lib/schema/shared-customXmlSchemaProperties.xsd +18 -0
  183. data/lib/schema/shared-documentPropertiesCustom.xsd +59 -0
  184. data/lib/schema/shared-documentPropertiesExtended.xsd +56 -0
  185. data/lib/schema/shared-documentPropertiesVariantTypes.xsd +195 -0
  186. data/lib/schema/shared-math.xsd +582 -0
  187. data/lib/schema/shared-relationshipReference.xsd +25 -0
  188. data/lib/schema/sml.xsd +4434 -0
  189. data/lib/schema/vml-main.xsd +569 -0
  190. data/lib/schema/vml-officeDrawing.xsd +509 -0
  191. data/lib/schema/vml-presentationDrawing.xsd +12 -0
  192. data/lib/schema/vml-spreadsheetDrawing.xsd +108 -0
  193. data/lib/schema/vml-wordprocessingDrawing.xsd +96 -0
  194. data/lib/schema/wml.xsd +3644 -0
  195. data/lib/schema/xml.xsd +116 -0
  196. data/test/benchmark.rb +72 -0
  197. data/test/content_type/tc_content_type.rb +76 -0
  198. data/test/content_type/tc_default.rb +16 -0
  199. data/test/content_type/tc_override.rb +14 -0
  200. data/test/doc_props/tc_app.rb +43 -0
  201. data/test/doc_props/tc_core.rb +42 -0
  202. data/test/drawing/tc_axes.rb +8 -0
  203. data/test/drawing/tc_axis.rb +85 -0
  204. data/test/drawing/tc_bar_3D_chart.rb +71 -0
  205. data/test/drawing/tc_bar_series.rb +37 -0
  206. data/test/drawing/tc_cat_axis.rb +31 -0
  207. data/test/drawing/tc_cat_axis_data.rb +27 -0
  208. data/test/drawing/tc_chart.rb +110 -0
  209. data/test/drawing/tc_d_lbls.rb +57 -0
  210. data/test/drawing/tc_data_source.rb +17 -0
  211. data/test/drawing/tc_drawing.rb +80 -0
  212. data/test/drawing/tc_graphic_frame.rb +27 -0
  213. data/test/drawing/tc_hyperlink.rb +64 -0
  214. data/test/drawing/tc_line_3d_chart.rb +47 -0
  215. data/test/drawing/tc_line_chart.rb +39 -0
  216. data/test/drawing/tc_line_series.rb +30 -0
  217. data/test/drawing/tc_marker.rb +44 -0
  218. data/test/drawing/tc_named_axis_data.rb +27 -0
  219. data/test/drawing/tc_num_data.rb +31 -0
  220. data/test/drawing/tc_num_val.rb +29 -0
  221. data/test/drawing/tc_one_cell_anchor.rb +66 -0
  222. data/test/drawing/tc_pic.rb +107 -0
  223. data/test/drawing/tc_picture_locking.rb +72 -0
  224. data/test/drawing/tc_pie_3D_chart.rb +28 -0
  225. data/test/drawing/tc_pie_series.rb +32 -0
  226. data/test/drawing/tc_scaling.rb +36 -0
  227. data/test/drawing/tc_scatter_chart.rb +48 -0
  228. data/test/drawing/tc_scatter_series.rb +21 -0
  229. data/test/drawing/tc_ser_axis.rb +31 -0
  230. data/test/drawing/tc_series.rb +23 -0
  231. data/test/drawing/tc_series_title.rb +33 -0
  232. data/test/drawing/tc_str_data.rb +18 -0
  233. data/test/drawing/tc_str_val.rb +21 -0
  234. data/test/drawing/tc_title.rb +49 -0
  235. data/test/drawing/tc_two_cell_anchor.rb +36 -0
  236. data/test/drawing/tc_val_axis.rb +24 -0
  237. data/test/drawing/tc_view_3D.rb +54 -0
  238. data/test/drawing/tc_vml_drawing.rb +25 -0
  239. data/test/drawing/tc_vml_shape.rb +106 -0
  240. data/test/profile.rb +24 -0
  241. data/test/rels/tc_relationship.rb +44 -0
  242. data/test/rels/tc_relationships.rb +37 -0
  243. data/test/stylesheet/tc_border.rb +37 -0
  244. data/test/stylesheet/tc_border_pr.rb +32 -0
  245. data/test/stylesheet/tc_cell_alignment.rb +81 -0
  246. data/test/stylesheet/tc_cell_protection.rb +29 -0
  247. data/test/stylesheet/tc_cell_style.rb +57 -0
  248. data/test/stylesheet/tc_color.rb +43 -0
  249. data/test/stylesheet/tc_dxf.rb +81 -0
  250. data/test/stylesheet/tc_fill.rb +18 -0
  251. data/test/stylesheet/tc_font.rb +121 -0
  252. data/test/stylesheet/tc_gradient_fill.rb +72 -0
  253. data/test/stylesheet/tc_gradient_stop.rb +31 -0
  254. data/test/stylesheet/tc_num_fmt.rb +30 -0
  255. data/test/stylesheet/tc_pattern_fill.rb +43 -0
  256. data/test/stylesheet/tc_styles.rb +235 -0
  257. data/test/stylesheet/tc_table_style.rb +44 -0
  258. data/test/stylesheet/tc_table_style_element.rb +45 -0
  259. data/test/stylesheet/tc_table_styles.rb +29 -0
  260. data/test/stylesheet/tc_xf.rb +120 -0
  261. data/test/tc_axlsx.rb +72 -0
  262. data/test/tc_helper.rb +10 -0
  263. data/test/tc_package.rb +227 -0
  264. data/test/util/tc_serialized_attributes.rb +19 -0
  265. data/test/util/tc_simple_typed_list.rb +78 -0
  266. data/test/util/tc_validators.rb +186 -0
  267. data/test/workbook/tc_defined_name.rb +41 -0
  268. data/test/workbook/tc_shared_strings_table.rb +44 -0
  269. data/test/workbook/tc_workbook.rb +125 -0
  270. data/test/workbook/worksheet/auto_filter/tc_auto_filter.rb +38 -0
  271. data/test/workbook/worksheet/auto_filter/tc_filter_column.rb +76 -0
  272. data/test/workbook/worksheet/auto_filter/tc_filters.rb +50 -0
  273. data/test/workbook/worksheet/tc_break.rb +49 -0
  274. data/test/workbook/worksheet/tc_cell.rb +319 -0
  275. data/test/workbook/worksheet/tc_cfvo.rb +31 -0
  276. data/test/workbook/worksheet/tc_col.rb +78 -0
  277. data/test/workbook/worksheet/tc_color_scale.rb +58 -0
  278. data/test/workbook/worksheet/tc_comment.rb +72 -0
  279. data/test/workbook/worksheet/tc_comments.rb +57 -0
  280. data/test/workbook/worksheet/tc_conditional_formatting.rb +224 -0
  281. data/test/workbook/worksheet/tc_data_bar.rb +46 -0
  282. data/test/workbook/worksheet/tc_data_validation.rb +265 -0
  283. data/test/workbook/worksheet/tc_date_time_converter.rb +124 -0
  284. data/test/workbook/worksheet/tc_header_footer.rb +151 -0
  285. data/test/workbook/worksheet/tc_icon_set.rb +45 -0
  286. data/test/workbook/worksheet/tc_page_margins.rb +97 -0
  287. data/test/workbook/worksheet/tc_page_set_up_pr.rb +15 -0
  288. data/test/workbook/worksheet/tc_page_setup.rb +143 -0
  289. data/test/workbook/worksheet/tc_pane.rb +54 -0
  290. data/test/workbook/worksheet/tc_pivot_table.rb +120 -0
  291. data/test/workbook/worksheet/tc_pivot_table_cache_definition.rb +54 -0
  292. data/test/workbook/worksheet/tc_print_options.rb +72 -0
  293. data/test/workbook/worksheet/tc_protected_range.rb +17 -0
  294. data/test/workbook/worksheet/tc_row.rb +117 -0
  295. data/test/workbook/worksheet/tc_selection.rb +55 -0
  296. data/test/workbook/worksheet/tc_sheet_calc_pr.rb +18 -0
  297. data/test/workbook/worksheet/tc_sheet_format_pr.rb +88 -0
  298. data/test/workbook/worksheet/tc_sheet_pr.rb +27 -0
  299. data/test/workbook/worksheet/tc_sheet_protection.rb +117 -0
  300. data/test/workbook/worksheet/tc_sheet_view.rb +214 -0
  301. data/test/workbook/worksheet/tc_table.rb +68 -0
  302. data/test/workbook/worksheet/tc_table_style_info.rb +53 -0
  303. data/test/workbook/worksheet/tc_worksheet.rb +538 -0
  304. data/test/workbook/worksheet/tc_worksheet_hyperlink.rb +55 -0
  305. metadata +546 -0
@@ -0,0 +1,66 @@
1
+ module Axlsx
2
+
3
+ # A VmlShape is used to position and render a comment.
4
+ class VmlShape
5
+
6
+ include Axlsx::OptionsParser
7
+ include Axlsx::Accessors
8
+
9
+ # Creates a new VmlShape
10
+ # @option options [Integer] row
11
+ # @option options [Integer] column
12
+ # @option options [Integer] left_column
13
+ # @option options [Integer] left_offset
14
+ # @option options [Integer] top_row
15
+ # @option options [Integer] top_offset
16
+ # @option options [Integer] right_column
17
+ # @option options [Integer] right_offset
18
+ # @option options [Integer] bottom_row
19
+ # @option options [Integer] bottom_offset
20
+ def initialize(options={})
21
+ @row = @column = @left_column = @top_row = @right_column = @bottom_row = 0
22
+ @left_offset = 15
23
+ @top_offset = 2
24
+ @right_offset = 50
25
+ @bottom_offset = 5
26
+ @visible = true
27
+ @id = (0...8).map{65.+(rand(25)).chr}.join
28
+ parse_options options
29
+ yield self if block_given?
30
+ end
31
+
32
+ unsigned_int_attr_accessor :row, :column, :left_column, :left_offset, :top_row, :top_offset,
33
+ :right_column, :right_offset, :bottom_row, :bottom_offset
34
+
35
+ boolean_attr_accessor :visible
36
+
37
+ # serialize the shape to a string
38
+ # @param [String] str
39
+ # @return [String]
40
+ def to_xml_string(str ='')
41
+ str << <<SHAME_ON_YOU
42
+
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>
51
+
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
+ SHAME_ON_YOU
63
+
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,352 @@
1
+ # encoding: UTF-8
2
+ module Axlsx
3
+ # Package is responsible for managing all the bits and peices that Open Office XML requires to make a valid
4
+ # xlsx document including valdation and serialization.
5
+ class Package
6
+ include Axlsx::OptionsParser
7
+
8
+ # provides access to the app doc properties for this package
9
+ # see App
10
+ attr_reader :app
11
+
12
+ # provides access to the core doc properties for the package
13
+ # see Core
14
+ attr_reader :core
15
+
16
+ # Initializes your package
17
+ #
18
+ # @param [Hash] options A hash that you can use to specify the author and workbook for this package.
19
+ # @option options [String] :author The author of the document
20
+ # @option options [Time] :created_at Timestamp in the document properties (defaults to current time).
21
+ # @option options [Boolean] :use_shared_strings This is passed to the workbook to specify that shared strings should be used when serializing the package.
22
+ # @example Package.new :author => 'you!', :workbook => Workbook.new
23
+ def initialize(options={})
24
+ @workbook = nil
25
+ @core, @app = Core.new, App.new
26
+ @core.creator = options[:author] || @core.creator
27
+ @core.created = options[:created_at]
28
+ parse_options options
29
+ yield self if block_given?
30
+ end
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
+
40
+
41
+ # Shortcut to determine if the workbook is configured to use shared strings
42
+ # @see Workbook#use_shared_strings
43
+ def use_shared_strings
44
+ workbook.use_shared_strings
45
+ end
46
+
47
+ # Shortcut to specify that the workbook should use shared strings
48
+ # @see Workbook#use_shared_strings
49
+ def use_shared_strings=(v)
50
+ Axlsx::validate_boolean(v);
51
+ workbook.use_shared_strings = v
52
+ end
53
+ # The workbook this package will serialize or validate.
54
+ # @return [Workbook] If no workbook instance has been assigned with this package a new Workbook instance is returned.
55
+ # @raise ArgumentError if workbook parameter is not a Workbook instance.
56
+ # @note As there are multiple ways to instantiate a workbook for the package,
57
+ # here are a few examples:
58
+ # # assign directly during package instanciation
59
+ # wb = Package.new(:workbook => Workbook.new).workbook
60
+ #
61
+ # # get a fresh workbook automatically from the package
62
+ # wb = Pacakge.new().workbook
63
+ # # # set the workbook after creating the package
64
+ # wb = Package.new().workbook = Workbook.new
65
+ def workbook
66
+ @workbook || @workbook = Workbook.new
67
+ yield @workbook if block_given?
68
+ @workbook
69
+ end
70
+
71
+ #def self.parse(input, confirm_valid = false)
72
+ # p = Package.new
73
+ # z = Zip::File.open(input)
74
+ # p.workbook = Workbook.parse z.get_entry(WORKBOOK_PN)
75
+ # p
76
+ #end
77
+
78
+ # @see workbook
79
+ def workbook=(workbook) DataTypeValidator.validate "Package.workbook", Workbook, workbook; @workbook = workbook; end
80
+
81
+ # Serialize your workbook to disk as an xlsx document.
82
+ #
83
+ # @param [String] output The name of the file you want to serialize your package to
84
+ # @param [Boolean] confirm_valid Validate the package prior to serialization.
85
+ # @return [Boolean] False if confirm_valid and validation errors exist. True if the package was serialized
86
+ # @note A tremendous amount of effort has gone into ensuring that you cannot create invalid xlsx documents.
87
+ # confirm_valid should be used in the rare case that you cannot open the serialized file.
88
+ # @see Package#validate
89
+ # @example
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.
91
+ # # Take a look at the README for an example of how to do it!
92
+ #
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) }
101
+ def serialize(output, confirm_valid=false)
102
+ return false unless !confirm_valid || self.validate.empty?
103
+ Relationship.clear_cached_instances
104
+ Zip::OutputStream.open(output) do |zip|
105
+ write_parts(zip)
106
+ end
107
+ true
108
+ end
109
+
110
+
111
+ # Serialize your workbook to a StringIO instance
112
+ # @param [Boolean] confirm_valid Validate the package prior to serialization.
113
+ # @return [StringIO|Boolean] False if confirm_valid and validation errors exist. rewound string IO if not.
114
+ def to_stream(confirm_valid=false)
115
+ return false unless !confirm_valid || self.validate.empty?
116
+ Relationship.clear_cached_instances
117
+ zip = write_parts(Zip::OutputStream.new(StringIO.new, true))
118
+ stream = zip.close_buffer
119
+ stream.rewind
120
+ stream
121
+ end
122
+
123
+ # Encrypt the package into a CFB using the password provided
124
+ # This is not ready yet
125
+ def encrypt(file_name, password)
126
+ return false
127
+ # moc = MsOffCrypto.new(file_name, password)
128
+ # moc.save
129
+ end
130
+
131
+ # Validate all parts of the package against xsd schema.
132
+ # @return [Array] An array of all validation errors found.
133
+ # @note This gem includes all schema from OfficeOpenXML-XMLSchema-Transitional.zip and OpenPackagingConventions-XMLSchema.zip
134
+ # as per ECMA-376, Third edition. opc schema require an internet connection to import remote schema from dublin core for dc,
135
+ # dcterms and xml namespaces. Those remote schema are included in this gem, and the original files have been altered to
136
+ # refer to the local versions.
137
+ #
138
+ # If by chance you are able to creat a package that does not validate it indicates that the internal
139
+ # validation is not robust enough and needs to be improved. Please report your errors to the gem author.
140
+ # @see http://www.ecma-international.org/publications/standards/Ecma-376.htm
141
+ # @example
142
+ # # The following will output any error messages found in serialization.
143
+ # p = Axlsx::Package.new
144
+ # # ... code to create sheets, charts, styles etc.
145
+ # p.validate.each { |error| puts error.message }
146
+ def validate
147
+ errors = []
148
+ parts.each do |part|
149
+ errors.concat validate_single_doc(part[:schema], part[:doc]) unless part[:schema].nil?
150
+ end
151
+ errors
152
+ end
153
+
154
+ private
155
+
156
+ # Writes the package parts to a zip archive.
157
+ # @param [Zip::OutputStream] zip
158
+ # @return [Zip::OutputStream]
159
+ def write_parts(zip)
160
+ p = parts
161
+ p.each do |part|
162
+ unless part[:doc].nil?
163
+ zip.put_next_entry(zip_entry_for_part(part))
164
+ entry = ['1.9.2', '1.9.3'].include?(RUBY_VERSION) ? part[:doc].force_encoding('BINARY') : part[:doc]
165
+ zip.puts(entry)
166
+ end
167
+ unless part[:path].nil?
168
+ zip.put_next_entry(zip_entry_for_part(part))
169
+ # binread for 1.9.3
170
+ zip.write IO.respond_to?(:binread) ? IO.binread(part[:path]) : IO.read(part[:path])
171
+ end
172
+ end
173
+ zip
174
+ end
175
+
176
+ # Generate a Entry for the given package part.
177
+ # The important part here is to explicitly set the timestamp for the zip entry: Serializing axlsx packages
178
+ # with identical contents should result in identical zip files – however, the timestamp of a zip entry
179
+ # defaults to the time of serialization and therefore the zip file contents would be different every time
180
+ # the package is serialized.
181
+ #
182
+ # Note: {Core#created} also defaults to the current time – so to generate identical axlsx packages you have
183
+ # to set this explicitly, too (eg. with `Package.new(created_at: Time.local(2013, 1, 1))`).
184
+ #
185
+ # @param part A hash describing a part of this pacakge (see {#parts})
186
+ # @return [Zip::Entry]
187
+ def zip_entry_for_part(part)
188
+ timestamp = Zip::DOSTime.at(@core.created.to_i)
189
+ Zip::Entry.new("", part[:entry], "", "", 0, 0, Zip::Entry::DEFLATED, 0, timestamp)
190
+ end
191
+
192
+ # The parts of a package
193
+ # @return [Array] An array of hashes that define the entry, document and schema for each part of the package.
194
+ # @private
195
+ def parts
196
+ parts = [
197
+ {:entry => RELS_PN, :doc => relationships.to_xml_string, :schema => RELS_XSD},
198
+ {:entry => "xl/#{STYLES_PN}", :doc => workbook.styles.to_xml_string, :schema => SML_XSD},
199
+ {:entry => CORE_PN, :doc => @core.to_xml_string, :schema => CORE_XSD},
200
+ {:entry => APP_PN, :doc => @app.to_xml_string, :schema => APP_XSD},
201
+ {:entry => WORKBOOK_RELS_PN, :doc => workbook.relationships.to_xml_string, :schema => RELS_XSD},
202
+ {:entry => CONTENT_TYPES_PN, :doc => content_types.to_xml_string, :schema => CONTENT_TYPES_XSD},
203
+ {:entry => WORKBOOK_PN, :doc => workbook.to_xml_string, :schema => SML_XSD}
204
+ ]
205
+
206
+ workbook.drawings.each do |drawing|
207
+ parts << {:entry => "xl/#{drawing.rels_pn}", :doc => drawing.relationships.to_xml_string, :schema => RELS_XSD}
208
+ parts << {:entry => "xl/#{drawing.pn}", :doc => drawing.to_xml_string, :schema => DRAWING_XSD}
209
+ end
210
+
211
+
212
+ workbook.tables.each do |table|
213
+ parts << {:entry => "xl/#{table.pn}", :doc => table.to_xml_string, :schema => SML_XSD}
214
+ end
215
+ workbook.pivot_tables.each do |pivot_table|
216
+ cache_definition = pivot_table.cache_definition
217
+ parts << {:entry => "xl/#{pivot_table.rels_pn}", :doc => pivot_table.relationships.to_xml_string, :schema => RELS_XSD}
218
+ parts << {:entry => "xl/#{pivot_table.pn}", :doc => pivot_table.to_xml_string} #, :schema => SML_XSD}
219
+ parts << {:entry => "xl/#{cache_definition.pn}", :doc => cache_definition.to_xml_string} #, :schema => SML_XSD}
220
+ end
221
+
222
+ workbook.comments.each do|comment|
223
+ if comment.size > 0
224
+ parts << { :entry => "xl/#{comment.pn}", :doc => comment.to_xml_string, :schema => SML_XSD }
225
+ parts << { :entry => "xl/#{comment.vml_drawing.pn}", :doc => comment.vml_drawing.to_xml_string, :schema => nil }
226
+ end
227
+ end
228
+
229
+ workbook.charts.each do |chart|
230
+ parts << {:entry => "xl/#{chart.pn}", :doc => chart.to_xml_string, :schema => DRAWING_XSD}
231
+ end
232
+
233
+ workbook.images.each do |image|
234
+ parts << {:entry => "xl/#{image.pn}", :path => image.image_src}
235
+ end
236
+
237
+ if use_shared_strings
238
+ parts << {:entry => "xl/#{SHARED_STRINGS_PN}", :doc => workbook.shared_strings.to_xml_string, :schema => SML_XSD}
239
+ end
240
+
241
+ workbook.worksheets.each do |sheet|
242
+ parts << {:entry => "xl/#{sheet.rels_pn}", :doc => sheet.relationships.to_xml_string, :schema => RELS_XSD}
243
+ parts << {:entry => "xl/#{sheet.pn}", :doc => sheet.to_xml_string, :schema => SML_XSD}
244
+ end
245
+ parts
246
+ end
247
+
248
+ # Performs xsd validation for a signle document
249
+ #
250
+ # @param [String] schema path to the xsd schema to be used in validation.
251
+ # @param [String] doc The xml text to be validated
252
+ # @return [Array] An array of all validation errors encountered.
253
+ # @private
254
+ def validate_single_doc(schema, doc)
255
+ schema = Nokogiri::XML::Schema(File.open(schema))
256
+ doc = Nokogiri::XML(doc)
257
+ errors = []
258
+ schema.validate(doc).each do |error|
259
+ errors << error
260
+ end
261
+ errors
262
+ end
263
+
264
+ # Appends override objects for drawings, charts, and sheets as they exist in your workbook to the default content types.
265
+ # @return [ContentType]
266
+ # @private
267
+ def content_types
268
+ c_types = base_content_types
269
+ workbook.drawings.each do |drawing|
270
+ c_types << Axlsx::Override.new(:PartName => "/xl/#{drawing.pn}",
271
+ :ContentType => DRAWING_CT)
272
+ end
273
+
274
+ workbook.charts.each do |chart|
275
+ c_types << Axlsx::Override.new(:PartName => "/xl/#{chart.pn}",
276
+ :ContentType => CHART_CT)
277
+ end
278
+
279
+ workbook.tables.each do |table|
280
+ c_types << Axlsx::Override.new(:PartName => "/xl/#{table.pn}",
281
+ :ContentType => TABLE_CT)
282
+ end
283
+
284
+ workbook.pivot_tables.each do |pivot_table|
285
+ c_types << Axlsx::Override.new(:PartName => "/xl/#{pivot_table.pn}",
286
+ :ContentType => PIVOT_TABLE_CT)
287
+ c_types << Axlsx::Override.new(:PartName => "/xl/#{pivot_table.cache_definition.pn}",
288
+ :ContentType => PIVOT_TABLE_CACHE_DEFINITION_CT)
289
+ end
290
+
291
+ workbook.comments.each do |comment|
292
+ if comment.size > 0
293
+ c_types << Axlsx::Override.new(:PartName => "/xl/#{comment.pn}",
294
+ :ContentType => COMMENT_CT)
295
+ end
296
+ end
297
+
298
+ if workbook.comments.size > 0
299
+ c_types << Axlsx::Default.new(:Extension => "vml", :ContentType => VML_DRAWING_CT)
300
+ end
301
+
302
+ workbook.worksheets.each do |sheet|
303
+ c_types << Axlsx::Override.new(:PartName => "/xl/#{sheet.pn}",
304
+ :ContentType => WORKSHEET_CT)
305
+ end
306
+ exts = workbook.images.map { |image| image.extname }
307
+ exts.uniq.each do |ext|
308
+ ct = if ['jpeg', 'jpg'].include?(ext)
309
+ JPEG_CT
310
+ elsif ext == 'gif'
311
+ GIF_CT
312
+ elsif ext == 'png'
313
+ PNG_CT
314
+ end
315
+ c_types << Axlsx::Default.new(:ContentType => ct, :Extension => ext )
316
+ end
317
+ if use_shared_strings
318
+ c_types << Axlsx::Override.new(:PartName => "/xl/#{SHARED_STRINGS_PN}",
319
+ :ContentType => SHARED_STRINGS_CT)
320
+ end
321
+ c_types
322
+ end
323
+
324
+ # Creates the minimum content types for generating a valid xlsx document.
325
+ # @return [ContentType]
326
+ # @private
327
+ def base_content_types
328
+ c_types = ContentType.new()
329
+ c_types << Default.new(:ContentType => RELS_CT, :Extension => RELS_EX)
330
+ c_types << Default.new(:Extension => XML_EX, :ContentType => XML_CT)
331
+ c_types << Override.new(:PartName => "/#{APP_PN}", :ContentType => APP_CT)
332
+ c_types << Override.new(:PartName => "/#{CORE_PN}", :ContentType => CORE_CT)
333
+ c_types << Override.new(:PartName => "/xl/#{STYLES_PN}", :ContentType => STYLES_CT)
334
+ c_types << Axlsx::Override.new(:PartName => "/#{WORKBOOK_PN}", :ContentType => WORKBOOK_CT)
335
+ c_types.lock
336
+ c_types
337
+ end
338
+
339
+ # Creates the relationships required for a valid xlsx document
340
+ # @return [Relationships]
341
+ # @private
342
+ def relationships
343
+ rels = Axlsx::Relationships.new
344
+ rels << Relationship.new(self, WORKBOOK_R, WORKBOOK_PN)
345
+ rels << Relationship.new(self, CORE_R, CORE_PN)
346
+ rels << Relationship.new(self, APP_R, APP_PN)
347
+ rels.lock
348
+ rels
349
+ end
350
+ end
351
+ end
352
+
@@ -0,0 +1,129 @@
1
+ # encoding: UTF-8
2
+ module Axlsx
3
+ # A relationship defines a reference between package parts.
4
+ # @note Packages automatically manage relationships.
5
+ class Relationship
6
+
7
+ class << self
8
+ # Keeps track of all instances of this class.
9
+ # @return [Array]
10
+ def instances
11
+ @instances ||= []
12
+ end
13
+
14
+ # Clear cached instances.
15
+ #
16
+ # This should be called before serializing a package (see {Package#serialize} and
17
+ # {Package#to_stream}) to make sure that serialization is idempotent (i.e.
18
+ # Relationship instances are generated with the same IDs everytime the package
19
+ # is serialized).
20
+ #
21
+ # Also, calling this avoids memory leaks (cached instances lingering around
22
+ # forever).
23
+ def clear_cached_instances
24
+ @instances = []
25
+ end
26
+
27
+ # Generate and return a unique id (eg. `rId123`) Used for setting {#Id}.
28
+ #
29
+ # The generated id depends on the number of cached instances, so using
30
+ # {clear_cached_instances} will automatically reset the generated ids, too.
31
+ # @return [String]
32
+ def next_free_id
33
+ "rId#{@instances.size + 1}"
34
+ end
35
+ end
36
+
37
+ # The id of the relationship (eg. "rId123"). Most instances get their own unique id.
38
+ # However, some instances need to share the same id – see {#should_use_same_id_as?}
39
+ # for details.
40
+ # @return [String]
41
+ attr_reader :Id
42
+
43
+ # The location of the relationship target
44
+ # @return [String]
45
+ attr_reader :Target
46
+
47
+ # The type of relationship
48
+ # @note Supported types are defined as constants in Axlsx:
49
+ # @see XML_NS_R
50
+ # @see TABLE_R
51
+ # @see PIVOT_TABLE_R
52
+ # @see WORKBOOK_R
53
+ # @see WORKSHEET_R
54
+ # @see APP_R
55
+ # @see RELS_R
56
+ # @see CORE_R
57
+ # @see STYLES_R
58
+ # @see CHART_R
59
+ # @see DRAWING_R
60
+ # @return [String]
61
+ attr_reader :Type
62
+
63
+ # The target mode of the relationship
64
+ # used for hyperlink type relationships to mark the relationship to an external resource
65
+ # TargetMode can be specified during initialization by passing in a :target_mode option
66
+ # Target mode must be :external for now.
67
+ attr_reader :TargetMode
68
+
69
+ # The source object the relations belongs to (e.g. a hyperlink, drawing, ...). Needed when
70
+ # looking up the relationship for a specific object (see {Relationships#for}).
71
+ attr_reader :source_obj
72
+
73
+ # Initializes a new relationship.
74
+ # @param [Object] source_obj see {#source_obj}
75
+ # @param [String] type The type of the relationship
76
+ # @param [String] target The target for the relationship
77
+ # @option [Symbol] :target_mode only accepts :external.
78
+ def initialize(source_obj, type, target, options={})
79
+ @source_obj = source_obj
80
+ self.Target=target
81
+ self.Type=type
82
+ self.TargetMode = options[:target_mode] if options[:target_mode]
83
+ @Id = if (existing = self.class.instances.find{ |i| should_use_same_id_as?(i) })
84
+ existing.Id
85
+ else
86
+ self.class.next_free_id
87
+ end
88
+ self.class.instances << self
89
+ end
90
+
91
+ # @see Target
92
+ def Target=(v) Axlsx::validate_string v; @Target = v end
93
+ # @see Type
94
+ def Type=(v) Axlsx::validate_relationship_type v; @Type = v end
95
+
96
+ # @see TargetMode
97
+ def TargetMode=(v) RestrictionValidator.validate 'Relationship.TargetMode', [:External, :Internal], v; @TargetMode = v; end
98
+
99
+ # serialize relationship
100
+ # @param [String] str
101
+ # @return [String]
102
+ def to_xml_string(str = '')
103
+ h = self.instance_values.reject{|k, _| k == "source_obj"}
104
+ str << '<Relationship '
105
+ str << h.map { |key, value| '' << key.to_s << '="' << Axlsx::coder.encode(value.to_s) << '"'}.join(' ')
106
+ str << '/>'
107
+ end
108
+
109
+ # Whether this relationship should use the same id as `other`.
110
+ #
111
+ # Instances designating the same relationship need to use the same id. We can not simply
112
+ # compare the {#Target} attribute, though: `foo/bar.xml`, `../foo/bar.xml`,
113
+ # `../../foo/bar.xml` etc. are all different but probably mean the same file (this
114
+ # is especially an issue for relationships in the context of pivot tables). So lets
115
+ # just ignore this attribute for now (except when {#TargetMode} is set to `:External` –
116
+ # then {#Target} will be an absolute URL and thus can safely be compared).
117
+ #
118
+ # @todo Implement comparison of {#Target} based on normalized path names.
119
+ # @param other [Relationship]
120
+ def should_use_same_id_as?(other)
121
+ result = self.source_obj == other.source_obj && self.Type == other.Type && self.TargetMode == other.TargetMode
122
+ if self.TargetMode == :External
123
+ result &&= self.Target == other.Target
124
+ end
125
+ result
126
+ end
127
+
128
+ end
129
+ end